Skip Headers
Oracle® CEP IDE Developer's Guide for Eclipse
Release 11gR1 (11.1.1)
E14301-02
  Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
 
Next
Next
 

1 Overview of Creating Oracle CEP Applications

This section contains information on the following subjects:

1.1 Overview of the Oracle CEP Programming Model

Because Oracle CEP 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 (see http://www.osgi.org/ for more information.)

The following sections provide additional information about the Oracle CEP programming model and creating applications:

1.1.1 Components of the Oracle CEP Event Processing Network

The Oracle CEP Event Processing Network (EPN) represents the interconnections between the various Oracle CEP components of an Oracle CEP application.

Oracle CEP applications and their event processing networks (EPNs) are made up of the following basic components:

For more information, see:

1.1.1.1 Nested Stages

When you define a child stage within a parent stage, the child stage is said to be nested. Only the parent stage can specify the child stage as a listener.

Example 1-1 shows the EPN assembly source in which HelloWorldBean is nested within the helloworldOutputChannel. Only the parent helloworldOutputChannel may specify the nested bean as a listener.

Example 1-1 EPN Assembly File With Nested Bean

<wlevs:adapter id="helloworldAdapter" class="com.bea.wlevs.adapter.example.helloworld.HelloWorldAdapter" >
    <wlevs:instance-property name="message" value="HelloWorld - the current time is:"/>
</wlevs:adapter>

<wlevs:channel id="helloworldInputChannel" event-type="HelloWorldEvent" >
    <wlevs:listener ref="helloworldProcessor"/>
    <wlevs:source ref="helloworldAdapter"/>
</wlevs:channel>

<wlevs:processor id="helloworldProcessor" />

<wlevs:channel id="helloworldOutput" event-type="HelloWorldEvent" advertise="true">
    <wlevs:listener>
        <bean class="com.bea.wlevs.example.helloworld.HelloWorldBean"/>
    </wlevs:listener>
    <wlevs:source ref="helloworldProcessor"/>
</wlevs:channel>

Alternatively, you can define this EPN so that all nodes are nested as Example 1-2 shows. The helloworldAdapter, the outermost parent stage, is the only stage accessible to other stages in the EPN.

Example 1-2 EPN Assembly File With all Nodes Nested

<wlevs:adapter id="helloworldAdapter" class="com.bea.wlevs.adapter.example.helloworld.HelloWorldAdapter" >
    <wlevs:instance-property name="message" value="HelloWorld - the current time is:"/>
    <wlevs:listener>
        <wlevs: id="helloworldInput" event-type="HelloWorldEvent" >
            <wlevs:listener>
                <wlevs:processor id="helloworldProcessor">
                    <wlevs:listener>
                        <wlevs: id="helloworldOutput" event-type="HelloWorldEvent">
                            <wlevs:listener>
                                <bean class="com.bea.wlevs.example.helloworld.HelloWorldBean"/>
                            </wlevs:listener>
                        </wlevs:>
                    </wlevs:listener>
                </wlevs:processor>
            </wlevs:listener>
        </wlevs:>
    </wlevs:listener>
</wlevs:adapter>

For more information, see Section 5.2.6, "Nested Stages".

1.1.1.2 Foreign Stages

You can refer to a stage simply by its id attribute when you define both the source and target stage in the same application.

To refer to a stage you define in a different application, you use the following syntax:

FOREIGN-APPLICATION-NAME:FOREIGN-STAGE-ID

Where FOREIGN-APPLICATION-NAME is the name of the application in which you defined the foreign stage and FOREIGN-STAGE-ID is the id attribute of the foreign stage.

Example 1-3 shows how the reference in application1 to the foreign stage HelloWorldBeanSource that you define in application application2.

Example 1-3 Application 1 Referencing Foreign Stage in Application 2

<wlevs:stream id="helloworldInstream" >
    <wlevs:listener ref="helloworldProcessor"/>
    <wlevs:source ref="application2:HelloWorldBeanSource"/>
</wlevs:stream>

Example 1-4 Foreign Stage in Application 2

<wlevs:event-bean id="HelloWorldBeanSource"
class="com.bea.wlevs.example.helloworld.HelloWorldBeanSource"
advertise="true"/> 

1.1.2 Event Types

Event types define the properties of the events that are handled by Oracle CEP applications. Adapters receive 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. You then use these event types in adapter and POJO Java code, and in the Oracle CQL and EPL rules you associate with the processors.

Events are JavaBean or Java class instances in which each property represents a data item from the event source. Oracle CEP supports the following event type implementations:

Oracle recommends that you define your events using the Java Bean (or Java class and factory) approach. Doing so allows you greater flexibility to deal with event types as part of your application logic and can simplify integration with existing systems.

Alternatively, you can specify the properties of the event type declaratively in the EPN assembly file using wlevs:property tags, in which case Oracle CEP will use a java.util.Map or tuple. Tuple is the default and is similar to the Oracle CQL tuple. It essentially provides the user with an optimized implementation, however, the user must always set and get its value using the EventTypeRepository APIs. This approach is best used for quick prototyping or when the application developer does not need to deal with JavaBean events as part of the application logic or due to integration to some legacy system.

For more information, see:

1.1.2.1 Event Type Instantiation and Immutability

In Oracle CEP, events are conceptually immutable. Once an event is instantiated (created and initialized), the Oracle CEP server will not change it and the application developer should not change it, either.

In Oracle CEP, an event can be instantiated either by the application developer or by the Oracle CEP server. For example:

  • An application developer can instantiate an event in an inbound Spring-bean, event-bean, or adapter.

  • Oracle CEP server can instantiate an event when a CQL processor outputs an event to a downstream component.

The Oracle CEP server uses the following procedure to instantiate an event for a Java Bean event type:

  • It invokes an empty-argument public constructor for the Java class.

  • It invokes a public setter method following Java Bean conventions for each event property.

Note that even though the event is conceptually immutable, setter methods must be available in this case. The Oracle CEP server will invoke these setter methods only once during event initialization.

If a Java Bean event is only being created by the application developer, then making the Java class immutable can help improve performance. A truly immutable bean is read only (provides only getters) and has public constructors with arguments that satisfy immutability. Note that immutability is not possible if the event is being output from a CQL processor, but it is possible if the event is used only as input.

The Oracle CEP server uses the following procedure to instantiate an event for a Java class event type:

  • It acquires an instance of the com.bea.wlevs.ede.api.EventBuilder.Factory you associate with the event type by calling the factory's createBuilder method.

  • It instantiates an event by calling the createEvent method.

Note that again, even though the event is conceptually immutable, setter methods must be available in this case. And, again, the Oracle CEP server will invoke these setter methods only once, indirectly, when the factory initializes the event.

1.1.2.2 Event Type Data Types

When creating event types, observe the data type restrictions for the following event types:

For more information, see:

  • "Datatypes" in the Oracle CEP CQL Language Reference

  • "Overview of the EPL Language" in the Oracle CEP EPL Language Reference

1.1.2.2.1 Event Types Specified as Java Bean, Java Class, or java.util.Map

When you define an event type as a Java Bean, Java class, or java.util.Map, you may use any Java type for its properties.

For more information, see

1.1.2.2.2 Event Types Specified as a Tuple

When you specify the properties of the event type declaratively in the EPN assembly file as a tuple, you may only use the types specified by the com.bea.wlevs.ede.api.Type class. Table 1-1 describes the usage for each of the types this class defines.

Table 1-1 com.bea.wlevs.ede.api.Type Usage

Type Usage

bigint

Numeric values in the range that java.math.BigInteger specifies.

boolean

Boolean values as java.lang.Boolean specifies.

byte

Byte values as java.lang.Byte specifies.

char

Single or multiple character values. Use for both char and java.lang.String values.

Optionally, you may specify the length of the char value as Example 1-5 shows for the property with name id. The default length is 256 characters. If you need more than 256 characters you should specify an adequate length.

double

Numeric values in the range that java.lang.Double specifies.

float

Numeric values in the range that java.lang.Float specifies.

int

Numeric values in the range that java.lang.Integer specifies.

interval

Interval values as the Oracle CQL INTERVAL data type specifies.

For more information, see "Interval Literals" in the Oracle CEP CQL Language Reference

object

An opaque data type that can be represented as a java.lang.Object.

timestamp

A timestamp String in a format that java.util.Date specifies.

For example:

"Sat, 12 Aug 1995 13:30:00 GMT+0430"

xmltype

XML values as the Oracle CQL XMLTYPE data type specifies.

For more information, see "SQL/XML (SQLX)" in the Oracle CEP CQL Language Reference.


Example 1-5 shows how to use these types:

Example 1-5 Using com.bea.welvs.ede.api.Type Data Types

<wlevs:event-type-repository>
        <wlevs:event-type type-name="SimpleEvent">
            <wlevs:properties>
                <wlevs:property name="id" type="char" length="4" />
                <wlevs:property name="msg" type="char" />
                <wlevs:property name="count" type="double" />
                <wlevs:property name="time_stamp" type="timestamp" />
        </wlevs:properties>
    </wlevs:event-type>
...
</wlevs:event-type-repository>

For more information, see Section 1.5.4, "How to Create an Oracle CEP Event Type as a Tuple".

1.1.2.2.3 Event Types for use With a Table Source

When you specify the properties of an event type (as any of a Java Bean, Java class, java.util.Map, or tuple) for use with a relational database table, you must observe additional JDBC type restrictions. For more information, see:

For more information, see:

1.1.2.2.4 Event Types for use With the csvgen Adapter

When you specify the properties of an event type (as any of a Java Bean, Java class, java.util.Map, or tuple) for use with the csvgen adapter, you may only use the data types that Table 1-2 describes.

Table 1-2 csvgen Adapter Types

Type Usage

char

Single or multiple character values. Use for both char and java.lang.String values.

Optionally, you may specify the length of the char value as Example 1-5 shows for the property with name id. The default length is 256 characters. If you need more than 256 characters you should specify an adequate length.

int

Numeric values in the range that java.lang.Integer specifies.

long

Numeric values in the range that java.lang.Long specifies.

double

Numeric values in the range that java.lang.Double specifies.


For more information, see:

1.1.3 Stream Sources and Stream Sinks and Relation Sources and Relation Sinks

All components in an EPN either emit events or 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.

Oracle CEP models event flow as either streams or relations:

  • A stream S is a bag multi-set of elements (s,T) where s is in the schema of S and T is in the time domain. Stream elements are tuple-timestamp pairs, which can be represented as a sequence of timestamped tuple insertions. In other words, a stream is a sequence of timestamped tuples. There could be more than one tuple with the same timestamp. The tuples of an input stream are required to arrive at the system in the order of increasing timestamps.

    You specify a channel as a stream by setting EPN assembly element wlevs: attribute is-relation to false (the default).

  • A relation is an unordered, time-varying bag of tuples: in other words, an instantaneous relation. At every instant of time, a relation is a bounded set. It can also be represented as a sequence of timestamped tuples that includes insertions, deletions, and updates to capture the changing state of the relation.

    You specify a channel as a realtion by setting EPN assembly element wlevs:channel attribute is-relation to true.

For more information, see:

1.1.3.1 Stream and Relation Sources

All components that emit events must implement the com.bea.wlevs.ede.api.StreamSource or com.bea.wlevs.ede.api.RelationSource interface.

The StreamSource interface has one method, setEventSender(); at runtime the event source component is injected with an com.bea.wlevs.ede.api.StreamSender instance. The StreamSender instance, in turn, has a sendInsertEvent() method that the component invokes to actually send events to the next component in the EPN. The StreamSender instance also provides a sendHeartbeat() method. The sendHeartBeat() method applies only to application-timestamped channels.

RelationSource, through the RelationSender, provides a sendUpdateEvent() and sendDeleteEvent() methods.

1.1.3.2 Stream and Relation Sinks

Components that receive events must implement the com.bea.wlevs.ede.api.StreamSink or com.bea.wlevs.ede.api.RelationSink interface.

The StreamSink interface has a single callback method, onInsertEvent(), that components implement to receive a list of events from the previous component in the EPN.

The RelationSink interface extends StreamSink to model an Oracle CQL relation sink. The RelationSink interface also provides an onDeleteEvent() and onUpdateEvent() methods.

1.1.4 Component Configuration Files

Each component in your event processing network (adapter, processor, channel, 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 wlevs_application_config.xsd schema file describes the structure of component configuration files. This XSD schema imports the following schemas:

  • wlevs_base_config.xsd: Defines common elements that are shared between application configuration files and the server configuration file

  • wlevs_eventstore_config.xsd: Defines event store-specific elements.

  • wlevs_diagnostic_config.xsd: Defines diagnostic elements.

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, channel, or adapter). For example:

<?xml version="1.0" encoding="UTF-8"?><n1:config xmlns:n1="http://www.bea.com/ns/wlevs/config/application"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">    <processor>        <name>helloworldProcessor</name>        <rules>            <query id="helloworldRule">                <![CDATA[ select * from helloworldInputChannel [Now] ]]>            </query>        </rules>    </processor>
    <channel>
        <name>helloworldInputChannel</name>
        <max-size>10000</max-size>
        <max-threads>2</max-threads>
    </channel>
    <channel>
        <name>helloworldOutputChannel</name>
        <max-size>10000</max-size>
        <max-threads>2</max-threads>
    </channel>
</n1:config>

For more information, see:

1.1.5 Accessing Component and Server Configuration Using the ConfigurationPropertyPlaceholderConfigurer Class

Using the ConfigurationPropertyPlaceholderConfigurer class, you can reference existing configuration file properties, in both component configuration and server configuration files, using a symbolic placeholder. This allows you to define a value in one place and refer to that one definition rather than hard-coding the same value in many places.

For example, given the element that Example 1-6 shows, you can refer to the netio element port value as Example 1-7 shows.

Example 1-6 netio Element

<netio>
    <name>MyNetIO</name>
    <port>9003</port>
</netio>

Example 1-7 Accessing the netio Element port Value

<property name="myprop" value="${MyNetIO.port}"/>

To use this feature, insert a ConfigurationPropertyPlaceholderConfigurer bean in the application context configuration file of your application bundle as Example 1-8 shows.

Example 1-8 Adding a ConfigurationPropertyPlaceholderConfigurer

 <bean class="com.bea.wlevs.spring.support.ConfigurationPropertyPlaceholderConfigurer"/>

For complete details, see the com.bea.wlevs.spring.support.ConfigurationPropertyPlaceholderConfigurer class in the Oracle CEP Java API Reference.

1.1.6 EPN Assembly File

You assemble an Oracle CEP application an Event Processing Network (EPN) assembly file before deploying it to the server; this EPN assembly file is an extension of the Spring framework XML configuration file.

For some Oracle CEP features, you specify some configuration in the component configuration file and some in the EPN assembly file.

The spring-wlevs-v11_0_0_0.xsd schema file describes the structure of EPN assembly files.

The structure of EPN assembly files is as follows. There is a top-level root element named beans that contains a sequence of sub-elements. Each individual sub-element contains the configuration data for an Oracle CEP component. For example:

<?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.xsd
            http://www.springframework.org/schema/osgi
            http://www.springframework.org/schema/osgi/spring-osgi.xsd
            http://www.bea.com/ns/wlevs/spring
            http://www.bea.com/ns/wlevs/spring/spring-wlevs-v11_0_0_0.xsd">

    <wlevs:event-type-repository>
        <wlevs:event-type type-name="HelloWorldEvent">
            <wlevs:class>com.bea.wlevs.event.example.helloworld.HelloWorldEvent</wlevs:class>
        </wlevs:event-type>
    </wlevs:event-type-repository>

    <wlevs:adapter id="helloworldAdapter" 
                   class="com.bea.wlevs.adapter.example.helloworld.HelloWorldAdapter" >
        <wlevs:instance-property name="message" value="HelloWorld - the current time is:"/>
    </wlevs:adapter>

    <wlevs:channel id="helloworldInputChannel" event-type="HelloWorldEvent" >
        <wlevs:listener ref="helloworldProcessor"/>
        <wlevs:source ref="helloworldAdapter"/>
    </wlevs:channel>

    <wlevs:processor id="helloworldProcessor" />

    <wlevs:channel id="helloworldOutputChannel" 
                   event-type="HelloWorldEvent" advertise="true">
        <wlevs:listener>
            <bean class="com.bea.wlevs.example.helloworld.HelloWorldBean"/>
        </wlevs:listener>
        <wlevs:source ref="helloworldProcessor"/>
    </wlevs:channel>

</beans>

For more information, see:

1.1.7 How Components Fit Together

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:

  • The compiled application Java code of the business logic POJO.

  • Component configuration files. Each processor is required to have a configuration file, although adapters and streams do not need to have a configuration file if the default configuration is adequate and you do not plan to monitor these components.

  • The EPN assembly file.

  • A MANIFEST.MF file with some additional OSGi entries.

After you assemble the artifacts into a JAR file, you deploy this bundle to Oracle CEP so it can immediately start receiving incoming data.

For more information, see Chapter 14, "Assembling and Deploying Oracle CEP Applications".

1.1.8 Oracle CEP Application Lifecycle

Figure 1-1 shows a state diagram for the Oracle CEP application lifecycle. In this diagram, the state names (STARTING, INITIALIZING, RUNNING, SUSPENDING, SUSPENDED, and FAILED) correspond to the ApplicationRuntimeMBean method getState() return values. These states are specific to Oracle CEP; they are not OSGi bundle states.

Figure 1-1 Oracle CEP Application Lifecycle State Diagram

Description of Figure 1-1 follows
Description of "Figure 1-1 Oracle CEP Application Lifecycle State Diagram"


Note:

For information on Oracle CEP server lifecycle, see "Oracle CEP Server Lifecycle" in the Oracle CEP Administrator's Guide.

This section describes the lifecycle of an application deployed to the Oracle CEP server and the sequence of com.bea.wlevs.ede.api API callbacks. The lifecycle description is broken down into actions that a user performs, including:

This information explains how Oracle CEP manages an application's lifecycle so that you can better use the lifecycle APIs in your application. For a description of these APIs (such as RunnableBean and SuspendableBean), see:

1.1.8.1 User Action: Installing an Application or Start the Server With Application Already Deployed

Oracle CEP performs the following actions:

  1. Oracle CEP installs the application as an OSGI bundle. OSGI resolves the imports and exports, and publishes the service.

  2. Oracle CEP creates beans (for both standard Spring beans and those that correspond to the Oracle CEP tags in the EPN assembly file). For each bean, Oracle CEP:

    • Sets the properties on the Spring beans. The <wlevs:instance-property> values are set on adapters and event-beans.

    • Injects appropriate dependencies into services specified by @Service or @ServiceReference annotations.

    • Injects appropriate dependencies into static configuration properties.

    • Calls InitializingBean.afterPropertiesSet().

    • Calls configuration callbacks (@Prepare,@Activate) on Spring beans as well as factory-created stages.

  3. Application state is now INITIALIZING.

  4. Oracle CEP registers the MBeans.

  5. Oracle CEP calls ActivatableBean.afterConfigurationActive() on all ActivatableBeans

  6. Oracle CEP calls ResumableBean.beforeResume() on all ResumableBeans

  7. For each bean that implements RunnableBean, Oracle CEP starts it running in a thread.

  8. Application state is now RUNNING.

1.1.8.2 User Action: Suspend Application

Oracle CEP performs the following actions:

  1. Oracle CEP calls SuspendableBean.suspend()on all SuspendableBeans.

  2. Application state is now SUSPENDED.

1.1.8.3 User Action: Resume Application

Oracle CEP performs the following actions:

  1. Oracle CEP calls ResumableBean.beforeResume()on all ResumableBeans

  2. For each bean that implements RunnableBean, Oracle CEP starts it running in a thread.

  3. Application state is now RUNNING.

1.1.8.4 User Action: Uninstall Application

Oracle CEP performs the following actions:

  1. Oracle CEP calls SuspendableBean.suspend() on all SuspendableBeans.

  2. Oracle CEP unregisters MBeans.

  3. Oracle CEP calls DisposableBean.dispose() on all DisposableBeans.

  4. Oracle CEP uninstalls application bundle from OSGI.

1.1.8.5 User Action: Update Application

This is equivalent to first unistalling an application and then installing it again.

See:

1.1.9 Oracle CEP APIs

Oracle CEP provides a variety of Java APIs that you use in your adapter or event bean implementation.

This section describes the APIs in the com.bea.wlevs.ede.api package that you will most typically use in your adapters and event beans.

  • Adapter—Adapters must implement this interface.

  • AdapterFactory—Adapter factories must implement this interface.

  • Component life cycle interfaces—If you want some control over the life cycle of the component you are programming, then your component should implement one or more of the following interfaces:

    • 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.

    • 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.

    • 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.

    • SuspendableBean—Use if you want to suspend resources or stop processing events when the event processing network is suspended. Implement the suspend() method.

    See also Appendix G, "Oracle CEP Metadata Annotation Reference" for additional lifecycle annotations.

  • 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.

  • StreamSink—Components that want to receive events as an Oracle CEP stream must implement this interface. An Oracle CEP stream has the following characteristics:

    • Append-only, that is, events are always appended to the end of the stream.

    • Unbounded and generally need a window to be defined before it can be processed.

    • Events have non-decreasing time-stamps.

    The interface has a callback method, onInsertEvent(), in which programmers put the code that handles the received events.

  • StreamSource—Components that send events modeling an Oracle CEP stream, such as adapters, must implement this interface. The interface has a setEventSender() method for setting the StreamSender, which actually sends the event to the next component in the network.

  • RelationSink—Components that want to receive events modeling an Oracle CEP relation must implement this interface. An Oracle CEP relation has the following characteristics:

    • Supports events that insert, delete, and update its content.

    • Is always known at an instant time.

    • Events have non-decreasing time-stamps.

    The interface has callback methods onDeleteEvent() and onInsertEvent() in which programmers put the code that handles event deletion and event insertion.

  • RelationSource—Components that send events modeling an Oracle CEP relation, such as adapters, must implement this interface. The interface has a setEventSender() method for setting the RelationSender, which actually sends the event to the next component in the network.

For more information, see:

1.2 Oracle CEP IDE for Eclipse

Oracle provides an IDE targeted specifically to programmers that want to develop Oracle CEP applications. Oracle CEP IDE for Eclipse 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 for Eclipse 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.

For detailed instructions on installing and using the IDE, see Chapter 2, "Overview of the Oracle CEP IDE for Eclipse".

1.3 Creating an Oracle CEP Application

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 Section 1.2, "Oracle CEP IDE for Eclipse."

To create an Oracle CEP application:

  1. Set up your environment as described in "Setting Your Development Environment" in the Oracle CEP Getting Started.

  2. Design your event processing network (EPN).

    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 Section 1.4, "Creating the EPN Assembly File."

  3. Design the rules that the processors are going to use to select events from the channel.

    See:

    • Oracle CEP CQL Language Reference

    • Oracle CEP EPL Language Reference


    Note:

    Oracle CQL replaces Event Processing Language (EPL) in Oracle CEP Release 11gR1 (11.1.1). Oracle CEP supports EPL for backwards compatibility.

  4. Determine the event types that your application is going to use, and, if creating your own JavaBean, program the Java file.

    See Section 1.5, "Creating Oracle CEP Event Types."

  5. Program, and optionally configure, the adapters or event beans that act as inbound, intermediate, or outbound components of your event processing network. You can create your own adapters or event beans, or use the adapters provided by Oracle CEP. For details, see:

  6. Configure the processors by creating their component configuration XML files; the most important part of this step is designing and declaring the initial rules that are associated with each processor.

    See:

  7. Optionally configure the channels that stream data between adapters, processors, and the business logic POJO by creating their configuration XML files.

    See Chapter 9, "Configuring Channels."

  8. Optionally configure the caching system to publish or consume events to and from a cache to increase the availability of the events and increase the performance of your applications.

    See Chapter 12, "Configuring Caching."

  9. Optionally, use the Oracle CEP server log subsystem to write log messages from your application to the Oracle CEP server log:

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    ...
    Log LOG=LogFactory.getLog("LogName");
    ...
    LOG.debug("Some debug information");
    ...
    

    Using the Oracle CEP Visualizer, you can deploy your application, configure the log level for your application, and view the Oracle CEP server console.

    For more information, see:

    • "Configuring Logging and Debugging for Oracle CEP" in the Oracle CEP Administrator's Guide

    • "How to Configure Component Logging" in the Oracle CEP Visualizer User's Guide

    • "How to View Console Output" in the Oracle CEP Visualizer User's Guide

See Section 1.7, "Next Steps" for the list of steps you should follow after you have completed programming your application, such as packaging and deploying.

1.4 Creating the EPN Assembly File

You use the Event Processing Network (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" in the Oracle CEP Getting Started. For additional information about Spring and OSGi, see Appendix A, "Additional Information about Spring and OSGi."

1.4.1 How to Create the EPN Assembly File Using Oracle CEP IDE for Eclipse

The most efficient and least error-prone way to create and edit the EPN file is using the EPN editor in the Oracle CEP IDE for Eclipse. Optionally, you can create a channel configuration file manually (see Section 1.4.2, "How to Create the EPN Assembly File Manually").

For more information, see Section 5.2, "EPN Editor Overview".

To create the EPN assembly file using Oracle CEP IDE for Eclipse:

  1. Create an Oracle CEP project.

    See Section 3.2, "Creating Oracle CEP Projects".

  2. Open the EPN editor.

    See Section 5.1, "Opening the EPN Editor".

  3. Create and connect nodes on the EPN.

    See Section 5.4, "Using the EPN Editor".

1.4.2 How to Create the EPN Assembly File Manually

Although the Oracle CEP IDE for Eclipse EPN editor is the most efficient and least error-prone way to create and edit the EPN file (see Section 1.4.1, "How to Create the EPN Assembly File Using Oracle CEP IDE for Eclipse"), alternatively, you can also create and maintain the EPN file manually.

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 Section B.2, "EPN Assembly Schema spring-wlevs-v11_0_0_0.xsd" for the full reference information on the other tags and attributes you can use.

To create the EPN assembly file manually:

  1. Using your favorite XML or plain text editor, create an XML file with the <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.xsd
      http://www.springframework.org/schema/osgi
      http://www.springframework.org/schema/osgi/spring-osgi.xsd
      http://www.bea.com/ns/wlevs/spring
      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.

  2. If you have programmed an adapter factory, add an <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>
            <entry key="type" value="hellomsgs<"/entry>
        </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.


    Caution:

    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 <entry key="type" ...> entry for each OSGI-registered adapter factory in each EPN assembly file for a server is unique.

  3. Add a <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:property> 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 Section D.12, "wlevs:event-type-repository" for reference information about this tag.

    See Section 1.5, "Creating Oracle CEP Event Types" for additional information about creating event types.

  4. For each adapter component in your application, add a <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" advertise="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 advertise attribute, common to all components, enables monitoring for the adapter; by default, manageability of the component is disabled due to possible performance impacts.

    See Section D.2, "wlevs:adapter" for reference information about this tag, in particular additional optional attributes and child tags.

  5. For each processor component in your application, add a <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 channel component listens to the preprocessorAmer processor.

    See Section D.20, "wlevs:processor" for reference information about this tag, in particular additional optional attributes, such as advertise for enabling monitoring of the component.

  6. For each channel component in your application, add a <wlevs:channel> 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 channel. For example:

    <wlevs:channel id="fxMarketAmerOut">
        <wlevs:listener ref="preprocessorAmer"/>
        <wlevs:source ref="fxMarketAmer"/>
    </wlevs:channel>
    

    In the example, the fxMarketAmerOut channel listens to the fxMarketAmer component, and the preprocessorAmer component in turn listens to the fxMarketAmerOut channel.

    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:channel id="spreaderOut" advertise="true">
        <wlevs:listener>
           <!-- Create business object -->
            <bean id="outputBean" 
                  class="com.bea.wlevs.example.fx.OutputBean" 
                  autowire="byName"/>
        </wlevs:listener>
    </wlevs:channel>
    

    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.

    Section D.10, "wlevs:channel" for reference information about this tag, in particular additional optional attributes, such as advertise for enabling monitoring of the component.

1.5 Creating Oracle CEP Event Types

Event types define the properties of the events that are handled by Oracle CEP applications. Adapters receive 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. You then use these event types in the adapter and POJO Java code, as well as in the Oracle CQL and EPL rules you associate with the processors.

This section describes:

For more information, see Section 1.1.2, "Event Types".

1.5.1 How to Create an Oracle CEP Event Type as a JavaBean

This procedure describes how to create and register an Oracle CEP event type as a Java Bean. This is the preferred approach.

See the JavaBeans Tutorial at http://java.sun.com/docs/books/tutorial/javabeans/ for additional details.

For more information on valid event type data types, see Section 1.1.2.2.1, "Event Types Specified as Java Bean, Java Class, or java.util.Map".

To create an Oracle CEP event type as a Java bean:

  1. Create a Java Bean class to represent your event type.

    Follow standard JavaBeans programming guidelines. See the JavaBeans Tutorial at http://java.sun.com/docs/books/tutorial/javabeans/ for additional details.

    Oracle recommends that, if possible, you make your event type JavaBeans immutable to improve performance. For more information, see Section 1.1.2.1, "Event Type Instantiation and Immutability".

    Example 1-9 shows the MarketEvent which is implemented by the com.bea.wlevs.example.algotrading.event.MarketEvent class.

    Example 1-9 MarketEvent Class

    package com.bea.wlevs.example.algotrading.event;
     
    import java.util.Date;
     
    public final class MarketEvent {
        private final Long timestamp;
     
        private final String symbol;
     
        private final Double price;
     
        private final Long volume;
     
        private final Long latencyTimestamp;
     
        public MarketEvent(final Long timestamp, final String symbol,
                final Double price, final Long volume, final Long latencyTimestamp) {
            this.timestamp = timestamp;
            this.symbol = symbol;
            this.price = price;
            this.volume = volume;
            this.latencyTimestamp = latencyTimestamp;
        }
     
        public Double getPrice() {
            return price;
        }
     
        public String getSymbol() {
            return symbol;
        }
     
        public Long getTimestamp() {
            return timestamp;
        }
     
        public Long getLatencyTimestamp() {
            return latencyTimestamp;
        }
     
        public Long getVolume() {
            return volume;
        }
     
    }
    
  2. Compile the JavaBean that represents your event type.

  3. Register your JavaBean event type in the Oracle CEP event type repository:

    1. To register declaratively, edit the EPN assembly file using the wlevs:event-type-repository element wlevs:event-type child element as Example 1-10 shows.

      Example 1-10 EPN Assembly File event-type-repository

      <wlevs:event-type-repository>
          <wlevs:event-type type-name="MarketEvent">
            <wlevs:class>
                com.bea.wlevs.example.algotrading.event.MarketEvent
            </wlevs:class>
          </wlevs:event-type>
      </wlevs:event-type-repository>
      
    2. To register programatically, use the EventTypeRepository class as Example 1-11 shows.

      Example 1-11 Programmatically Registering an Event

      EventTypeRepository rep = getEventTypeRepository();
      rep.registerEventType(
          "MarketEvent", 
          com.bea.wlevs.example.algotrading.event.MarketEvent.getClass()
      );
      

      For more information, see Section 1.5.6, "Accessing the Event Type Repository".

  4. Use the event type:

    • Reference the event types as standard JavaBeans in the Java code of the adapters and business logic POJO in your application.

      public void onEvent(List newEvents)
              throws RejectEventException {
          for (Object event : newEvents) {
                  MarketEvent marketEvent = (MarketEvent) event;
              System.out.println("Price: " + marketEvent.getPrice());
          }
      }
      
    • Access the event types from Oracle CQL and EPL rules:

      The following Oracle CQL rule shows how you can reference the MarketEvent in a SELECT statement:

      <query id="helloworldRule">
          <![CDATA[ select MarketEvent.price from marketEventChannel [Now] ]]>
      </query>
      

1.5.2 How to Create an Oracle CEP Event Type as a Java Class

This procedure describes how to create and register an Oracle CEP event type as a Java class that does not conform to the JavaBeans programming guidelines.

For more information on valid event type data types, see Section 1.1.2.2.1, "Event Types Specified as Java Bean, Java Class, or java.util.Map".

To create an Oracle CEP event type as a Java class:

  1. Create a Java class to represent your event type.

    Oracle recommends that, if possible, you make your event type Java class immutable to improve performance. For more information, see Section 1.1.2.1, "Event Type Instantiation and Immutability".

    Example 1-9 shows the ForeignExchangeEvent which is implemented by the ForeignExchangeEvent inner class of com.bea.wlevs.example.fx.OutputBean.

    Example 1-12 ForeignExchangeEvent Class: Does not Conform to JavaBean Standards

    package com.bea.wlevs.example.fx.OutputBean.ForeignExchangeEvent;
    
    static public class ForeignExchangeEvent {
        private String symbol;
        private Double price;
        private String fromRate;
        private String toRate;
        private Long clientTimestamp;
        private Long adapterTimestamp;
     
        public ForeignExchangeEvent() {
    
        }
     
        public ForeignExchangeEvent(String symbol, Double price, String fromRate, String toRate) {
            this.symbol = symbol;
            this.price = price;
            this.fromRate = fromRate;
            this.toRate = toRate;
     
            if (clientTimestamp == null)
                this.clientTimestamp = new Long(0);
     
            if (adapterTimestamp == null)
                this.adapterTimestamp = new Long(0);
        }
     
        public String getSymbol() {
            return symbol;
        }
     
        public Double getPrice() {
            return price;
        }
     
        public String getFromRate() {
            return fromRate;
        }
     
        public String getToRate() {
            return toRate;
        }
     
        public Long getClientTimestamp() {
            return clientTimestamp;
        }
     
        public Long getAdapterTimestamp() {
            return adapterTimestamp;
        }
     
    }
    
  2. Create a Java class to represent your event type builder as Example 1-13 shows.

    Example 1-13 ForeignExchangeBuilderFactory

    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);
            }
            
        }
    }
    

    Oracle CEP uses the event builder factory to create event instances that do not follow the JavaBean specification. See Section 1.5.5, "Using an Event Type Builder Factory" for additional information about using an event type builder factory.

  3. Compile the Java classes that represent your event type and event builder factory.

  4. Register your event type and event builder factory in the Oracle CEP event type repository:

    1. To register declaratively, edit the EPN assembly file using the wlevs:event-type-repository element wlevs:event-type child element as Example 1-10 shows.

      Use the <wlevs:class> tag to point to your JavaBean class, and then use the <wlevs:property name="builderFactory"> tag to specify a custom event builder factory for the event type.

      Example 1-14 EPN Assembly File event-type-repository

      <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>
      
    2. To register programatically, use the EventTypeRepository class as Example 1-11 shows.

      Example 1-15 Programmatically Registering an Event

      EventTypeRepository rep = getEventTypeRepository();
      ForeignExchangeBuilderFactory factory = new ForeignExchangeBuilderFactory();
      rep.registerEventType(
          "ForeignExchangeEvent", 
          com.bea.wlevs.example.fx.OutputBean.ForeignExchangeEvent.getClass(),
          factory.createBuilder()
      );
      

      For more information, see Section 1.5.6, "Accessing the Event Type Repository".

  5. Use the event type:

    • Reference the event types as standard JavaBeans in the Java code of the adapters and business logic POJO in your application.

      public void onEvent(List newEvents)
              throws RejectEventException {
          for (Object event : newEvents) {
                  ForeignExchangeEvent fxEvent = (ForeignExchangeEvent) event;
              System.out.println("Price: " + fxEvent.getPrice());
          }
      }
      
    • Access the event types from Oracle CQL and EPL rules:

      The following Oracle CQL rule shows how you can reference the MarketEvent in a SELECT statement:

      <query id="helloworldRule">
          <![CDATA[ select ForeignExchangeEvent.price from marketEventChannel [Now] ]]>
      </query>
      

