This section contains information on the following subjects:
Because Oracle Complex Event Processing (or Oracle CEP for short) applications are low latency high-performance driven applications, they run on a lightweight container and are developed using a POJO-based programming model. In POJO (Plain Old Java Object) programming, business logic is implemented in the form of POJOs, and then injected with the services they need. This is popularly called dependency injection. The injected services can range from those provided by Oracle CEP services, such as configuration management, to those provided by another Oracle product such as Oracle Kodo, to those provided by a third party.
Oracle CEP defines a set of core services or components used together to assemble event-driven applications; the typical services are adapters, streams, and processors. You can also create your own business logic POJOs and Spring beans that are part of the application, as well as specialized event beans that are just like Spring beans but with full access to the Oracle CEP framework, such as monitoring and record/playback of events. In addition to these, Oracle CEP includes other infrastructure services, such as caching, clustering, configuration, monitoring, logging, and so on.
All services are deployed on the underlying Oracle microServices Architecture (mSA) technology. Oracle mSA is based upon the OSGi Service Platform defined by the OSGi Alliance.
The following sections provide additional information about the Oracle CEP programming model and creating applications:
Oracle CEP applications and their event processing networks (EPNs) are made up of the following basic components:
The user-defined rules are written using the Event Processing Language (EPL).
All components in an EPN are either event sources (emit events) or event sinks (receive events.) Some components can be both, such as an event bean in the middle of an EPN that receives events from an adapter, for example, and then sends events to a processor.
Components that emit events must implement the com.bea.wlevs.ede.api.EventSource
interface. This interface has one method, setEventSender()
; at runtime the event source component is injected with an com.bea.wlevs.ede.api.EventSender
instance. This EventSender
instance, in turn, has a sentEvent()
method that the component invokes to actually send events to the next component in the EPN.
Components that receive events from event sources must implement the com.bea.wlevs.ede.api.EventSink
interface. This interface has a single callback method, onEvent(), that event sinks implement to receive a list of events from the previous component in the EPN.
Each component in your event processing network (adapter, processor, stream, or event bean) can have an associated configuration file, although only processors are required to have a configuration file. The caching system also uses a configuration file, regardless of whether it is a stage in the event processing network. Component configuration files in Oracle CEP are XML documents whose structure is defined using standard XML Schema. You create a single file that contains configuration for all components in your application, or you can create separate files for each component; the choice depends on which is easier for you to manage.
The following two schema documents define the default structure of application configuration files:
wlevs_base_config.xsd
: Defines common elements that are shared between application configuration files and the server configuration file.
wlevs_application_config.xsd
: Defines elements that are specific to application configuration files.
The structure of application configuration files is as follows. There is a top-level root element named <config>
that contains a sequence of sub-elements. Each individual sub element contains the configuration data for an Oracle CEP component (processor, stream, or adapter). For example:
<?xml version="1.0" encoding="UTF-8"?>
<helloworld:config
xmlns:helloworld="http://www.bea.com/ns/wlevs/example/helloworld">
<processor>
<name>helloworldProcessor</name>
<rules>
<rule id="helloworldRule"><![CDATA[ select * from HelloWorldEvent retain 1 event ]]></rule>
</rules>
</processor>
<adapter>
<name>helloworldAdapter</name>
<message>HelloWorld - the current time is:</message>
</adapter>
<stream monitoring="true" >
<name>helloworldOutstream</name>
<max-size>10000</max-size>
<max-threads>2</max-threads>
</stream>
</helloworld:config>
Oracle CEP applications are made of services that are assembled together to form an Event Processing Network (EPN).
The server uses the Spring framework as its assembly mechanism due to Spring’s popularity and simplicity. Oracle CEP has extended the Spring framework to further simplify the process of assembling applications. This approach allows Oracle CEP applications to be easily integrated with existing Spring-beans, and other light-weight programming frameworks that are based upon a dependency injection mechanism.
A common approach for dependency injection is the usage of XML configuration files to declaratively specify the dependencies and assembly of an application. You assemble an Oracle CEP application an EPN assembly file before deploying it to the server; this EPN assembly file is an extension of the Spring framework XML configuration file.
After an application is assembled, it must be package so that it can be deployed into Oracle CEP. This is a simple process. The deployment unit of an application is a plain JAR file, which must contain, at a minimum, the following artifacts:
After you assemble the artifacts into a JAR file, you deploy this bundle to Oracle CEP so it can immediately start receiving incoming data.
This section describes the lifecycle of an application deployed to Oracle CEP and the sequence of com.bea.wlevs.ede.api
API callbacks. The lifecycle description is broken down into actions that a user performs, such as install an application, suspend it, resume it, and so on.
The point of this section is to show you how Oracle CEP manages an application’s lifecycle so that you can better use the lifecycle APIs in your application. See Oracle CEP APIs for a brief description of these lifecycle APIs, such as RunnableBean
and SuspendableBean
, as well as the
Javadocs.
The application states referenced in this section are returned by the getState()
method on the ApplicationMBean
. These states are specific to Oracle CEP; they are not OSGI bundle states. The possible states are: UNINSTALLED, INITIALIZING, RUNNING, and SUSPENDED.
User action: Install an application or start the server with application already deployed
<wlevs:instance-property>
values are set on adapters and event-beans.@Service
or @ServiceReference
annotations.@Prepare
,@Activate
) on Spring beans as well as factory-created stages.ActivatableBean.afterConfigurationActive()
on all ActivatableBeans
ResumableBean.beforeResume()
on all ResumableBeans
RunnableBean
, Oracle CEP starts it running in a thread.User action: Suspend application.
User action: Resume application.
User action: Uninstall application.
User action: Update application.
This is equivalent to first unistalling an application and then installing it again.
Oracle CEP provides a variety of Java APIs that you use in your adapter or event bean implementation.
This section describes the APIs that you will most typically use in your adapters and event beans; see the Javadoc for the full reference documentation for all classes and interfaces. See Creating Custom Adapters and Event Beans as well as the HelloWorld and FX examples in the installed product, for sample Java code that uses these APIs.
com.bea.wlevs.ede.api EventSink
—Components that receive events from an EventSource
, such as the business logic POJO, must implement this interface. The interface has a callback method, onEvent()
, in which programmers put the code that handles the received events.EventSource
—Components that send events, such as adapters, must implement this interface. The interface has a setEventSender()
method for setting the EventSender
, which actually sends the event to the next component in the network.DisposableBean
—Use if you want to release resources when the application is undeployed. Implement the destroy()
method in your component code.InitializingBean
—Use if you require custom initialization after Oracle CEP has set all the properties of the component. Implement the afterPropertiesSet()
method.ActivatableBean
—Use if you want to run some code after all dynamic configuration has been set and the event processing network has been activated. Implement the afterConfigurationActive()
method.SuspendableBean
—Use if you want to suspend resources or stop processing events when the event processing network is suspended. Implement the suspend()
method.ResumableBean
—Use if you want to perform some task, such as acquire or configure resources, before the component resumes work.RunnableBean
—Use if you want the component to be run in a thread.The Spring framework implements similar bean life cycle interfaces; however, the equivalent Spring interfaces do not allow you to manipulate beans that were created by factories, while the Oracle CEP interfaces do.
Adapter
, AdapterFactory
—Adapters and adapter factories must implement these interfaces respectively.EventBuilder
—Use to create events whose Java representation does not expose the necessary setter and getter methods for its properties. If your event type is represented with a JavaBean with all required getter and setter methods, then you do not need to create an EventBuilder
.EventBuilder.Factory
—Factory for creating EventBuilders
.
Oracle provides an IDE targeted specifically to programmers that want to develop Oracle CEP applications. Oracle CEP Development Environment for Eclipse (Oracle CEP IDE for short) is a set of plugins for the Eclipse IDE designed to help develop, deploy, and debug applications for Oracle CEP.
The key features of the Oracle CEP IDE are as follows:
Although it is not required or assumed that you are using the Oracle CEP IDE, Oracle recommends that you give it a try.
See the online help, integrated in the Oracle CEP IDE product itself, for detailed instructions on using the IDE.
New versions of the IDE are constantly being uploaded to the Oracle Technology Network Web site. Oracle highly recommends that you download the IDE from this site:
http://www.oracle.com/technology/products/event-driven-architecture/cep-ide/10
A version of the Oracle CEP IDE is shipped with the Oracle CEP product, although this version might be older than the one on the Oracle Technology Network site. However, if you want to use the version shipped with the product, follow these steps:
http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/europa/winter/eclipse-jee-europa-winter-win32.zip
http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/europa/winter/eclipse-jee-europa-winter-linux-gtk.tar.gz
This file is called cep-tools-10.3.0.20080917-2044.zip
and is located in the ORACLE_CEP_HOME
/ocep_10.3/eclipse-update-site
directory, where ORACLE_CEP_HOME
refers to the main directory into which you installed Oracle CEP, such as /oracle_cep
.
Help > Software Updates > Find and Install
.Search for New Features
option.New Archived Site
and choose the zip file.Once Eclipse has restarted, you should find all of the Oracle CEP IDE tools available to you.
The following procedure shows the suggested start-to-finish steps to create an Oracle CEP application. Although it is not required to program and configure the various components in the order shown, the procedure shows a typical and logical flow recommended by Oracle.
It is assumed in the procedure that you are using an IDE, although it is not required and the one you use is your choice. For one targeted to Oracle CEP developers, see Oracle CEP Development Environment for Eclipse.
This step involves creating the EPN assembly file, adding the full list of components that make up the application and how they are connected to each other, as well as registering the event types used in your application.
This step combines both designing of your application, in particular determining the components that you need to configure and code, as well as creating the actual XML file that specifies all the components. You will likely be constantly updating this XML file as you implement your application, but Oracle recommends you start with this step so you have a high-level view of your application.
For details, see Creating the EPN Assembly File.
See the EPL Reference Guide.
See Configuring the Complex Event Processor.
See Configuring the Stream Component.
Oracle CEP provides a load generator testing tool that you can use to test your application, in particular the EPL rules. This testing tool can temporarily replace the adapter component in your application, for testing purposes only of course. For details, see Using the Load Generator to Test Your Application.
See Next Steps for the list of steps you should follow after you have completed programming your application, such as packaging and deploying.
You use the EPN assembly file to declare the components that make up your Oracle CEP application and how they are connected to each other. You also use the file to register event types of your application, as well as the Java classes that implement the adapter and POJO components of your application.
For an example of an EPN assembly file, see the foreign exchange (FX) example. For additional information about Spring and OSGi, see Additional Information about Spring and OSGi.
As is often true with Spring, there are different ways to use the tags to define your event network. This section shows one way. See Oracle CEP Spring Tag Reference or the XSD Schema for the full reference information on the other tags and attributes you can use.
For a typical way to create the EPN assembly file for your application, follow these steps:
<beans>
root element and namespace declarations as follows:<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:osgi="http://www.springframework.org/schema/osgi"
xmlns:wlevs="http://www.bea.com/ns/wlevs/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/osgi
http://www.bea.com/ns/wlevs/spring
http://www.springframework.org/schema/osgi/spring-osgi.xsd
http://www.bea.com/ns/wlevs/spring/spring-wlevs.xsd">
...
</beans>
If you are not going to use any of the Spring-OSGI tags in the XML file, then their corresponding namespace declarations, shown in bold in the preceding example, are not required.
<osgi:service ...>
Spring tag to register the factory as an OSGi service. For example:<osgi:service interface="com.bea.wlevs.ede.api.AdapterFactory">
<osgi:service-properties><prop key="type">hellomsgs</prop>
</osgi:service-properties>
<bean class="com.bea.wlevs.adapter.example.helloworld.HelloWorldAdapterFactory" />
</osgi:service>
Specify the Oracle CEP-provided adapter factory (com.bea.wlevs.ede.api.AdapterFactory
) for the interface
attribute. Use the <osgi-service-properties>
tag to give the OSGI service a type name, in the example above the name is hellomsgs
; you will reference this label later when you declare the adapter components of your application. Finally, use the <bean>
Spring tag to register the your adapter factory bean in the Spring application context; this class generates instances of the adapter.
WARNING: | Be sure the type name (hellomsgs in the preceding example) is unique across all applications deployed to a particular Oracle CEP. The OSGI service registry is per server, not per application, so if two different adapter factory services have been registered with the same type name, it is undefined which adapter factory a particular application will use. To avoid this confusion, be sure that the value of the <prop key="type"> entry for each OSGI-registered adapter factory in each EPN assembly file for a server is unique. |
<wlevs:event-type-repository>
tag to register the event types that you use throughout your application, such as in the adapter implementations, business logic POJO, and the EPL rules associated with the processor components. For each event type in your application, add a <wlevs:event-type>
child tag.
Event types are simple JavaBeans that you either code yourself (recommended) or let Oracle CEP automatically generate from the meta data you provide in the <wlevs:event-type>
tag. If you code the JavaBean yourself, use a <wlevs:class>
tag to specify your JavaBean class. You can optionally use the <wlevs:property name="builderFactory">
tag to specify the Spring bean that acts as a builder factory for the event type, if you have programmed a factory. If you want Oracle CEP to automatically generate the JavaBean class, use the <wlevs:metadata>
tag to list each property of the event type. The following example is taken from the FX sample:
<wlevs:event-type-repository>
<wlevs:event-type type-name="ForeignExchangeEvent">
<wlevs:class>
com.bea.wlevs.example.fx.OutputBean$ForeignExchangeEvent
</wlevs:class>
<wlevs:property name="builderFactory">
<bean id="builderFactory"
class="com.bea.wlevs.example.fx.ForeignExchangeBuilderFactory"/>
</wlevs:property>
</wlevs:event-type>
</wlevs:event-type-repository>
See
wlevs:event-type-repository
for reference information about this tag. See Creating the Event Types for additional information about creating event types.
<wlevs:adapter>
tag to declare that the component is part of the event processing network. Use the required id
attribute to give it a unique ID and the provider
attribute to specify the type of data feed to which the adapter will be listening. Use the <wlevs:instance-property>
child tag to pass the adapter the properties it expects. For example, the csvgen
adapter, provided by Oracle CEP to test your EPL rules with a simulated data feed, defines a setPort()
method and thus expects a port
property, among other properties. Use the provider
attribute to specify the adapter factory, typically registered as an OSGi service; you can also use the csvgen
keyword to specify the csvgen
adapter.
The following example declares the helloWorldAdapter
of the HelloWorld example:
<wlevs:adapter id="helloworldAdapter" provider="hellomsgs" manageable="true">
<wlevs:instance-property name="message" value="HelloWorld - the currenttime is:"/>
</wlevs:adapter>
In the example, the property message
is passed to the adapter. The adapter factory provider is hellomsgs
, which refers to the type name of the adapter factory OSGI service. The manageable
attribute, common to all components, enables monitoring for the adapter; by default, manageability of the component is disabled due to possible performance impacts.
See
wlevs:adapter
for reference information about this tag, in particular additional optional attributes and child tags.
<wlevs:processor>
tag. Use the id
attribute to give it a unique ID. Use either the listeners
attribute or <wlevs:listener>
child tag to specify the components that listen to the processor. The following two examples are equivalent:<wlevs:processor id="preprocessorAmer" listeners="spreaderIn"/>
<wlevs:processor id="preprocessorAmer">
<wlevs:listener ref="spreaderIn"/>
</wlevs:processor>
In the examples, the spreaderIn
stream component listens to the preprocessorAmer
processor.
See
wlevs:processor
for reference information about this tag, in particular additional optional attributes, such as manageable
for enabling monitoring of the component.
<wlevs:stream>
tag to declare that the component is part of the event processing network. Use the id
attribute to give it a unique ID. Use the <wlevs:listener>
and <wlevs:source>
child tags to specify the components that act as listeners and sources for the stream. For example:<wlevs:stream id="fxMarketAmerOut">
<wlevs:listener ref="preprocessorAmer"/>
<wlevs:source ref="fxMarketAmer"/>
</wlevs:stream>
In the example, the fxMarketAmerOut
stream listens to the fxMarketAmer
component, and the preprocessorAmer
component in turn listens to the fxMarketAmerOut
stream.
Nest the declaration of the business logic POJO, called outputBean
in the example, using a standard Spring <bean>
tag inside a <wlevs:listener>
tag, as shown:
<wlevs:stream id="spreaderOut" advertise="true">
<wlevs:listener>
<!-- Create business object -->
<bean id="outputBean"
class="com.bea.wlevs.example.fx.OutputBean"
autowire="byName"/>
</wlevs:listener>
</wlevs:stream>
The advertise
attribute is common to all Oracle CEP application assembly tags and is used to register the component as a service in the OSGI registry.
See
wlevs:stream
for reference information about this tag, in particular additional optional attributes, such as manageable
for enabling monitoring of the component.
Event types define the properties of the events that are handled by Oracle CEP applications. Adapters receiving incoming events from different event sources, such as JMS, or financial market data feeds. You must define these events by an event type before a processor is able to handle them. An event type can be created either programmatically using the EventTypeRepository
class or declaratively in the EPN assembly file.
You then use these event types in the adapter and POJO Java code, as well as in the EPL rules associated with the processors.
Events are JavaBean instances in which each property represents a data item from the feed. Oracle recommends that you create your own JavaBean class that represents the event type and register the class in the EPN assembly file. By creating your own JavaBean, you can reuse it and you have complete control over what the event looks like. Alternatively, you can specify the properties of the event type in the EPN assembly file using <wlevs:metadata>
tags, in which case Oracle CEP will use a map; this method is best used for quick prototyping.
The following simple example shows the JavaBean that implements the HelloWorldEvent
:
package com.bea.wlevs.event.example.helloworld;
public class HelloWorldEvent {
private String message;
public String getMessage() {
return message;
}
public void setMessage (String message) {
this.message = message;
}
}
The preceding Java class follows standard JavaBeans programming guidelines. See the JavaBeans Tutorial for additional details.
In addition, Oracle recommends that, if possible, you make your JavaBeans immutable for performance reasons because immutable beans help the garbage collection work much better. Immutable beans are read only (only getters) and have public constructors with arguments that satisfy immutability.
Once you have programmed and compiled the JavaBean that represents your event type, you register it in the EPN assembly file using the <wlevs:event-type>
child tag of <wlevs:event-type-repository>
. Use the <wlevs:class>
tag to point to your JavaBean class, and then optionally use the <wlevs:property name="builderFactory">
tag to specify a custom event builder factory for the event type, which can be used to create event instances that do not follow the JavaBean specification. If want Oracle CEP to generate the bean instance for you, use the <wlevs:metadata>
tag to group standard Spring <entry>
tags for each property. The following example shows both ways:
<wlevs:event-type-repository>
<wlevs:event-type type-name="ForeignExchangeEvent">
<wlevs:class>
com.bea.wlevs.example.fx.OutputBean$ForeignExchangeEvent
</wlevs:class>
<wlevs:property name="builderFactory">
<bean id="builderFactory"
class="com.bea.wlevs.example.fx.ForeignExchangeBuilderFactory"/>
</wlevs:property>
</wlevs:event-type>
<wlevs:event-type type-name="AnotherEvent">
<wlevs:metadata>
<entry key="name" value="java.lang.String"/>
<entry key="age" value="java.lang.Integer"/>
<entry key="address" value="java.lang.String"/>
</wlevs:metadata>
</wlevs:event-type>
</wlevs:event-type-repository>
In the example, ForeignExchangeEvent
is implemented by the ForeignExchangeEvent
inner class of com.bea.wlevs.example.fx.OutputBean
. Instances of AnotherEvent
will be generated by Oracle CEP. The AnotherEvent
has three properties: name
, age
, and address
.
See Using an Event Type Builder Factory for additional information about using an event type builder factory.
You can now reference the event types as standard JavaBeans in the Java code of the adapters and business logic POJO in your application. The following snippet from the business logic POJO HelloWorldBean.java
of the HelloWorld application shows an example:
public void onEvent(List newEvents)
throws RejectEventException {
for (Object event : newEvents) {HelloWorldEvent helloWorldEvent = (HelloWorldEvent) event;
System.out.println("Message: " + helloWorldEvent.getMessage());
}
}
The following EPL rule shows how you can reference the HelloWorldEvent
in a SELECT
statement:
SELECT * FROM HelloWorldEvent RETAIN 1 event
When you register an event type in the repository using the <wlevs:event-type>
tag, Oracle CEP creates instances of the event using the information in the event type class.
Sometimes, however, you might want or need to have more control over how the event type instances are created. This is required if the POJO that represents the event does not expose the necessary getter and setter methods for the event properties. For example, assume the event type has a firstname
property, but the EPL rule that executes on the event type assumes the property is called fname
. Further assume that you cannot change either the event type class (because you are using a shared event class from another bundle, for example) or the EPL rule to make them compatible with each other. In this case you can use an event type builder factory to change the way the event type instance is created so that the property is named fname
rather than firstname
.
When you program the event type builder factory, you must implement the EventBuilder.Factory
inner interface of the
com.bea.wlevs.ede.api.EventBuilder
interface; see the
Javadocs for details about the methods you must implement, such as createBuilder()
and createEvent()
.
The following example of an event type builder factory class is taken from the FX sample:
package com.bea.wlevs.example.fx;
import java.util.HashMap;
import java.util.Map;
import com.bea.wlevs.ede.api.EventBuilder;
import com.bea.wlevs.example.fx.OutputBean.ForeignExchangeEvent;
public class ForeignExchangeBuilderFactory implements EventBuilder.Factory {
public EventBuilder createBuilder() {
return new ForeignExchangeBuilder();
}
static class ForeignExchangeBuilder implements EventBuilder {
private Map<String,Object> values = new HashMap<String,Object>(10);
public Object createEvent() {
return new ForeignExchangeEvent(
(String) values.get("symbol"),
(Double) values.get("price"),
(String) values.get("fromRate"),
(String) values.get("toRate"));
}
public void put(String property, Object value) throws IllegalStateException {
values.put(property, value);
}
}
}
When you register the event type in the EPN assembly file, use the <wlevs:property name="builderFactory">
child tag of the <wlevs:event-type>
tag to specify the name of the factory class. The hard-coded builderFactory
value of the name
attribute alerts Oracle CEP that it should use the specified factory class, rather than its own default factory, when creating instances of this event. For example, in the FX example, the builder factory is registered as shown in bold:
<wlevs:event-type-repository>
<wlevs:event-type type-name="ForeignExchangeEvent">
<wlevs:class>com.bea.wlevs.example.fx.OutputBean$ForeignExchangeEvent</wlevs:class><wlevs:property name="builderFactory">
</wlevs:event-type>
<bean id="builderFactory"
class="com.bea.wlevs.example.fx.ForeignExchangeBuilderFactory"/>
</wlevs:property>
</wlevs:event-type-repository>
Each Oracle CEP application gets its own Java classloader and loads application classes using that classloader. This means that, by default, one application cannot access the classes in another application. However, because the event type repository is a singleton service, you can configure the repository in one bundle and then explicitly export the event type classes so that applications in separate bundles (deployed to the same Oracle CEP server) can use these shared event types.
The event type names in this case are scoped to the entire Oracle CEP server instance. This means that you will get an exception if you try to create an event type that has the same name as an event type that has been shared from another bundle, but the event type classes are different.
To share event type classes, add their package name to the Export-Package
header of the MANIFEST.MF
file of the bundle that contains the event type repository you want to share.
Be sure you deploy the bundle that contains the event type repository before all bundles that contain applications that use the shared event types, or you will get a deployment exception.
After you have programmed all components of your application and created their configuration XML files:
MANIFEST.MF
file that describes the bundle.See Assembling an Oracle CEP Application: Main Steps.
See Deploying Oracle CEP Applications: Main Steps.
See Stopping and Starting the Server.