Notification API Overview

The Notification API allows your application to send notifications to users of a front-end trading application.

With the API, your application can open a unique channel of communication for each user, send that user notifications with arbitrary fields and allow the user to respond with actions for each notification received. Examples of notifications you may want to send include system level notifications, such as a service going down or trade life-cycle events, such as order fills.

The StreamLink Alerts API provides a means of integrating with with the Notification API. It allows a user to subscribe to their NotifcationChannel, prompting a call into the NotificationApplicationListener with the Notification API's representation of that channel. The StreamLink Alerts API can be used to send the preconfigured action, 'DISMISS', or any other custom action.

The 'DISMISS' action is the only action to have automatic behaviour associated with it. When a 'DISMISS' is sent by the StreamLink Alerts API, the notification in question will be removed from the cache, and that user will be unsubscribed from that Notification.

Under the hood, a NotificationChannel is a container on the subject /PRIVATE/NOTIFICATIONS/%u/CONTAINER. The channel is populated with Notification records identified by sourceName and user provided unique id. The NotificationProvider allows multiple NotificationChannels, each associated with a user, to be serviced on a single namespace.

Key Concepts

Source Name - identifies the NotificationProvider in logs and over jmx. Passed into constructor of NotificationConfiguration. NotificationChannel - corresponds to a set of notifications for a single user. Notifications are added to and removed from this. Notification - a notification with arbitrary fields sent to the user subscribed to the NotificationChannel

Getting Started

Instantiating a NotificationProvider

Here is how you would instantiate a NotificationProvider given a NotificationApplicationListener called NotificationGenerator:

import com.caplin.datasource.ConnectionListener;
import com.caplin.datasource.DataSource;
import com.caplin.datasource.PeerStatusEvent;
import com.caplin.datasource.notification.NotificationConfiguration;
import com.caplin.datasource.notification.NotificationProvider;

import java.util.logging.Logger;

public class InstantiatingANotificationProvider implements ConnectionListener
{
        
        private final Logger logger;
        
        public InstantiatingANotificationProvider(DataSource dataSource)
        {
                this.logger = dataSource.getLogger();
                NotificationConfiguration configuration = new NotificationConfiguration("NotificationProviderId");
                new NotificationProvider(dataSource, configuration, new NotificationGenerator(logger));
                dataSource.addConnectionListener(this);
        }
        
        @Override
        public void onPeerStatus(PeerStatusEvent peerStatusEvent)
        {
                logger.info("onPeerStatus: " + peerStatusEvent);
        }
        
        public static void main(String[] args) throws Exception
        {
                // Example arguments: -f ./Blade/DataSource/etc/datasource.conf --config-base-location=global_config
                DataSource dataSource = DataSource.fromArgs(args);
                
                new InstantiatingANotificationProvider(dataSource);
                
                // The DataSource should not be started before creating a NotificationProvider to ensure all notification requests are received
                dataSource.start();
        }
}

Sample ApplicationListener

Here is the example ApplicationListener, NotificationGenerator:

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Logger;

import com.caplin.datasource.notification.Notification;
import com.caplin.datasource.notification.NotificationApplicationListener;
import com.caplin.datasource.notification.NotificationChannel;

public class NotificationGenerator implements NotificationApplicationListener
{
        private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
        private final Logger logger;
        
        private int currentMessageIndex = 0;
        
        public NotificationGenerator(Logger logger)
        {
                this.logger = logger;
        }
        
        @Override
        public void notificationChannelOpened(NotificationChannel channel)
        {
                // References to channels are obtained here. A reference
                // would usually be kept so that notifications can be added and
                // removed with sendNNotification(s) and removeNotification(s)
                // as and when.
                
                logger.info("notificationChannelOpened: " + channel.getSubject());
                channel.sendNotification(notificationFor(channel.getUsername()));
        }
        
        private Notification notificationFor(String username)
        {
                //fields used here must be in your fields.conf
                
                Notification notification = new Notification(Integer.toString(++currentMessageIndex));
                notification.setField("tradeDate", DATE_FORMAT.format(new Date()));
                notification.setField("currencyPair", "EUR/USD");
                notification.setField("submittedBy", username);
                return notification;
        }
        
        @Override
        public void notificationChannelClosed(NotificationChannel channel)
        {
                //any channel cleanup should go here
                
                logger.info("notificationChannelClosed: " + channel.getSubject());
        }
}

Packages 
Package Description
com.caplin.datasource.notification
This package contains the public elements of the Notification API.