1.5.3 How to Create an Oracle CEP Event Type as a java.util.Map

This procedure describes how to create and register an Oracle CEP event type as a java.util.Map. Oracle recommends that you create an Oracle CEP event type as a JavaBean (see Section 1.5.1, "How to Create an Oracle CEP Event Type as a JavaBean").

For more information on valid event type data types, see Section 1.1.2.2.1, "Event Types Specified as Java Bean, Java Class, or java.util.Map".

To create an Oracle CEP event type as a java.util.Map:

  1. Decide on the properties your event type requires.

  2. Register your event type in the Oracle CEP event type repository:

    1. To register declaratively, edit the EPN assembly file using the wlevs:event-type-repository element wlevs:event-type child element as Example 1-16 shows.

      Example 1-16 EPN Assembly File event-type-repository

      <wlevs:event-type-repository>
          <wlevs:event-type type-name="AnotherEvent">
                <wlevs:property>
                   <entry key="name" value="java.lang.String"/>
                   <entry key="age" value="java.lang.Integer"/>
                   <entry key="address" value="java.lang.String"/>
                </wlevs:property>
          </wlevs:event-type>
      </wlevs:event-type-repository>
      

      At runtime, Oracle CEP generates a bean instance of AnotherEvent for you. The AnotherEvent has three properties: name, age, and address.

    2. To register programatically, use the EventTypeRepository class as Example 1-17 shows.

      Example 1-17 Programmatically Registering an Event

      EventTypeRepository rep = getEventTypeRepository();
      java.util.Map map = new Map({name, java.lang.String}, {age, java.lang.Integer}, {address, java.lang.String});
      rep.registerEventType(
          "AnotherEvent", 
          map
      );
      

      For more information, see Section 1.5.6, "Accessing the Event Type Repository".

  3. Use the event type:

    • Reference the event types as standard JavaBeans in the Java code of the adapters and business logic POJO in your application.

      public void onEvent(List newEvents)
              throws RejectEventException {
          for (Object event : newEvents) {
                  java.util.Map anEvent = (java.util.Map) event;
              System.out.println("Age: " + anEvent.getAge());
          }
      }
      
    • Access the event types from Oracle CQL and EPL rules:

      The following Oracle CQL rule shows how you can reference the MarketEvent in a SELECT statement:

      <query id="helloworldRule">
          <![CDATA[ select AnotherEvent.age from eventChannel [Now] ]]>
      </query>
      

