1 Overview of Creating Oracle Event Processing Applications

This chapter introduces the tools, technologies, and processes through which you can build Oracle Event Processing applications, including the programming model, how applications work, and key concepts and technologies.

This chapter includes the following sections:

1.1 Oracle Event Processing Application Programming Model

This section provides an overview of the concepts, technologies, and tools that are part of building Oracle Event Processing applications.

An Oracle Event Processing application receives and processes data streaming from an event source. That data might be coming from one of a wide variety of places, including a monitoring device, a financial services company, or a motor vehicle. Using the data, the application might identify and respond to patterns, look for extraordinary events and alert other applications, or do some other work that requires immediate action based on quickly changing data.

When developing an Oracle Event Processing application, you assemble a network of components that each have a role in processing the data. This event processing network is essentially linear, with events passing through it from one end to the other. Along the way, components execute queries in a language specifically designed for streaming data, execute logic in Java, and create connections with other external components.

Section 1.1.1, "Key Concepts Underlying Oracle Event Processing Applications"

Section 1.1.2, "Component Roles in an Event Processing Network"

Section 1.1.3, "Tools and Supporting Technologies for Developing Applications"

1.1.1 Key Concepts Underlying Oracle Event Processing Applications

Applications you build with Oracle Event Processing are based on concepts and technologies that are a mix of the familiar and (if you're new to event-based applications) unfamiliar. The following list briefly describes the key concepts and technologies that underlie how event processing networks work.

  • Applications leverage the database programming model. Some of the programming model in Oracle Event Processing applications is conceptually an extension of what you find in database programming. Events are similar to database rows in that they are tuples against which you can execute queries (with a language that is an extension of SQL). In other words, if you know relational databases, much of this will seem familiar.

    For a closer look at the similarity between database programming and Oracle Event Processing applications, see Section 1.3, "Overview of Events, Streams and Relations".

  • Stages represent discrete functional roles. The staged structure of an event processing network (EPN) provides a means for you to execute different kinds of logic against events flowing through the network. This includes query logic with Oracle Continuous Query Language (Oracle CQL) as well as logic in Java. It also provides a way to capture multiple processing paths with a network that branches into multiple downstream directions based on discoveries your code makes.

    For a list of roles stages play in an EPN, see Section 1.1.2, "Component Roles in an Event Processing Network". For a closer look at the pieces of an EPN, see Section 1.2, "How an Oracle Event Processing Application Works".

  • Stages transmit events through an EPN by acting as event sinks and event sources. The stages in an EPN are able to receive events (as event sinks) and/or send events (as event sources). This includes stage components that come with Oracle Event Processing as well as components you build, such as your own adapters and beans.

    For more about implementing your own event sinks and sources, see Chapter 16, "Handling Events with Java"

  • Events are handled either as streams or relations. The concept of a stream, unique to streaming event-based applications, captures the fact that events arrive at your application sequentially by timestamp. Contrast this with rows in a database, where the table rows have no inherent relationship to one another aside from schema. However, many queries of events in stream result in a relation, in which events could be related in a way other than their relative sequence in time (similar to database query results).

    For more on streams and relations, see Section 1.3, "Overview of Events, Streams and Relations".

1.1.2 Component Roles in an Event Processing Network

The core of Oracle Event Processing applications you build is an event processing network (EPN). You build an EPN by connecting components (also known as stages) that each have a role in processing events that pass through the network. When developing an Oracle Event Processing application, you identify which kinds of components will be needed. As you add components to the EPN, you configure each as well as their connections with one another. As you use the IDE to build the EPN, you arrange and connect components in a roughly linear shape in which events will enter from the left end, move through the EPN and exit or terminate at the right end.

For a high-level overview of an EPN using an application example, including fuller descriptions of the technologies involved, see Section 1.2, "How an Oracle Event Processing Application Works".

The EPN components you use provide ways to:

  • Exchange event data with external sources. Through adapters and other stages, you can connect external components to the EPN of your application to add ways for data, including event data, to pass into or out of the EPN.

    These external components include those in the following list (you can also build your own).

    • Relational databases. You can access a database table from within Oracle CQL code, querying the database as you would with SQL.

    • Caches. By adding a cache stage to an EPN, you can exchange data with the cache.

    • Java Message Service (JMS). With the JMS adapter, you can exchange messages with a JMS destination without writing the Java code typically needed for it.

    • HTTP publish-subscribe server. The HTTP pub-sub adapter simplifies exchanging messages with an HTTP publish-subscribe server.

  • Model event data so that it can be handled by application code. You implement or define event types that model event data so that application code can work with it. For more information, see Chapter 9, "Defining and Using Event Types".

  • Query and filter events. The Oracle Continuous Query Language (Oracle CQL) is an extension of the SQL language through which you can query events as you would data in a database. Oracle CQL includes features specifically intended for querying streaming data. You add Oracle CQL code to an event processing network by adding a processor. For more information, see Chapter 17, "Querying an Event Stream with Oracle CQL".

  • Execute Java logic to handle events. To an EPN you can add Java classes that receive and send events just as other EPN stages do. Logic in these classes can retrieve values from events, create new events, and more. For more information, see Chapter 16, "Handling Events with Java".

For IDE reference information on creating event processing networks, see Section 7.4, "Using the EPN Editor".

1.1.3 Tools and Supporting Technologies for Developing Applications

Included with Oracle Event Processing is a set of tools and supporting technologies you can use to develop applications. These include tools for building and debugging applications, testing applications in a lightweight way, accessing underlying functionality with Java, and designing Oracle CQL queries.

The following lists some of these tools and technologies:

1.2 How an Oracle Event Processing Application Works

As with many enterprise-scale applications, an Oracle Event Processing application is full of "connected-to" relationships. For example, an adapter might be connected to a processor, which might be connected to an event bean, which might be connected to a external data source, and so on. The connections aren't necessarily in that order, but you get the idea.

Events arrive from an outside source, then move through the application's event processing network (EPN). Along the way they might be filtered, queried, and otherwise processed as needed by EPN components that you put in place.

For example, take a look at a simple TradeReport application you can build using the topics described in Chapter 8, "Walkthrough: Assembling a Simple Application".

Description of tradereport_finishedepn.png follows
Description of the illustration tradereport_finishedepn.png

The following sections describe the role of each component in the application.

Event Information is Received in Its Raw Form

In the TradeReport example, the event data source is simply a text file with rows of comma-separated values. To try things out, you can use such a file in combination with the load generator included with Oracle Event Processing.

An event data source is outside the application, yet connected though an adapter that knows how to retrieve its data. The event source could be something physically near (such as another application in the organization) or it could be quite far away (perhaps a temperature sensor in a server room in another city).

For information on event data and creating event types, see Chapter 9, "Defining and Using Event Types".

For step-by-step content on capturing event data in the TradeReport application, see Section 8.3, "Create an Event Type to Carry Event Data".

Adapters Connect External Components to the EPN

In the TradeReport example, the event data source is connected to the event processing network through an adapter that knows how to receive event data sent from the CSV file. The adapter converts the incoming data into instances of an event type that the EPN can work with.

You can use an adapter to either receive incoming or send outgoing data. Adapters provided with Oracle Event Processing give you access to CSV files and also to systems such as the Java Message Service or an HTTP Publish-Subscribe server. You can also develop your own adapters for integrating systems that aren't supported by default.

When configuring an input adapter, you specify how the event data should be bound to an instance of an event type that you've defined in the EPN.

For more information, see the following:

Chapter 11, "Integrating the Java Message Service"

Chapter 12, "Integrating an HTTP Publish-Subscribe Server"

Chapter 13, "Integrating a Cache"

Chapter 15, "Integrating an External Component Using a Custom Adapter"

Chapter 21, "Testing Applications With the Load Generator and csvgen Adapter"

For step-by-step content on adding a csvgen adapter to receive CSV content in the TradeReport application, see Section 8.4, "Add an Input Adapter to Receive Event Data".

Event Types Provide Useful Structure for Event Data

In the TradeReport application, the input adapter converts the incoming event data from a set of comma-separated values into property values of an event type instance that's defined as a Java class.

An event type provides a predictable structure for event data that other code in your application can use. Examples of that code include an Oracle CQL query that filters the events to discover those to act on, Java code in a bean that creates new kinds of events based on what your application received, and code to retrieve values and merge them with values from another data source.

Event types define properties that provide access to event data. Adapters receive incoming events from different event sources, such as the Java Messaging System (JMS) or financial market data feeds. You must define an Oracle Event Processing event type for these events before code is able to work with them.

You specify event types when you're configuring the EPN. With the structure of the raw event data in hand, you can define an event type that best suits your application's needs. The general best practice for defining an event type is to write a JavaBean class whose properties map to the event data that your application will use. You can also define event types as simple tuples and Java Map instances.

For more information, see Chapter 9, "Defining and Using Event Types"

For step-by-step content on defining an event type for the TradeReport application, see Section 8.3, "Create an Event Type to Carry Event Data".

Channels Transfer Events from Stage to Stage

In the TradeReport application, the input adapter transmits events to an Oracle CQL processor by sending the events through a channel.

Channels connect stages in an event processing network. Between most components you will add a channel that listens for events coming from one stage and sends those events to another stage.

For more information on adding channels, see Chapter 10, "Connecting EPN Stages Using Channels".

For step-by-step content on adding a channel to the TradeReport application, see Section 8.5, "Add a Channel to Convey Events".

Processors Contain Query Code to Examine Events

The TradeReport application includes a processor that contains a simple Oracle Continuous Query Language (Oracle CQL) query to filter the stream of received events down to only those that meet certain criteria. As events flow through the processor, the Oracle CQL code executes, acting as a filter to determine which events get passed to the next stage.

The logic of the application relies on the specific qualities of events flowing through it. In this application, a processor stage is a place to discover those qualities by using Oracle CQL code to look for occurrences of particular data or trends.

Because it is a great deal like the SQL language used to query more static, relational data sources, the Oracle CQL language is a powerful tool to discover information about data represented by events. For example, Oracle CQL contains a wide assortment of functions ranging from simple count() and sum() functions to sophisticated statistics functions.

Oracle CQL is like SQL, but also includes functionality intended specifically for writing queries that account for a characteristic typically not as important when querying static databases: the passage of time. Through these time-related features, you can, for example, write code that defines specific windows, such as from the present to the preceding 5 milliseconds. Your queries can execute to isolate this window as events pass through.

You can also use the code in Oracle CQL processor to collect and combine data from a variety of sources, including a cache and a relational database. Using a cache, for example, gives you a place to put frequently-retrieved data where performance will be faster.

The Oracle CQL engine is also extensible with cartridges that make additional functionality available to your Oracle CQL code.

For more information on Oracle CQL, see Chapter 17, "Querying an Event Stream with Oracle CQL".

For step-by-step information on defining an Oracle CQL query in the TradeReport application, see Section 8.8, "Add an Oracle CQL Processor to Filter Events".

Beans Provide a Place for Java Logic

Once the TradeReport application has processed events with Oracle CQL, it passes the resulting events to an event bean that receives the events and prints to the console data contained in each event type instance.

In an EPN, a bean provides a place for you to execute Java code over events that are passing through. A bean can receive and sent events. For example, a bean might receive events of one type, then retrieve their data to perform some calculation or lookup using the data. The bean could then create new events from the newly generated data before passing the new events along to another stage.

You can write and configure beans as either Spring beans or event beans. Spring beans are managed by the Spring framework, and are a good choice if you want to integrate your bean to an existing Spring deployment. Event beans, on the other hand, use Oracle Event Processing conventions for configuring beans so that they're managed by the Oracle Event Processing server. With an event bean, for example, you get the support of Oracle Event Processing server features such as monitoring and event recording and playback (useful for debugging an application).

For more information on writing and using Java classes that handle events, see Chapter 16, "Handling Events with Java".

For step-by-step content on adding an event bean to the TradeReport application, see Section 8.6, "Create a Listener to Receive and Report Events".

Configuration Files Define an EPN and Its Components

The EPN presence of and connections between TradeReport application stages is configured in an EPN assembly XML file. There is also a component configuration file which, though it isn't used in this case, could define runtime configuration for the components.

The EPN assembly file is what you are writing as you assemble an event processing network using the IDE (the EPN editor is essentially a user interface for designing EPN assembly files). What's in the EPN assembly file declares the stages and determines how they interact, including which direction events flow when moving from one stage to another. The EPN assembly file also sets default values for component settings, or values that you won't need to change at runtime.

With a component configuration file, on the other hand, you can specify configuration data that an administrator can later change while the application is running. The component configuration file is where Oracle CQL code is typically written (as configuration for a processor component).

For more information on configuration files, see Section 1.4, "Overview of Application Configuration".

Design and Configuration Conventions Scalability and High Availability

While the simple TradeReport application doesn't demonstrate them, there are design patterns that you can use to ensure that your application remains available and scales well.

When ensuring that your application remains highly available, you integrate application design patterns, server resources, and configuration conventions so that your deployed application continues to fulfill its role even in the event of software or hardware failures.

A scalable Oracle Event Processing application incorporates design patterns with implementation and configuration conventions to ensure that the application functions well as the event load increases.

For more information, see the following:

Chapter 24, "Developing Applications for High Availability"

Chapter 25, "Developing Scalable Applications"

1.3 Overview of Events, Streams and Relations

An Oracle Event Processing application handles events that arrive in a stream as raw event data, are converted to event type instances inside the application, and move from one application stage to another in an event processing network. Along the way, the events might be filtered with Oracle CQL queries, handled by Java code, stored in a cache, forwarded to other applications, and so on.

But what is an event? With the emphasis on the streaming aspect of event data, it can be easy to forget how much events are like rows in a database. In application terms, an event is a tuple, or set of values. Like a relational database row, an event has a schema in which each value has specific constraints, such as a particular data type. An event's schema defines its set of properties (where values will go) and their types.

Where events are unlike database rows is in the importance of time. In a stream of events, when an event arrives, including which event arrives before or after another event, can make all the difference. As a result, your application needs to be able to account for time and sequence.

For example, in an application that processes stock trades, event tuples made up of stock symbol, price, last price, percentage change, and volume would likely arrive one after the other in the order in which each trade was executed. Your application's logic might look for trades of one stock that occurred immediately after trades of another.

In other words, in an event processing application the sequence in which events occur in a stream is as important as the data types and values of each event property. As a result, conventions of the Oracle Event Processing programming model reflect the importance of time and sequence. Your code should be able to discover which events are related to one another based on certain criteria (such as a shared stock symbol). But it also needs to be able to discover sequence patterns (such as trades within fifteen seconds of one another). And it should be able to discover these things with very low latency as the events arrive at your application.

To account for both the sequential and relational aspects of event data, Oracle Event Processing uses the concepts of streams and relations.

  • A stream is a potentially infinite sequence of events. Like rows in a database, the events are tuples, yet each has its own timestamp. In a stream, the events must be ordered by time, one after the other, so that timestamps do not decrease from one event to the next (although there might be events in a stream that have the same timestamp).

  • In a relation, sequence might be unimportant (as with the results of a database query). Instead, events in a relation are typically related because they met certain criteria. For example, events in a relation might be the result of a query executed against a stream of stock trades, where the query was looking for trade volumes above a particular level.

Consider that stream of stock trade events. The events are arriving in sequence, each with its own timestamp (perhaps the time when the trade occurred). To isolate the share price for trades that occurred within 5 seconds of one another, you query the stream (received from StockTradeChannel) with the following Oracle CQL code:

select price from StockTradeChannel [range 5 seconds] 

Because it uses a window -- [range 5 seconds] -- to isolate the events, this query's output is a relation. Though the events returned from the query have timestamps, they are unordered in the relation. Because the incoming events are in a stream, the query will execute continuously against every 5 seconds' worth of events as they pass into the query processor. As new events come along, those meeting the query terms are inserted into the relation, while those leaving (pushed out, actually) are deleted from the relation.

Why does this matter? A stream's integrity as a stream is important. Technically, a stream is a continuously moving -- well, streaming -- and ordered set of tuples. In a stream, every event can be said to be "inserted," having been put into the stream by its source, one after the other. When you get a subset of the stream with a query, you no longer have something that is ordered. And once you have the subset in hand, you might want to further isolate events by executing Oracle CQL code that queries the relations that result from queries of streams.

For this reason, examples in the Oracle CQL reference show the output of a query as events that are, as a result of the query and at that particular place in time, either inserted or deleted.

Before passing a relation along to the next stage in the EPN, you can convert it back into a stream by using an operator such as IStream.

For more information, see:

1.4 Overview of Application Configuration

You configure Oracle Event Processing applications through XML files that are based on standard schemas. When you install Oracle Event Processing, XSD files for these schemas are included in the directory MIDDLEWARE_HOME\ocep_11.1\xsd.

As you assemble an event processing network (EPN), even if you are using the IDE, you are creating an EPN assembly XML file. An entry for a stage in this file adds that stage to the EPN and defines its connections with other stages. For more on this file, see Section 1.4.1, "Overview of EPN Assembly Files".

Each component in your event processing network (adapter, processor, channel, or event bean) can have associated configuration XML. By providing this configuration, you provide a way for the component's configuration to be edited at runtime. (Only processors are required to have a configuration file.) Configuration XML for components can be grouped into a single component configuration file or divided among multiple files, depending on the needs of your development process. For more on component configuration files, see Section 1.4.2, "Overview of Component Configuration Files".

Other aspects of an Oracle Event Processing application might require their own configuration files. These include caching provided by Oracle Coherence. For information about other configuration, see documentation sections related to those technologies.

1.4.1 Overview of EPN Assembly Files

When you are assembling an event processing network (EPN) using the IDE, you are defining the EPN in an assembly file. The EPN assembly file is an XML file whose shape is based on the Spring framework XML configuration file. The EPN assembly file schema extends the Spring configuration schema.

The spring-wlevs-v11_1_1_6.xsd schema file describes the structure of EPN assembly files. When you install Oracle Event Processing, XSD files such as this one are included in the directory MIDDLEWARE_HOME\ocep_11.1\xsd..

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 Event Processing 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_1_1_6.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 some Oracle Event Processing features, you specify some configuration in the EPN assembly file and some in the component configuration file.

For more information, see:

1.4.1.1 Nesting Stages in an EPN Assembly File

When you define a child stage within a parent stage in an EPN, 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:channel id="helloworldInputChannel" event-type="HelloWorldEvent" >
            <wlevs:listener>
                <wlevs:processor id="helloworldProcessor">
                    <wlevs:listener>
                        <wlevs:channel id="helloworldOutputChannel" 
                            event-type="HelloWorldEvent">
                            <wlevs:listener>
                                <bean 
                                    class="com.bea.wlevs.example.helloworld.HelloWorldBean"/>
                            </wlevs:listener>
                        </wlevs:channel>
                    </wlevs:listener>
                </wlevs:processor>
            </wlevs:listener>
        </wlevs:channel>
    </wlevs:listener>
</wlevs:adapter>

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

1.4.1.2 Referencing Foreign Stages in an EPN Assembly File

You can refer to a stage that is in another Oracle Event Processing application. A stage from another application is considered a foreign stage. You do this by id attribute when you define both the source and target stage in the same application.

Note:

You can't connect a processor stage to a channel that is a foreign stage.

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"/> 

The following stages cannot be foreign stages:

  • Cache

When creating Oracle Event Processing applications with foreign stages, you must consider foreign stage dependencies when assembling, deploying, and redeploying your application. For more information, see Section 23.2.3, "Assembling Applications With Foreign Stages".

1.4.2 Overview of 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 Event Processing 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. When you install Oracle Event Processing, XSD files such as this one are included in the directory MIDDLEWARE_HOME\ocep_11.1\xsd..

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 Event Processing 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.4.2.1 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.

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

Example 1-5 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 Fusion Middleware Java API Reference for Oracle Event Processing.

For more information on accessing property files, see Section 5.7.3, "How to Add a Property File to an Oracle Event Processing Project".

1.4.3 Configuring Oracle Event Processing Resource Access

Because Oracle Event Processing applications are low latency high-performance event-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 Event Processing services, such as configuration management, to those provided by another Oracle product such as Oracle Kodo, to those provided by a third party.

By using Oracle Event Processing and standard Java annotations and deployment XML, you can configure the Oracle Event Processing Spring container to inject resources (such as data sources or persistence managers, and so on) into your Oracle Event Processing 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 Event Processing supports the following types of resource access:

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

See Appendix I, "Oracle Event Processing Metadata Annotation Reference" for complete details of all Oracle Event Processing annotations.

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

Example 1-6 Sample Resource: Data Source StockDS

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

1.4.3.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.4.3.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 Event Processing 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-7 shows.

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

In Example 1-7 and Example 1-8, the resource name StockDs exactly matches the name of the data source in the Oracle Event Processing server config.xml file as Example 1-6 shows.

Example 1-7 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-8 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-9 shows. Similarly, in this case, the wlevs:resource element name attribute is not needed as Example 1-10.

Example 1-9 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-10 Static Resource Injection Using Static Resource Names: XML

< wlevs:event-bean id="simpleBean" class="...SimpleBean"/>
    <wlevs:resource property="dataSource"/>
</wlevs:event-bean>
1.4.3.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-11 shows.

Example 1-11 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-12 shows.

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

Example 1-12 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-13 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.4.3.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-14 shows.

Example 1-14 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 runtime 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.4.3.3 Dynamic Resource Lookup Using JNDI

Oracle Event Processing supports the use of JNDI to look up resources dynamically as Example 1-15.

Example 1-15 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-15, the JNDI name StockDs must exactly match the name of the data source in the Oracle Event Processing server config.xml file as Example 1-6 shows.

Note:

You must disable security when starting the Oracle Event Processing 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 Event Processing" in the Oracle Fusion Middleware Administrator's Guide for Oracle Event Processing.

1.4.3.4 Understanding Resource Name Resolution

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

Table 1-1 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.5 Oracle Event Processing APIs

Oracle Event Processing 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.

  • AdapterFactory—Adapter factories must implement this interface.

    For more information, see Section 15.6, "Creating a Custom Adapter Factory"

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

    For more information about the life cycle, see Section 1.7, "Oracle Event Processing Application Lifecycle".

    • InitializingBean—Use if you require custom initialization after Oracle Event Processing 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.

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

    • ResumableBean—Use if you want to perform some task, such as acquire or configure resources, before the component resumes work.

    • DisposableBean—Use if you want to release resources when the application is undeployed. Implement the destroy method in your component code.

    See also Appendix I, "Oracle Event Processing Metadata Annotation Reference" for additional lifecycle annotations.

  • Event type instantiation interfaces—Use these interfaces for greater control over how event types are instantiated for use in an EPN.

    For more information about event types, see Chapter 1, "Overview of Creating Oracle Event Processing Applications".

  • Event source and sink interfaces—Use these to enable a class to receive and send events as part of the event processing network.

    For more information on event sources and sinks, see Section 16.2, "Handling Events with Sources and Sinks" and

    • StreamSinkand BatchStreamSink—Components that want to receive events as an Oracle Event Processing stream must implement this interface. An Oracle Event Processing 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.

      For more implementation information, see Section 16.2.1, "Implementing an Event Sink".

    • StreamSource, StreamSender and BatchStreamSender—Components that send events modeling an Oracle Event Processing stream, such as adapters, must implement StreamSource. The interface has a setEventSender method for setting the StreamSender or BatchStreamSender, which actually send the event to the next component in the network.

      For more implementation information, see Section 16.2.2, "Implementing an Event Source".

    • RelationSink and BatchRelationSink—Components that want to receive events modeling an Oracle Event Processing relation must implement one of these interfaces. An Oracle Event Processing 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.

      For more implementation information, see Section 16.2.1, "Implementing an Event Sink".

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

      For more implementation information, see Section 16.2.2, "Implementing an Event Source".

For more information, see:

1.6 Packaging an Application

After an application is assembled, it must be packaged so that it can be deployed into Oracle Event Processing. 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 Event Processing so it can immediately start receiving incoming data.

For more information, see Chapter 23, "Assembling and Deploying Oracle Event Processing Applications".

1.7 Oracle Event Processing Application Lifecycle

Figure 1-1 shows a state diagram for the Oracle Event Processing 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 Event Processing; they are not OSGi bundle states.

Figure 1-1 Oracle Event Processing Application Lifecycle State Diagram

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

Note:

For information on Oracle Event Processing server lifecycle, see "Oracle Event Processing Server Lifecycle" in the Oracle Fusion Middleware Administrator's Guide for Oracle Event Processing.

This section describes the lifecycle of an application deployed to the Oracle Event Processing server and the sequence of com.bea.wlevs.ede.api API callbacks.

This information explains how Oracle Event Processing manages an application's lifecycle so that you can better use the lifecycle APIs in your application.

For a description of these lifecycle APIs (such as RunnableBean and SuspendableBean), see:

The lifecycle description is broken down into actions that a user performs, including those described in the following sections.

Installing an application or starting the server with application already deployed

Oracle Event Processing performs the following actions:

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

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

    • 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 the InitializingBean.afterPropertiesSet method.

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

      For more information, see Section 1.4.3, "Configuring Oracle Event Processing Resource Access".

  3. Application state is now INITIALIZING.

  4. Oracle Event Processing registers the MBeans.

  5. Oracle Event Processing calls the ActivatableBean.afterConfigurationActive method on all ActivatableBeans.

  6. Oracle Event Processing calls the ResumableBean.beforeResume method on all ResumableBeans.

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

  8. Application state is now RUNNING.

Suspending the application

Oracle Event Processing performs the following actions:

  1. Oracle Event Processing calls the SuspendableBean.suspend method on all SuspendableBeans.

  2. Application state is now SUSPENDED.

Resuming the application

Oracle Event Processing performs the following actions:

  1. Oracle Event Processing calls the ResumableBean.beforeResume method on all ResumableBeans

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

  3. Application state is now RUNNING.

Uninstalling application

Oracle Event Processing performs the following actions:

  1. Oracle Event Processing calls the SuspendableBean.suspend method on all SuspendableBeans.

  2. Oracle Event Processing unregisters MBeans.

  3. Oracle Event Processing calls the DisposableBean.dispose method on all DisposableBeans.

  4. Oracle Event Processing uninstalls application bundle from OSGI.

Updating the application

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

See those user actions in this list.

Calling methods of stream and relation sources and sinks

You may not call a method on a stream or relation source or sink from a lifecycle callback because components may not be ready to receive events until after these phases of the application lifecycle complete.

For example, you may not call StreamSender method sendInsertEvent from a lifecycle callback such as such as afterConfigurationActive or beforeResume.

You can call a method on a stream or relation source or sink from the run method of beans that implement RunnableBean.

For more information, see the description of installing an application. Also see Section 16.2, "Handling Events with Sources and Sinks".