Tuesday, January 27, 2009

Event Publishing in OSGi

In Java, a common pattern to publish events is the Observer pattern, which requires the event source to maintain a list of interested listeners. An alternative is to use the PubSub model, where event source and listeners don't need to be aware of the existence of each other. To build a PubSub application, JMS is one choice, but if your application is built upon OSGi, you can take advantage of the EventAdmin and EventHandler services which are part of the OSGi specification.

The steps to create event publisher and event subscriber in OSGi is simple. First, we need to create EventHandler services and register them with OSGi. Registration parameters define the events that interest the EventHandler. List 1 is a sample event listener:

public class SampleListener implements EventHandler, BundleActivator{
@Override
public void start(BundleContext ctx) throws Exception {
Properties props = new Properties();
/* interested in Foo/Bar events */
props.setProperty(EventConstants.EVENT_TOPIC, "Foo/Bar");
ctx.registerService(EventHandler.class.getName(), new Listener1(), props);
}

@Override
public void handleEvent(Event event) {
/*code to process the event*/
...
}

...
}


EventAdmin is the second service that is necessary. Fortunately, it is part of OSGi. So to make use of it, we need to do nothing except that we may need to manually install the EventAdmin bundle into your OSGi environment. But to make the use of this service easier, an EventAdmin service tracker would be helpful:

public class EventAdminTracker extends ServiceTracker {
public EventAdminTracker(BundleContext context) {
super(context, EventAdmin.class.getName(), null);
}

public void postEvent(Event e){
EventAdmin ad = (EventAdmin) this.getService();
if(ad!=null){
ad.postEvents(e);
}
}
}


The last component is the event source. It is no different from regular event sources in Java.

public class EventSource implements BundleActivator {
private EventAdminTracker eat;

@Override
public void start(BundleContext ctx) throws Exception {
eat = new EventAdminTracker(ctx);
eat.open();
createSampleEvent();
}

@Override
public void stop(BundleContext ctx) throws Exception {
eat.close();
}

private void createSampleEvent{
Event e = new Event("Foor/Bar", null);
/* create a Foo/Bar event */
eat.postEvent(e);
}
}


The above is all we need to do to publish events in OSGi. As you can see, it is very easy.

No comments:

Blog Archive