Giter Club home page Giter Club logo

delta-notifier's Introduction

Delta Notifier

This component receives raw delta messages from mu-authorization and forwards them to interested entities.

Configuration

Delta's need to be sent from mu-authorization to the delta-notifier. The delta notifier needs to be configured to send the right information to your microservice.

Wiring mu-delta-notifier in a mu-semtech stack

The delta-notifier needs to receive messages from mu-authorization and it needs to send messages to other services. Ideally this would be expressed by links to make the communication paths clear. The link option in docker-compose creates an alternative name and places a dependency between the services. We cannot use this as it creates a loop some-service -> mu-authorization -> delta-notifier -> some-service. We do advise documenting which services consume the delta service in docker-compose comments to ensure the application flow is clear.

More information on wiring mu-authorization and the mu-delta-notifier can be found in the documentation of mu-authorization. At the time of writing, you can add a file in mu-authorization's config (most often at config/authorization/delta.ex) and include the following contents:

defmodule Delta.Config do
  def targets do
    [ "http://deltanotifier" ]
  end
end

Including the delta-notifier in your stack

Default inclusion of the delta-notifier looks like this:

  deltanotifier:
    image: semtech/mu-delta-notifier
    volumes:
      - ./config/delta:/config

Receiving delta notifications

Receiving services should be configured in config/delta/rules.js. The format of this file is in flux, yet it is the intention that services consuming these delta messages can consistently receive messages in a specific format. Use the resourceFormat key to select your preferred format.

We first present an example, next we explain each of the properties. The following is a connection to the resource service in config/delta/rules.js.

export default [
  {
    match: {
      // form of element is {subject,predicate,object}
      // predicate: { type: "uri", value: "http://www.semanticdesktop.org/ontologies/2007/03/22/nmo#isPartOf" }
    },
    callback: {
      url: "http://resource/.mu/delta", method: "POST"
    },
    options: {
      resourceFormat: "v0.0.0-genesis",
      gracePeriod: 1000,
      ignoreFromSelf: true
    }
  }
]

The exported property contains an array of definitions, each linking a match to a callback.

  • match: Pattern to match against. Any supplied key must match, anything unspecified is ignored.
  • match.subject: Matches the subject. Both type and value may be specified.
  • match.predicate: Matches the predicade. Both type and value may be specified.
  • match.object: Matches the object. Both type and value may be specified.
  • callback: The place to inform about a matched delta
  • callback.url: URL to inform about a match
  • callback.method: Method to use when informing about a match
  • options: Options describing the match
  • options.resourceFormat: Version format describing the format of the contents. Keys may be added to this format, but they may not be removed. Filter the properties as needed.
  • options.gracePeriod: Only send the response after a certain amount of time. Groups deltas for this rule within this time frame and mu-session-id and mu-auth-allowed-groups and sends them in one go.
  • options.foldEffectiveChanges: (experimental) Fold identique inserted/deleted quads that don't have any effect. Requires effective changes from database. Defaults to false.
  • options.ignoreFromSelf: Don't inform about changes that originated from the microservice to be informed (based on the hostname).
  • options.retry: (experimental) How many times the request is sent again on failure. Defaults to 0. Warning: in case of retries, deltas may be received out of order!
  • options.retryTimeout: (experimental) How much time is left in between retries (in ms). Currently defaults to 250ms.

Modifying quads

Normalize datetime

To enable normalization of datetime values, set the NORMALIZE_DATETIME_IN_QUAD to "true". This may reduce false effective changes being sent. E.g. timezone differences or "2024-02-22T15:04:37.000Z" being the same as "2024-02-22T15:04:37Z".

Custom quad normalization

Mount a custom function in /config/normalize-quad.js to implement your own quad normalization. See corresponding ./config/normalize-quad.js as example.

Delta formats

The delta may be offered in multiple formats. Versions should match the exact string. Specify options.resourceFormat to indicate the specific resourceformat.

v0.0.1

v0.0.1 is the latest format of the delta messages. It may be extended with authorization rights etc. in the future. The value encoding follows the json-sparql spec RDF term encoding. For example:

    [
      { "inserts": [{"subject": { "type": "uri", "value": "http://mu.semte.ch/" },
                     "predicate": { "type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" },
                     "object": { "type": "uri", "value": "https://schema.org/Project" }},
                     {"subject": { "type": "uri", "value": "http://mu.semte.ch/" },
                     "predicate": { "type": "uri", "value": "http://purl.org/dc/terms/modified" },
                     "object": { "type": "literal", "value": "https://schema.org/Project", "datatype": "http://www.w3.org/2001/XMLSchema#dateTime"}}],
        "deletes": [] }
    ]

v0.0.0-genesis

Genesis format as described by the initial Delta service PoC. It looks like:

    { 
      "delta": {
        "inserts": [{"s": "http://mu.semte.ch/",
                     "p": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
                     "o": "https://schema.org/Project"}],
        "deletes": [] }
    }

false or undefined

Any falsy value will currently not send the changed triples to the consuming service. Use this if you use this as a trigger for checking the new state in the database.

Debugging

