Object Behavior Within Oracle’s Complex Event Processing Server

This article highlights object bundling behavior within the Complex Event Processing Network. Object bundling behavior is important because the Expression Query Language (EQL) directly references object class names in a similar fashion to SQL referencing table names. There are certain instances where Expression Query Language will bundle objects into a MapEventObject. You may or may not want this behavior to occur depending on what stage of event processing you are in. This article highlights the relationship among the Expression Query Language, POJO classes, and POJO classes bundled within a MapEventObject. In this article I use POJO, Object and event interchangeably.

Events typically enter the Event Sever through Adapters and are forwarded on into the network. If the event passes through a Complex Event Processing (CEP) node, the event is evaluated against the rules associated with that CEP node. If one or more of the Expression Query Language (EQL) rules evaluates to true, then the object passes from the CEP node to the associated stream and then onto the next connecting node.

Let’s take a look at object behavior in the HelloWord demo application included with Oracle’s CEP Server 3.0. In the HelloWorld demo application the CEP engine node is labeled helloworldProcessor.


In the helloworldProcessor the following EQL is executed:

SELECT * from HelloWorldEvent retain 1 event

The CEP node executing the above EPL will allow all of the HelloWorldEvent objects to pass onto the next node, perhaps an event bean or another CEP node. In this case the HelloWorldBean:

public class HelloWorldBean implements EventSink {

@SuppressWarnings({ "unchecked" })
public void onEvent(List newEvents) throws EventRejectedException {

for (Object event : newEvents) {
if (event instanceof HelloWorldEvent) {
HelloWorldEvent helloWorldEvent = (HelloWorldEvent) event;

//Perform operations on the object here


HelloWorldBean receives a list passed to the onEvent method. As you iterate though the list you can check that the event is an “instanceof” the HelloWorldEvent, cast the object and manipulate it.

Objects will not always be forwarded like this based on their event type. When performing a join or matching operation on a stream of events, the events will be bundled into a MapEventObject. Additional Java language processing is required to get a the user defined java classes within the MapEventObject. Let's take a look at some EQL examples and the object bundling that results.

select * from (select * from SpotAndFowardEvent retain 1 events) spotForward, (select * from TheCostOfMoney retain 1 events) costOM where costOM.currencyPair = spotForward.currencyPair and costOM.timePeriodDays = spotForward.timePeriodDays

The EQL above joins two POJO streams of class type SpotAndFowardEvent and TheCostOfMoney. These two classes have attributes currencyPair and timePeriodDays; the join is performed when the attributes of the opposing classes are equal. The output from this CEP process to the event stream is a MapEventObject.

if (event instanceof MapEventObject) {
MapEventObject mEvent = (MapEventObject) event;
for (MapEventObject.Entry entry : mEvent.entrySet()){
System.out.println("getKey: : " + entry.getKey());
//Based on the key determine what object type to cast the value to
//Perform operations on the object here

The Java code above shows you how to get at the objects located in the MapEventObject. There is, however, another way of sending data out of the CEP node when joining two streams using the "INSERT INTO" clause of the EQL language. Here is the same join as the one performed by the EQL above, but in this example we are taking a third POJO object SpotAndFowardAndYield and populating its attributes with the attributes selected from the SpotAndFowardEvent and TheCostOfMoney POJOs.

INSERT INTO SpotAndFowardAndYield(domesticCurrency, foreignCurrency, currencyPair, timePeriodDays) select spotForward.domesticCurrency, spotForward.foreignCurrency, spotForward.currencyPair, costOM.timePeriodDays from (select * from SpotAndFowardEvent retain 1 events) spotForward, (select * from TheCostOfMoney retain 1 events) costOM where costOM.currencyPair = spotForward.currencyPair and costOM.timePeriodDays = spotForward.timePeriodDays

Now instead of having to iterate through a MapEventObject you can just check to see if the event is an instance of SpotAndFowardAndYield and cast it to that type if you are so inclined.

if (event instanceof SpotAndFowardAndYield) {
SpotAndFowardAndYield sfy = (SpotAndFowardAndYield) event;

//Perform operations on the object here

So what is the best practice, either INSERT INTO a new object or manipulating a MapEventObject? The answer is dependent on where your are in your event processing network. If you are going to need to forward objects to another CEP node, INSERT INTO will provide a cleaner solution, mainly because the MapEventObject can not be manipulated very easily by the CEP engine. If you are going to route one or more of the objects to separate streams, or if you are at the terminal node of your EPN then it might make sense to keep the objects separate within the MapEventObject.

When mapping a time/event based algorithm to an event processing network, it is important to keep this behavior in mind as it directly impacts the event object model within the network. Building a visual EPN diagram and mapping out how you are going to deal with combining streams, before you code, can possibly save a great deal of time.


Post a Comment:
  • HTML Syntax: NOT allowed



« July 2016