OSGi EventAdmin

I recently had a few people come to me to chat about the OSGi EventAdmin service. For those who are curious, the EventAdmin service is part of the OSGi Compendium Specification and allows you to publish and listen to events via a pub-sub system. I’ll try to do a quick write up on how to actually use the service. As with any OSGi service, the first and foremost thing you need to do is acquire the EventAdmin service. There are many ways to do this, but I prefer to use Declarative Services these days. This is what a sample component definition would look like:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" 
   immediate="true"
   name="org.eclipse.example">
<implementation class= "org.eclipse.example.MyClass"/>
<reference bind="setEventAdmin" interface="org.osgi.service.event.EventAdmin"/>
</scr:component>

Once we acquire the EventAdmin service, there are really two things you can do: publish and listen for events.

Publishing Events

To publish events, you need to pick a name for your topic. For example purposes, let’s pretend we wanted to publish information about memory events. A good topic name for this would be something like:

org/eclipse/equinox/events/MemoryEvent/{NORMAL,SERIOUS,CRITICAL}

If we wanted to publish a critical memory event, we have to create an Event object and publish it using EventAdmin:

...
Event event = new Event("org/eclipse/equinox/events/MemoryEvent/CRITICAL", null);
eventAdmin.postEvent(event);

It’s important to note that there are two ways of sending events using EventAdmin. This depends whether you want your event to be sent in a asynchronous our synchronous fashion. In the example above, we used the postEvent(...) method in EventAdmin which sends events in an asynchronous fashion. To send events in a synchronous fashion, EventAdmin exposes the sendEvent(...) method so we could simply change our code to send event synchronously:

...
Event event = new Event("org/eclipse/equinox/events/MemoryEvent/CRITICAL", null);
eventAdmin.sendEvent(event);

An additional thing to note is that you can send additional properties with your events as the Event object takes an optional Map parameter in its constructor.

Listening for Events

From the consumer side of things, we’re interested in handling the memory events. To do this, we need to register an EventHandler, let’s call it a MemoryEventHandler in this case:

public class MemoryEventHandler implements EventHandler {
 
	public void handleEvent(Event event) {
		// TODO panic... handle memory event
	}
}

Next, we need to register our MemoryEventHandler with the service registry with the proper EventAdmin topic name. There are many ways to do this, but for the variety purposes, let’s do it the traditional way in a bundle activator via a BundleContext reference:

...
EventHandler handler = new MemoryEventHandler();
properties = new Hashtable<String, String>();
properties(
   EventConstants.EVENT_TOPIC, 
   "org/eclipse/equinox/events/MemoryEvent/CRITICAL");		
context.registerService(EventHandler.class.getName(), handler, properties);

The important part of the service registration involves topic you’re interested via the EventConstants.EVENT_TOPIC constant. In the example above, we were interested in critical memory events so we used the proper topic:

org/eclipse/equinox/events/MemoryEvent/CRITICAL

If we were interested in all memory events, EventAdmin supports wildcard matching on topics so we could do this:

org/eclipse/equinox/events/MemoryEvent/*

EventAdmin also supports filtering via the EventConstants.EVENT_FILTER constant.

For the curious, the example above could have easily been done using DS:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" 
   name="org.eclipse.example.memoryHandler">
<implementation class="org.eclipse.example.MemoryEventHandler"/>
<service> 
 <provide interface="org.osgi.service.event.EventHandler"/>
</service>
 <property name=”event.topics” value=”org/eclipse/equinox/events/MemoryEvent/CRITICAL” />
</scr:component>

That’s all it takes to listen for events!

EventAdmin in Eclipse

Cool, now that you know more about EventAdmin… how about using it in your Eclipse RCP applications? Well, I have good news as Equinox has a great implementation of EventAdmin available. Furthermore, as of Eclipse 3.6 M2, EventAdmin will ship part of the Eclipse SDK. If you’re not building on top of Eclipse 3.6 yet, you can simply grab the event admin implementation from the Equinox SDK downloads page.

Note: The example I described in this blog is something someone proposed be included within Eclipse.

You may also like...

Share this Post

Twitter0
Google+0
LinkedIn
Facebook

Tags

20 Responses to “OSGi EventAdmin”

  1. Jerome Dotet says:

    Interesting post, Thanks. Definitely one of the best resource on the event admin.

    I just would like to mention the advanced event admin integration provided by iPOJO. This feature avoid dealing directly with the event admin. Well, Ok, it is not really difficult, but anyway it can become very complex if you use asynchronous / synchronous event sending, topic filters…

    With this feature, the code does not have to implement Event Handler nor publishing the service (with properties). Everything is managed by iPOJO. To send event, iPOJO injects a ‘smart’ proxy automating everything.

    iPOJO goes further than SCR. And, of course, works on Equinox.

    Here are the links:
    http://felix.apache.org/site/event-admin-handlers.html
    http://ipojo.org

  2. Fer says:

    Hello Chris,

    I would like to know as I can get the response (in the Publisher) from handleEvent method, for example:

    ***Publishing***
    I publish a new event,

    Dictionary properties = new Hashtable();
    result.put(“name”, “David”);
    Event event = new Event(“org/eclipse/equinox/events/message”, properties);
    eventAdmin.postEvent(event); //asynchronous call

    ***Listening***
    After I handle the event as,

    public void handleEvent(Event event) {
    //I call a method than return a message (String) for a event name
    String message = getMessage(event.getProperty(“name”));

    }

    How I can get the message in the publisher???

    Best Regards,

    Thanks!

  3. Nirav Thaker says:

    Nice post. I am curious, if I am running webapp on OSGi with Event Admin as my default messaging does it provide standard MQ features like store and forward, fault tolerant messages?
    For RCP I don’t think it matters as much but for transactional applications does it guarantee transaction semantics, like message sending will be retried several times before giving up etc.? I am looking for lightweight alternative to JMS and OSGi as viable stack for webapps and Event Admin looks good enough replacement for JMS.

  4. BJ Hargrave says:

    Chris,

    In the DS snippet for registering the handler, you forgot to set the topic property!

    Also, the interface for the provided service must be EventHandler.

  5. BJ Hargrave says:

    Chris,

    In the DS snippet for registering the handler, you forgot to set the topic property!

    <property name=”event.topics” value=”org/eclipse/equinox/events/MemoryEvent/CRITICAL” />

    Also, the interface for the provided service must be EventHandler.

    <service>
    <provide interface=”org.osgi.service.event.EventHandler”/>
    </service>

  6. Jerome Dotet says:

    See, that’s why the iPOJO Event Admin features are so useful :-)

    It avoids some of these issues….

  7. Scott Lewis says:

    Hey Chris.

    Your readers might be interested in the distributed EventAdmin implementation now available in the Eclipse Communications Framework (ECF) project.

  8. Philipp Kursawe says:

    I am using the EA constantly. However there is a little problem with it. Imagine you have a device service that notifies about attached USB devices. Whenever a new device is connected or disconnected an event is published. Now lets imagine an EventHandler that displays each attached device in a listbox. When the EventHandler is registered *after* one or more devices has already been attached, its listbox would be empty. What would you do, to update the eventhandlers powered listbox after it has been registered? The solution I found is to have the event publisher service watch for eventhandlers for the topic it is publishing with and then, when such a handler gets registered to send only this handler events directly, to update it. So in this example send an “Connected” event for each currently connected device. Another solution would be to have yet another service that the event handler can use to update its status itself. Whats the preferred way to “initialize” such a handler?

  9. Thanks BJ, I made the fix. You miss these things sometimes :)

    I’ll aim to make an example for Eclipse 3.6 M3 that listens to bundle events using EventAdmin.

  10. Fer says:

    Hello All,

    How could return the result of a query from database (in Server/Consumer – handleEvent method) to the Client/Publisher???

    Thanks for advance.

  11. Abhi says:

    Hi Chris

    Am yet to try this out but thought I might as well ask, when you say pub-sub model does it allow for multicast/broadcast semantics. Thus can I have multiple event handlers for the same event and OSGI would clone the event and send it to all the handlers?

    If not does the Event Admin allow developers to watch on it? Something that could be used for different purposes like performance monitoring / event correlation. Of course there are CEP frameworks that do this, but wondering if this can be grown in that direction.

  12. @Fer, EventAdmin is a ONE WAY delivery of the event from the publisher to the subscriber. As a subscriber, you can’t return something to the publisher.

    @Abhi, EventAdmin allows for multiple event handlers to act on published events. To read more about how this is handled, read the OSGi Compendium Specification, section 113.7.3

  13. Fer says:

    Hi Chris,

    If EventAdmin is a one way delivery of the event from the publisher to the subscriber, is it possible that client and server can be publisher and consumer at the same time? For example, the return of query result from database was another event to the client.

  14. Fer, currently EventAdmin is limited to one JVM. If you wanted a distributed model, please look at the Distributed EventAdmin service that Scott Lewis mentioned.

  15. Fer says:

    Thanks Chris, I will look at the Distributed EventAdmin service.
    However, in my case the client and server are at the same JVM and within the same OSGi container.

    Thanks a lot.

  16. @Nirav, by default the OSGi EventAdmin doesn’t provide MQ features like store and forward and fault tolerant messages… however it would take much work to build on top of the basics provided by the EventAdmin service. You could provide your own EventAdmin implementation that does such things or you could ride upon existing EventAdmin implementation and listen for every event and do what you need do.

  17. Philipp Kursawe says:

    Chris, whats your take on my design problem outlined in my comment? Any thoughts on that?

  18. John Bauer says:

    Is the EventAdmin meant to be used as a replacement for the venerable Java Beans Property Change Listeners and other Observable implementations for your model classes? I always struggle with how to implement subject / observer in java data models. I am tired of the Java Beans solution (that doesn’t handle collections etc). The EventAdmin looks interesting because it standardizes the pattern but I am not sure it is a good solution to know when an attribute changes? Any guidance or other suggestions? Thanks.

  19. Jeff Hamm says:

    Is EventAdmin allowed to be configured and started in 3.5.2 eclipse using DS? I recently upgraded from 3.4 to 3.5.2 and now my EventAdmin declaration is Unsatisfied when examined through “ls” and “component” osgi commands. Is there something else I can look at to see what is going on?

  20. Ashok says:

    Hi,

    my question Default galieo eclipse does not have “org.eclipse.equinox.event” plugin whether it support this impl.

    is there any other way to impl this kind of event passing mechanism. i my project build process uses
    eclipse deltapack and eclipse galieo target platform only then this plugin will miss to add this plugin .. please provide me any other way to imple this kind…… any url and code sniphet will good.,

    thanks
    ashok

20 responses so far

Written by . Published in Categories: Planet Eclipse