Debugging can be enabled in the service by setting environment variables. The following may be handy:

  • DEBUG_DELTA_SEND: Logs all delta messages that are being sent to clients
    • DEBUG_DELTA_NOT_SENDING_EMPTY: Logs a message when an empty delta message is discovered and will not be sent
  • DEBUG_DELTA_MATCH: Logs a check for each target block, indicating a check will occur
  • DEBUG_TRIPLE_MATCHES_SPEC: Extensive logging for triples matching a given specification. Handy when requests are unexpectedly not sent.
  • DEBUG_DELTA_FOLD: Logs the incoming and outgoing delta messages of the folding process

Extending

You are encouraged to help figure out how to best extend this service. Fork this repository. Run an experiment. Open an issue or PR describing your experiment. Feel free to open up an issue if you would like to discuss a possible extension.

delta-notifier's People

Contributors

erikap avatar fangiod avatar lagartoverde avatar madnificent avatar nvdk avatar rahien avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

delta-notifier's Issues

SyntaxError: Unexpected token 'export' for config file on startup

Hi,

I encounter the following stacktrace when starting the delta notifier with the latest tag.

deltanotifier_1                | 
deltanotifier_1                | > [email protected] node-prod /usr/src/app
deltanotifier_1                | > node ./start-prod.js
deltanotifier_1                | 
deltanotifier_1                | /config/rules.js:1
deltanotifier_1                | export default [
deltanotifier_1                | ^^^^^^
deltanotifier_1                | 
deltanotifier_1                | SyntaxError: Unexpected token 'export'
deltanotifier_1                |     at wrapSafe (internal/modules/cjs/loader.js:1072:16)
deltanotifier_1                |     at Module._compile (internal/modules/cjs/loader.js:1122:27)
deltanotifier_1                |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
deltanotifier_1                |     at Module.load (internal/modules/cjs/loader.js:1002:32)
deltanotifier_1                |     at Function.Module._load (internal/modules/cjs/loader.js:901:14)
deltanotifier_1                |     at Module.require (internal/modules/cjs/loader.js:1044:19)
deltanotifier_1                |     at require (internal/modules/cjs/helpers.js:77:18)
deltanotifier_1                |     at Object.<anonymous> (/usr/src/app/prod/app/app.js:7:37)
deltanotifier_1                |     at Module._compile (internal/modules/cjs/loader.js:1158:30)
deltanotifier_1                |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
deltanotifier_1                | npm ERR! code ELIFECYCLE
deltanotifier_1                | npm ERR! errno 1
deltanotifier_1                | npm ERR! [email protected] node-prod: `node ./start-prod.js`
deltanotifier_1                | npm ERR! Exit status 1
deltanotifier_1                | npm ERR! 
deltanotifier_1                | npm ERR! Failed at the [email protected] node-prod script.
deltanotifier_1                | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
deltanotifier_1                | 
deltanotifier_1                | npm ERR! A complete log of this run can be found in:
deltanotifier_1                | npm ERR!     /root/.npm/_logs/2021-03-29T10_14_40_881Z-debug.log
xdc_deltanotifier_1 exited with code 1

I'm using the following config file but it fails even with the base one.

export default [
    {
        match: {
            // form of element is {subject,predicate,object}
            // predicate: { type: "uri", value: "http://www.semanticdesktop.org/ontologies/2007/03/22/nmo#isPartOf" }
        },
        callback: {
            url: "http://resource/.mu/delta", method: "POST"
        },
        options: {
            resourceFormat: "v0.0.1",
            gracePeriod: 1000,
            ignoreFromSelf: true
        }
    },
    {
       match: {
           predicate: { "type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" },
           object: { type: "uri", value: "http://www.w3.org/ns/dcat#Dataset" }
       },
       callback: {
           url: "http://temp-kafka-replacement:5000/authorization-test", method: "POST"
       },
       options: {
           resourceFormat: "v0.0.1",
           gracePeriod: 1000,
           ignoreFromSelf: true
       }
    }
]

The issue doesn't occur on 0.1.0.
If it doesn't occur for everyone, it could point to a node version not specified somewhere I suppose?

Compatibility to Linked Data Event Streams

We launched the Linked Data Event Streams (LDES) specification with a focus on making third parties replicate the full history of a dataset, and stay in-sync with it. It is available at https://w3id.org/ldes/specification

It has a different set-up as the delta-notifier’s v0.0.1 format, which is based on additions/updates/deletions of triples. LDES advocates defining a collection of entities (e.g., a collection of mandates). LDES requires you to add version identifiers to the mandates (e.g., ex:MayorofGhent2019v1) and add all triples that you want to expose in this particular collection (you can document this in a shacl shape). We thus only add triples to the system: triples describing a new version of the entity. In order to keep that manageable, you can describe a retention policy and that way remove older data or previous versions from disk.

Some examples of feeds already available:

Components that already exist that allows you to work with LDES:

I wonder whether the delta-notifier could also work with LDES by:

  1. Subscribing to an LDES using the LDES client https://github.com/TREEcg/event-stream-client/tree/main/packages/actor-init-ldes-client
  2. Sending the new version objects to the right mu-semtech microservice

It is then a responsibility of that microservice to understand what it needs to do with that version object. One option could be to just add triples as-is in a store (this is similar to what we do in LDES2Service). Another option could be to create a version materialization (making the subject’s IRI the IRI of the dcterms:isVersionOf object, and changing dcterms:created into dcterms:modified), removing all triples of the previous version and loading the new version in the store.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.