We recently announced a new event delivery feature called DataGroups, and feedback received to date has been very encouraging. Thank you to Matt Davey and Olivier DeHeurles, both of whom have written excellent blogs on their thoughts about DataGroups, and on how the technology can be used.
One of the major use cases for Nirvana has been in the provision of Single Dealer Platforms (SDPs). We have blogged previously about the fact that many of the largest SDPs by market share use Nirvana. We are very proud of this success, and are keen to continue providing last mile messaging for SDPs that help our customers build the most competitive offerings on the market.
As the SDP market has evolved, it has become increasingly important to banks that they differentiate their offerings. One important aspect of this is the ability to efficiently send tailored prices to individual users or to groups of users.
In the past, SDPs designed around Nirvana have often used one or more of the following approaches to distribute prices to clients:
- Publish prices to dedicated channels/topics or queues associated with individual users/groups. These can be created dynamically when required, or be defined statically.
- Create a tiered grouping (e.g. Gold, Silver, Bronze) and an associated Nirvana namespace of channels/topics or queues.
- Create an arbitrary grouping mechanism (e.g. institutional or regional) and an associated namespace of channels/topics or queues.
These approaches have their place, but we identified scenarios where our customers would benefit from additional flexibility in circumstances where they wish, for example, to move users between tiers / groups on the fly.
Having worked closely with our SDP customers, it became clear that the task of distributing custom prices could be further facilitated by:
- Providing a lightweight grouping structure allowing the transparent addition or removal of consumers (using the Nirvana client API).
- Enabling remote subscription management – thus simplifying the client logic.
- Removing the need to employ large numbers of ACLs to secure all the individual price flows.
Nirvana DataGroups are designed to deliver on all of the above requirements.
DataGroups provide a fully transparent event delivery construct based on arbitrary groups of consumers.
DataGroups are extremely lightweight from both client and server perspectives; a back-end process, such as a Complex Event Processing engine, can simply create DataGroups and then add or remove users (or even entire nested DataGroups) based on the bank’s business logic. A user who is removed from one DataGroup and added to another will continue to receive events without any interruption to service, or indeed explicit awareness that any DataGroup change has occurred.
Some DataGroup Code Samples
Here are two simple classes:
The first shows how a consumer’s Nirvana session is initialised in order to support DataGroup functionality, and how it receives message callbacks.
The second is an example of a backend process that can manage DataGroup memberships and event publishing.
Enabling DataGroups In Client Code and Receiving Callbacks
public class DataGroupClient implements nDataStreamListener{
nSession mySession;
public DataGroupClient( String realmURLs){
nSessionAttributes nsa = new nSessionAttributes(realmURLs);
mySession = nSessionFactory.create(nsa, this);
mySession.init(this);
}
////
// nDataStreamListener Implementation
////
//Callback received when event is available
public void onMessage(nConsumeEvent event){
//some code to process the message
}
}
Managing DataGroups and Members, and Publishing Events
public class DataGroupController implements nDataGroupListener {
nSession mySession;
public DataGroupController( nSession session){
mySession = session;
registerForDataGroupChanges();
}
//publish messge to a nDataGroup
public void publishMessageToDataGroup( nDataGroup group, nConsumeEvent event){
mySession.writeDataGroup(event, group);
}
//publish message to multiple nDataGroups
public void publishMessagesToDataGroups( nDataGroup[] groups, nConsumeEvent event){
mySession.writeDataGroup(event, groups);
}
//Create a new nDataGroup
public void createDataGroup(String name) {
mySession.createDataGroup(name);
}
//Delete a nDataGroup
public void deleteDataGroup(String name){
mySession.deleteDataGroup(name);
}
//Add a nDataStream (user) to a nDataGroup
public void addStreamToDataGroup(nDataGroup group, nDataStream user){
group.add(user);
}
//Remove a nDataStream (user) from a nDataGroup
public void removeStreamFromDataGroup(nDataGroup group, nDataStream user){
group.remove(user);
}
//Add a nDataGroup to a nDataGroup
public void addNestedDataGroup(nDataGroup parent, nDataGroup child){
parent.add(child);
}
//Remove a nDataGroup from a nDataGroup
public void removeNestedDataGroup(nDataGroup parent, nDataGroup child){
parent.remove(child);
}
// return default nDataGroup
// and register as a DataGroupListener (for callbacks when users (nDataStreams) are added or removed)
public void registerForDataGroupChanges(){
nDataGroup group = mySession.getDefaultDataGroup(this);
}
////
// nDataGroupListener interface implementations
////
// callback for when new stream added to default data group
public void addedStream(nDataGroup group, nDataStream stream, int count){
System.out.println(group.getName() + " : New stream " + stream.getName() + " : " + stream.getSubject() + " added, size now " + count);
}
// callback indicating nDataStream removed from data group
// if count == 0 there are no nDataStreams remaining within the nDataGroup
public void deletedStream(nDataGroup group, nDataStream stream, int count){
System.out.println(group.getName() + " : Data stream " + stream.getName() + " : " + stream.getSubject() + " removed, size now " + count);
}
// callback indicating new nDataGroup added
public void addedGroup(nDataGroup to, nDataGroup group, int count){
System.out.println(to.getName() + " : Data group " + group.getName() + " added, size now " + count);
}
// callback indicating new nDataGroup created
public void createdGroup(nDataGroup group){
System.out.println("Data group " + group.getName() + " created");
}
// callback indicating nDataGroup deleted
public void deletedGroup(nDataGroup group){
System.out.println("Data group " + group.getName() + " deleted");
}
// callback indicating nested nDataGroup removed from nDataGroup
public void removedGroup(nDataGroup from, nDataGroup group, int count){
System.out.println(from.getName() + " : Data group " + group.getName() + " removed, size now " + count);
}
}
“Early Access” to DataGroups
To access DataGroup functionality before its official release, you can download a Nirvana 6.0 early access build right now.
The early access builds contains sample apps along with full source code for C# and Java. Additional language support will follow in our next EA release.
This looks good but surprised it has taken this long for Nirvana to have such functionality. Pretty sure the container objects in Caplin’s stack have done this for many years. I used it on a DMA service rather than SDP but was essentially the same, also had filters.
Thanks for your comments and thoughts Rob.
The key aim for us with DataGroups was to complement the Message Queue and Topic/Channel (pub/sub) functionality already inherent in Nirvana (but often not a present in other streaming products). We feel that Nirvana is unique within the internet messaging space in terms of offering this breadth of messaging functionality.
Pingback: DataGroups : A Comparison With Existing Nirvana Functionality | my-Channels Blog
Pingback: Nirvana 6.0 Released | my-Channels Blog