1.5.4 How to Create an Oracle CEP Event Type as a Tuple

This procedure describes how to create and register an Oracle CEP event type declaratively in the EPN assembly file as a tuple. Oracle recommends that you create an Oracle CEP event type as a JavaBean (see Section 1.5.1, "How to Create an Oracle CEP Event Type as a JavaBean").

For more information on valid event type data types, see Section 1.1.2.2.2, "Event Types Specified as a Tuple".

To create an Oracle CEP event type as a tuple:

  1. Decide on the properties your event type requires.

  2. Register your event type declaratively in the Oracle CEP event type repository:

    To register declaratively, edit the EPN assembly file using the wlevs:event-type-repository element wlevs:event-type child element as Example 1-18 shows.

    Example 1-18 EPN Assembly File event-type-repository

    <wlevs:event-type-repository>
        <wlevs:event-type type-name="CrossRateEvent">
            <wlevs:properties>
                <wlevs:property name="price" type="double"/>
                <wlevs:property name="fromRate" type="char"/>
                <wlevs:property name="toRate" type="char"/>
            </wlevs:properties>
        </wlevs:event-type>
    </wlevs:event-type-repository>
    

    At runtime, Oracle CEP generates a bean instance of CrossRateEvent for you. The CrossRateEvent has three properties: price, fromRate, and toRate.

    For more information on the valid values of the type attribute, see Section 1.1.2.2.2, "Event Types Specified as a Tuple".

  3. Use the event type:

    • Reference the event types using the EventTypeRepository introspection interface EventType in the Java code of the adapters and business logic POJO in your application:

      @Service
      public void setEventTypeRepository(EventTypeRepository etr) {
          etr_ = etr;
      }
      ...
      // handle events
      public void onInsertEvent(Object event) throws EventRejectedException {
          // get the event type for the current event instance
          EventType eventType = etr_.getEventType(event);
      
          // get the event type name
          String eventTypeName = eventType.getTypeName();
      
          // get the event property names
          String[] propNames = eventType.getPropertyNames();
      
          // test if property is present
          if(eventType.isProperty("fromRate")) {
              // get property value
              Object propValue = eventType.getProperty("fromRate").getValue(event);
          }
          ...
      }
      

      For more information, see Section 1.5.6, "Accessing the Event Type Repository".

    • Access the event types from Oracle CQL and EPL rules:

      The following Oracle CQL rule shows how you can reference the CrossRateEvent in a SELECT statement:

      <query id="FindCrossRatesRule"><![CDATA[
          select ((a.price * b.price) + 0.05) as internalPrice, 
              a.fromRate as crossRate1, 
              b.toRate as crossRate2 
          from FxQuoteStream [range 1] as a, FxQuoteStream [range 1] as b   
          where 
              NOT (a.price IS NULL)
          and
              NOT (b.price IS NULL)
          and
              a.toRate = b.fromRate
      ]]></query>
      

