Skip to content

Notification

Simon Oakes edited this page Mar 10, 2021 · 2 revisions

Notification

You can configure the registry to send notifications to an external messaging system such as ActiveMQ whenever changes occur in certain registers.

The registry is packaged with a standard implementation of this feature which sends messages using the STOMP protocol. This should be compatible with any message broker which supports STOMP.

You can also customise the registry to use alternative messaging systems by supplying a JMS implementation or custom notification plugin.

Configuration

You can enable the standard notification feature simply by setting properties in your app.conf. Once it is enabled, you can control its behaviour by modifying the contents of the /system/monitor system register.

Firstly, you must enable the registry monitoring feature by defining the necessary components:

jmsConnectionFactory = org.fusesource.stomp.jms.StompJmsConnectionFactory

notificationAgent = com.epimorphics.registry.notification.JmsNotificationAgent
notificationAgent.connectionFactory = $jmsConnectionFactory

monitorConfig = com.epimorphics.registry.notification.MonitorRegister
monitorConfig.defaultTopic = ldregistry.topic

monitor = com.epimorphics.registry.notification.RegistryMonitor
monitor.agent = $notificationAgent
monitor.config = $monitorConfig

Then, configure the components for your particular messaging environment.

Default Topic

You can set the default topic (or topics) to notify by setting the defaultTopic property on your MonitorRegister component. You can specify multiple default topics as a comma-separated list.

STOMP

You can configure the connection to your STOMP message broker by setting properties on the StompJmsConnectionFactory component in your app.conf.

These are the most common properties that you may need to set. Refer to the Java code for a complete view.

Property Definition
brokerURI The URI of the STOMP message broker.
username The user name to authenticate with, if necessary.
password The password to authenticate with, if necessary.

Example

jmsConnectionFactory = org.fusesource.stomp.jms.StompJmsConnectionFactory
jmsConnectionFactory.brokerURI = tcp://localhost:61613
jmsConnectionFactory.username = your_username
jmsConnectionFactory.password = your_password

Alternatively, you can store your credentials in a separate properties file. This file should be located at /opt/ldregistry/config/stomp/auth.conf, and should contain the following properties:

Property Definition
username The user name to authenticate with, if necessary.
password The password to authenticate with, if necessary.

If you do so, you must ensure that the StompAuthProperties component is declared in app.conf.

Example

# auth.conf
username = your_username
password = your_password

# app.conf
stompAuth = com.epimorphics.registry.notification.stomp.StompAuthProperties

JMS

You can configure the registry's JMS integration by setting properties on the JmsNotificationAgent component in your app.conf. This may be necessary to ensure that the messages sent by the registry are compatible with your message broker.

Property Definition Default
disableMessageId If true, do not set the message ID property on the message. true
connectionFactory A reference to a JMS ConnectionFactory component.

You should not normally change the connectionFactory property unless you are customising the notification system.

Example

notificationAgent = com.epimorphics.registry.notification.JmsNotificationAgent
notificationAgent.connectionFactory = $jmsConnectionFactory
notificationAgent.disableMessageId = false

Monitoring

In order to start sending notifications, you must configure which registers to send notifications for. You can choose the registers by adding items to the /system/monitor system register, which contains items of type reg:MonitorSpec.

Each reg:MonitorSpec corresponds to a single register to monitor, given by its reg:monitors property.

Property Definition
reg:monitors The register to monitor (required).
reg:ignores Sub-registers of the monitored register to exclude from monitoring.
reg:notifies The names or URIs of topics to notify when the monitored register changes. If not set, the default topic will be notified.

While a register is being monitored, any changes that occur in the register or any of its sub-registers (except ignored sub-registers) will trigger a notification.

The resolution of the topic names will depend on your message broker.

Example

<def>   a               reg:MonitorSpec;
        rdfs:label      "def";
        reg:monitors    <http://example.org/registry/def> .

Topics

For each monitoring configuration, you can provide the set of topics to notify as string literals or as resources. If you want to represent topics as resources, you should define them as items in the /system/topic system register, which contains items of type reg:Topic.

Each reg:Topic describes a single topic, whose name is given by its dct:identifier property. This should be the unique name that identifies the topic on your chosen message broker.

Property Definition
dct:identifier The unique name that identifies the topic on your chosen message broker.

If you do so, you must also configure a TopicRegister component in your app.conf, and assign it to the topicRegister config of your MonitorRegister. The component will track the state of the topic system register so that any changes to your topic definitions will be propagated to the notification system.

Example

<ldregistry_test>    a               reg:Topic;
                     rdfs:label      "Test topic"@en;
                     dct:identifier  "ldregistry.test" .
topicReg = com.epimorphics.registry.notification.TopicRegister

monitorConfig = com.epimorphics.registry.notification.MonitorRegister
monitorConfig.topicRegister = $topicReg

