Tweaking SAVAN : Persistent subscriptions

WS-Eventing defines a protocol for one Web service (called a "subscriber") to register interest (called a "subscription") with another Web service (called an "event source") in receiving messages about events (called "notifications" or "event messages").

The subscriber may manage the subscription by interacting with a Web service (called the "subscription manager") designated by the event source.

Savan is the WS-Eventing implementation for Apache Axis2.

This post is a continuation of my previous post, which demonstrates Savan with an example.

Before going any further with this, please make sure you have gone through it and have the example running.

The sample application included three components.

1. Event source[axis2-savan-event-source] - a stock quote service publishes stock prices iteratively

2. Event sink[axis2-savan-event-sink] - a stock quote consumer subscribes to the stock quote service to receive events

3. [axis2-savan-client] - initiates subscription for the stock quote consumer

By default Savan manages event subscriptions with an in-memory subscriber store.

That is, in case the server running the event source, got restarted, event sink no more will receive any events.

This post takes you through, explaining how to add a custom subscriber store to manage subscriptions in a persistence manner.

Let's get started with the custom subscriber store code.

package org.apache.ws.axis2;

import java.util.Iterator;

import org.apache.axis2.context.ConfigurationContext;
import org.apache.savan.SavanException;
import org.apache.savan.storage.SubscriberStore;
import org.apache.savan.subscribers.Subscriber;
import org.apache.savan.subscribers.SubscriberGroup;

public class CustomSubscriberStore implements SubscriberStore {

public void init(ConfigurationContext arg0) throws SavanException {
// TODO Initialize the storage
}

public void addSubscriberGroup(String arg0) throws SavanException {
// TODO Add subscriber to a subscriber group
}

public void addSubscriberToGroup(String arg0, Subscriber arg1) throws SavanException {
// TODO Add subscriber to a subscriber group
}

public void delete(String arg0) throws SavanException {
// TODO Delete a previously stored subscriber
}

public SubscriberGroup getSubscriberGroup(String arg0) throws SavanException {
// TODO Retrieve a previously stored subscriber group
}

public Subscriber retrieve(String arg0) throws SavanException {
// TODO Retrieve a previously stored subscriber
}

public Iterator retrieveAllSubscriberGroups() throws SavanException {
// TODO Retrieve a previously stored subscriber groups
}

public Iterator retrieveAllSubscribers() throws SavanException {
// TODO Retrieve previously stored subscribers
}

public void store(Subscriber arg0) throws SavanException {
// TODO Store the subscriber in the persistent data store
}

}
Once completed, add the jar containing the above class to [AXIS2_HOME]\lib.

Now we need to make sure, Savan module loads the above class.

That can be configured in savan-config.xml.

You can find savan-config.xml in side [AXIS2_HOME]\repository\modules\savan-SNAPSHOT.mar. [You may extract savan-SNAPSHOT.mar, do the changes to the configuration file and then zip it again as savan-SNAPSHOT.mar]

<subscriberStores>
<subscriberStore>
<key>default</key>
<class>org.apache.savan.storage.DefaultSubscriberStore</class>
</subscriberStore>
<!-- this is your new subscriber store, with the key 'custom' -->
<subscriberStore>
<key>custom
<class>org.apache.ws.axis2.CustomSubscriberStore
</subscriberStore>
</subscriberStores>
Now, we are almost done. Let's configure the event source[axis2-savan-event-source] to use our custom subscriber store.

You need edit services.xml of StockQuoteService and add a new parameter.

<service name="StockQuoteService" scope="application">

<module ref="savan" />
<module ref="addressing" />

<parameter name="ServiceClass" locked="false">org.apache.ws.axis2.StockQuoteService</parameter>
<!-- Set SubscriberStoreKey to the key you set for you custom subscriber store in savan-config.xml -->
<parameter name="SubscriberStoreKey" locked="false">custom</parameter>

</service>
All set - redeploy the event source service and test with the client.