1.5.5 Using an Event Type Builder Factory

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 Oracle CEP Java API Reference 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">
      <bean id="builderFactory"
            class="com.bea.wlevs.example.fx.ForeignExchangeBuilderFactory"/>
    </wlevs:property>
  </wlevs:event-type>
</wlevs:event-type-repository>

1.5.6 Accessing the Event Type Repository

The EventTypeRepository is a singleton OSGi service. Because it is a singleton, you only need to specify its interface name to identify it. You can get a service from OSGi in any of the following ways:

For more information, see Oracle CEP Java API Reference.

1.5.6.1 Using the EPN Assembly File

You can access the EventTypeRepository by specifying an osgi:reference in the EPN assembly file as Example 1-19 shows.

Example 1-19 EPN Assembly File With OSGi Reference to EventTypeRepository

<osgi:reference id="etr" interface="com.bea.wlevs.ede.api.EventTypeRepository" />
<bean id="outputBean" class="com.acme.MyBean" >
    <property name="eventTypeRepository" ref="etr" />
</bean>

Then, in the MyBean class, you can access the EventTypeRepository using the eventTypeRepository property initialized by Spring as Example 1-20 shows.

Example 1-20 Accessing the EventTypeRepository in the MyBean Implementation

package com.acme;

import com.bea.wlevs.ede.api.EventTypeRepository;
import com.bea.wlevs.ede.api.EventType;