Cache & Restore

You can configure your notification agent to cache any notifications that fail to send, and attempt to re-send them once the connection to the message broker is restored, by defining a BacklogNotificationAgent component in your app.conf, and assigning it to the agent property of your RegistryMonitor (usually monitor.agent).

This component handles the caching and retrieval of failed notifications. It will attempt to clear the backlog of notifications whenever a new notification comes in.

You must set the agent property of the component to be a reference to your original NotificationAgent (eg. JmsNotificationAgent). This should be compatible with custom notification plugins.

Since this component uses system resources to maintain a cache of unsent notifications, you may need to specify a limit to how many notifications it can cache at one time. You can do this by setting the limit property on the component in your app.conf.

Property Definition Default
agent The underlying notification agent implementation. Required.
limit The maximum number of notifications that can be cached at one time.
location The absolute path to the directory in which to store cached notifications. /var/opt/ldregistry/notification/backlog

Note

If the backlog cannot be cleared for any reason, new notifications will also not be sent.

Example

notificationAgent = com.epimorphics.registry.notification.JmsNotificationAgent
notificationAgent.connectionFactory = $jmsConnectionFactory

notificationBacklog = com.epimorphics.registry.notification.BacklogNotificationAgent
notificationBacklog.agent = $notificationAgent
notificationBacklog.limit = 1000

monitorConfig = com.epimorphics.registry.notification.MonitorRegister
monitorConfig.defaultTopic = ldregistry.test

monitor = com.epimorphics.registry.notification.RegistryMonitor
monitor.agent = $notificationBacklog
monitor.config = $monitorConfig

Usage

While the notification system is enabled and monitoring a register, a notification will be sent whenever the contents of the register change.

Messages

The format and contents of the notification messages will depend on the type and substance of the change that occurred. All messages will have the following properties (or headers):

Property Definition
operation The name of the operation which was performed. See Operations.
target The URI of the register item on which the operation was performed.

In general, for constructive operations, the message body will be a representation of the new state of the target item. For destructive operations like deleting an item, the message body may be empty.

Operations

Operation Definition Payload
Register A new register or register item was created. The created entity and metadata, in TTL format.
Update An existing register or register item was modified. The new state of the entity and metadata, in TTL format.
StatusUpdate The status of an existing register or register item was modified. The new status of the entity.
RealDelete A register or register item was permanently deleted from the registry. None
Annotate A graph annotation was added to a register or register item. The graph that was added.

Some operations may be performed in bulk through the registry UI or API. In that case, a separate notification will be sent for each entity that was created or modified.

In particular, when performing a mixed upload of new and existing entries, the new entries will be sent with an operation value of Register and existing ones with a value of Update.

When deleting a register, the delete operation will cascade to all of its items and sub-registers. As a result, each of those deleted entries will trigger a separate notification. If possible, the registry will send the notifications in "bottom-up" order.

Customisation

If you require a messaging implementation that has not been provided by registry-core, you can do so by creating a fork of the registry-core project and customising the WAR.

JMS

The simplest way to add a new messaging implementation is by integrating with the standard registry functionality, which uses the JMS API to send messages.

Many message broker systems provide JMS implementations that can simply be plugged in by the following method:

  1. Add the JMS implementation to your custom WAR (usually by adding the Maven dependency in pom.xml).
  2. Configure the ConnectionFactory implementation in your app.conf and assign it as the connectionFactory property of the JmsNotificationAgent component (usually notificationAgent.connectionFactory).

Example

# Notifications
jmsConnectionFactory = org.apache.activemq.ActiveMQConnectionFactory
jmsConnectionFactory.brokerURL = http://localhost:61613

notificationAgent = com.epimorphics.registry.notification.JmsNotificationAgent
notificationAgent.connectionFactory = $jmsConnectionFactory

monitorConfig = com.epimorphics.registry.notification.MonitorRegister
monitorConfig.defaultTopic = ldregistry.topic

monitor = com.epimorphics.registry.notification.RegistryMonitor
monitor.agent = $notificationAgent
monitor.config = $monitorConfig

Notification Plugin

You can write an entirely unique notification plugin by implementing the NotificationAgent Java interface. It will be invoked in the same way as the standard notification system when changes occur in the configured registers.

See the Java class for a description of the interface.

To inject the notification plugin into the registry, you must configure it in your app.conf file and assign it as the agent property of the RegistryMonitor component (usually monitor.agent).

Example

# Notifications
notificationAgent = com.epimorphics.registry.notification.CustomNotificationAgent

monitorConfig = com.epimorphics.registry.notification.MonitorRegister
monitorConfig.defaultTopic = ldregistry.topic

monitor = com.epimorphics.registry.notification.RegistryMonitor
monitor.agent = $notificationAgent
monitor.config = $monitorConfig

Currently available plugins