Esper-OSGi Integration Print E-mail
Written by Valery Abu-Eid   
Wednesday, 11 March 2009 21:41

Integration Scenarios

Taking into account that Esper supports runtime changes, the main challenge that is left for OSGi developers who want to use Esper in the OSGi Environment is deciding upon the optimal design for Esper-OSGi application to make it modular and dynamic so you could deliver features in bundles at runtime. Depending on the usage scenario, you might have additional requirements, like making the Event Model extensible at runtime. I tried three different variants, each of them had advantages and liabilities, below is a small discussion on each of them:

  • Providing main Esper interfaces as OSGi Services: In this scenario the bundle that starts Esper engine registers the interfaces com.espertech.esper.client.EPRuntime and com.espertech.esper.client.EPAdministrator provided by the running Esper engine as OSGi Services. Although this approach requires the least development effort from Event Processing Service Provider, it has two major flaws:
    • Clients either have too much of functionality or nothing at all. Either you give them access to the Administration service so they not only can add new Event Processing Statements and Event Listeners, but also, removing all existing statements and other Esper components, or you don't, but then they will be incapable of performing basic activities such as adding and removing their own Event Listeners, Event Processing Statements, etc.
    • Clients will be responsible for tracing changes to services provided by Event Processing Service Provider. It might sound simple but it's not, say if your client application registered an Event Processing Statement and later a newer version of the Event Processing Service Provider became available which runs a new Engine instance as a replacement for the old one, your client application will need to be able trace these changes then it will need to register the components it have already registered again.
  • Providing general (not-Esper) interfaces for Event Processing as OSGi Services: In this scenario the bundle that starts Esper engine registers general interfaces that provide Event Processing capabilities, the services delegate request to com.espertech.esper.client.EPRuntime and com.espertech.esper.client.EPAdministrator that are used internally (not exposed to other bundles). While this approach tackles the security flaw we had with the previous approach it still have the other: Client applications still need to watch for the Services and recognize the changes so they could re-register needed components when changing Esper engine.
  • The interaction between Event Processing Service provider and client applications is done via OSGi Services, some of them registered by the Event Processing Service Provider, others by the client: The Event Processing Service Provider bundle registers the service that allow clients publish events, clients register the Event Processing Statements and Listeners they provide as OSGi Services (quite similar to how we used to listen to events in the OSGi Environment using the EventAdmin service). With this approach, clients don't need to watch for Engine changes, restarts, etc. all the work related to Event Processing service is made transparent for them, but the main problem of this approach is the hugely increased amount of work and code complexity at the Event Processing Service side.

As you saw, each of the approaches above has its advantages and liabilities, anyway, I believe that the third approach to be the most robust since it carries responsibilities away from client applications, on the contrary, clients need to be aware of the watching problem I talked about and capable of handling it (which is not an easy task at all). Please note, that I didn't tackle scenarios that require the Event Model to be extensible at runtime.

Integration Issues

Prior to working on Esper-OSGi integration scenarios you need to address few concerns:

  • Esper dependencies are OSGi-incompliant: Esper itself is OSGi-compliant but its dependencies are not. Since I use DA-Launcher it takes from me few seconds to tackle the problem (I mean copying the "lib" directory of Esper to the "osgi-incompliant-libraries" directory of DA-Launcher), it you are not using DA-Launcher as the launcher of your OSGi based application you can use Bundler, if you never used it before it will take from you few minutes for the first time and 2-3 minutes when you get used to it.
  • OSGi Environment aware Class Loader: While you didn't have to address class/resource issues when running Esper in a plain Java application, you will have to tackle this problem in the OSGi Environment, so your Event Type classes will be visible to Esper. The solution is relatively simple, all you need to do is setting the Thread Context Class Loader to a Class Loader that can load your event type classes. This problem is tackled in the example application in "/esper-engine-runner/src/main/java/org/dynamicjava/example_applications/osgi_integration/esper/dynamic_esp_example/esper_engine_runner/internal/EsperEngineManager.java"

Example Application

The Example Application represents a Dynamic Esper application that consists of six application bundles:

  • ESP API: Provides a general Event Processing API that allow applications to post events and create Event Processing Statements.
  • Market Data Feed API: Provides Event Types and Listeners that are used in the example application.
  • Market Data Feed Statements: Provides Event Processing Statements as OSGi Services. The example statement validates Market Data Feed for unsupported symbols.
  • Market Data Feed Listener: Registers a listener that listens to the alerts fired by the Symbol Validator statement.
  • Market Data Feed Publisher: Publishes Market Data Feed events that will be validated by the statements of Esper engine.
  • Esper Engine Runner: Responsible for running Esper Engine, registering the Event Processing services and processing client statements and listeners registered as OSGi Services.

All of the bundles other than the ESP API and Market Data Feed API are dynamic. You can uninstall them and re-install them to check how the application will still behave normally, not only you can add new Event Processing Statements in bundles but you can stop the engine and restart it. The solution is not simple and it doesn't have a single key component, so understanding it requires a revision of the source code of different bundles (for which I don't have enough space to present in this article).

Example Application + Source Code: dynamic-esp-example.zip