public class MyBean {
    private EventTypeRepository eventTypeRepository;

    public void setEventTypeRepository(EventTypeRepository eventTypeRepository) {
        this.eventTypeRepository = eventTypeRepository;
    }

    public void onInsertEvent(Object event) throws EventRejectedException {
        // get the event type for the current event instance
        EventType eventType = eventTypeRepository.getEventType(event);
        ...
    }
}

1.5.6.2 Using the Spring-DM @ServiceReference Annotation

You can access the EventTypeRepository by using the Spring-DM @ServiceReference annotatoin to initialize a property in your Java source as Example 1-21 shows.

Example 1-21 Java Source File Using the @ServiceReference Annotation

import org.springframework.osgi.extensions.annotation.ServiceReference;
import com.bea.wlevs.ede.api.EventTypeRepository;
...
@ServiceReference
setEventTypeRepository(EventTypeRepository etr) {
    ...
}

1.5.6.3 Using the Oracle CEP @Service Annotation

You can access the EventTypeRepository by using the Oracle CEP @Service annotatoin to initialize a property in your Java source as Example 1-21 shows.

Example 1-22 Java Source File Using the @Service Annotation

import com.bea.wlevs.util.Service;
import com.bea.wlevs.ede.api.EventTypeRepository;
...
@Service
setEventTypeRepository(EventTypeRepository etr) {
    ...
} 

For more information, see Section G.5, "com.bea.wlevs.util.Service".

1.5.7 Sharing Event Types Between Application Bundles

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.

1.6 Configuring Oracle CEP Resource Access

By using Oracle CEP and standard Java annotations and deployment XML, you can configure the Oracle CEP Spring container to inject resources (such as data sources or persistence managers, and so on) into your Oracle CEP application components.

The Spring container typically injects resources during component initialization. However, it can also inject and re-inject resources at runtime and supports the use of JNDI lookups at runtime.

Oracle CEP supports the following types of resource access:

See Section 1.6.4, "Understanding Resource Name Resolution" for information on resource name resolution.

See Appendix G, "Oracle CEP Metadata Annotation Reference" for complete details of all Oracle CEP annotations.

In the following sections, consider the example resource that Example 1-23 shows. This is a data source resource named StockDS that you specifiy in the Oracle CEP server config.xml file.

Example 1-23 Sample Resource: Data Source StockDS

<config ...>
    <data-source>
        <name>StockDs</name>
        ...
        <driver-params>
            <url>jdbc:derby:</url>
            ...
        <driver-params>
    </data-source>
...
</config>

1.6.1 Static Resource Injection

Static resource injection refers to the injection of resources during the initialization phase of the component lifecycle. Once injected, resources are fixed, or static, while the component is active or running.

You can configure static resource injection using:

1.6.1.1 Static Resource Names

When you configure static resource injection using static resource names, the resource name you use in the @Resource annotation or Oracle CEP assembly XML file must exactly match the name of the resource as you defined it. The resource name is static in the sense that you cannot change it without recompiling.

To configure static resource injection using static resource names at design time, you use the standard javax.annotation.Resource annotation as Example 1-24 shows.

To override design time configuration at deploy time, you use Oracle CEP assembly file XML as Example 1-25 shows.

In Example 1-24 and Example 1-25, the resource name StockDs exactly matches the name of the data source in the Oracle CEP server config.xml file as Example 1-23 shows.

Example 1-24 Static Resource Injection Using Static Resource Names: Annotations

import javax.annotation.Resource;

public class SimpleBean implements EventBean {
...
    @Resource (name="StockDs")
    public void setDataSource (DataSource dataSource){
        this.dataSource = dataSource;
    }
}

Example 1-25 Static Resource Injection Using Static Resource Names: XML

< wlevs:event-bean id="simpleBean" class="...SimpleBean"/>
    <wlevs:resource property="dataSource" name="StockDs"/>
</wlevs:event-bean>

If the name of the EventBean set method matches the name of the resource, then the @Resource annotation name attribute is not needed as Example 1-26 shows. Similarly, in this case, the wlevs:resource element name attribute is not needed as Example 1-27.

Example 1-26 Static Resource Injection Using Static Resource Names: Annotations

import javax.annotation.Resource;

public class SimpleBean implements EventBean {
...
    @Resource ()
    public void setStockDs (DataSource dataSource){
        this.dataSource = dataSource;
    }
}

Example 1-27 Static Resource Injection Using Static Resource Names: XML

< wlevs:event-bean id="simpleBean" class="...SimpleBean"/>
    <wlevs:resource property="dataSource"/>
</wlevs:event-bean>

1.6.1.2 Dynamic Resource Names

A dynamic resource name is one that is specified as part of the dynamic or external configuration of an application. Using a dynamic resource name, the deployer or administrator can change the resource name without requiring that the application developer modify the application code or the Spring application context.

To add a dynamic resource name to a component, such as an adapter or POJO, you must first specify custom configuration for your component that contains the resource name as Example 1-28 shows.

Example 1-28 Custom Component Configuration

<simple-bean>
    <name>SimpleBean</name>
    <trade-datasource>StockDs</trade-datasource>
</simple-bean>

To configure static resource injection using dynamic resource names at design time, you use the standard javax.annotation.Resource annotation as Example 1-29 shows.

To override design time configuration at deploy time, you use Oracle CEP assembly file XML as Example 1-30 shows.

Example 1-29 Static Resource Injection Using Dynamic Resource Names: Annotations

import javax.annotation.Resource;

public class SimpleBean implements EventBean {...    @Resource (name="trade-datasource")    public void setDataSource (DataSource dataSource){        this.dataSource = dataSource;    }}

Example 1-30 Static Resource Injection Using Dynamic Resource Names: XML

< wlevs:event-bean id="simpleBean" class="...SimpleBean"/>    <wlevs:resource property="dataSource" name="trade-datasource"/></wlevs:event-bean>

1.6.2 Dynamic Resource Injection

Dynamic resource injection refers to the injection of resources dynamically while the component is active in response to a dynamic configuration change using Spring container method injection.

To configure dynamic resource injection at design time, you use the standard javax.annotation.Resource annotation as Example 1-31 shows.

Example 1-31 Dynamic Resource Injection: Annotations

import javax.annotations.Resource;

public class SimpleBean implements EventBean {
...
    @Resource ("trade-datasource")
    public abstract DataSource getDataSource ();
    ...
    }

The component calls the getDataSource() method at run time whenever it needs to retrieve a new instance of the resource that the resource name trade-datasource refers to.

Typically, the component calls the getDataSource() method during the @Prepare or @Activate methods when dynamic configuration changes are handled. For more information see:

Another strategy is to always call the getDataSource() prior to using the data source. That is, the application code does not store a reference to the data source as a field in the component.

1.6.3 Dynamic Resource Lookup Using JNDI

Oracle CEP supports the use of JNDI to look up resources dynamically as Example 1-32.

Example 1-32 Dynamic Resource Lookup Using JNDI

import javax.naming.InitialContext;

public class SimpleBean implements EventBean {...    public abstract void getDataSource () throws Exception {        InitialContext initialContext= new InitialContext ();        return initialContext.lookup ("StockDs”);    }}

In Example 1-32, the JNDI name StockDs must exactly match the name of the data source in the Oracle CEP server config.xml file as Example 1-23 shows.


Note:

You must disable security when starting the Oracle CEP server in order to use JNDI. Oracle does not recommend the use of JNDI for this reason.

For more information, see "Configuring Security for Oracle CEP" in the Oracle CEP Administrator's Guide.


1.6.4 Understanding Resource Name Resolution

Oracle CEP server resolves resource names by examining the naming scopes that Table 1-3 lists.

Table 1-3 Resource Name Resolution

Naming Scope Contents Resolution Behavior

Component

The property names of the component's custom configuration

Mapping

Application

The names of the configuration elements in the application configuration files

Matching

Server

The names of the configuration elements in the server configuration file

Matching

JNDI

The names registered in the server's JNDI registry

Matching


Each naming scope contains a set of unique names. The name resolution behavior is specific to a naming scope. Some naming scopes resolve names by simple matching. Other scopes resolve names by mapping the name used to do the lookup into a new name. Once a name is mapped, lookup proceeds recursively beginning with the current scope.

1.7 Next Steps

After you have programmed all components of your application and created their configuration XML files: