25 Developing Scalable Applications

This chapter introduces components and design patterns that you can use to allow your Oracle Event Processing applications to scale with an increasing event load, along with how to configure scalability for your application, including information on setting up event partitioning.

This chapter includes the following sections:

25.1 Understanding Scalability

This section introduces components and design patterns that you can use to allow your Oracle Event Processing applications to scale with an increasing event load.

This section includes the following sections:

25.1.1 Scalability Options

Oracle Event Processing provides options that you can use to allow your Oracle Event Processing application to scale with an increasing event load.

In general, you can design your application to partition an input event stream and process events in parallel at the point of event ingress, within the Event Processing Network (EPN), or both.

You should plan to use scalability and parallel processing as early in the event processing sequence as possible. For example, parallel process high-volume, low-value events to extract the typically low-volume, high-value events your application depends on.

Oracle Event Processing provides a variety of scalability components you can use as Section 25.1.2, "Scalability Components" describes.

25.1.1.1 Scalability and High Availability

Because scalability often involves deploying an application to multiple servers, it is advantageous to also consider high availability options when designing your Oracle Event Processing application for scalability.

Input stream partitioning and parallel processing impose important restrictions on application design, such as preserving event order and carefully managing the use of multi-threading.

For more information on high availability options, see:

25.1.2 Scalability Components

Oracle Event Processing provides the following components that you can use to improve the scalability of your Oracle Event Processing applications:

25.1.2.1 EventPartitioner

A com.bea.wlevs.channel.EventPartitioner provides a mechanism for partitioning events on a channel across its output event sinks as Figure 25-1 shows.

Figure 25-1 Event Partitioner EPN

Description of Figure 25-1 follows
Description of "Figure 25-1 Event Partitioner EPN"

This section describes:

For more information, see Section 25.2.1, "Configuring Scalability With a Channel EventPartitioner".

25.1.2.1.1 EventPartitioner Implementation

Oracle Event Processing provides a default event property-based EventPartitioner that you can configure a channel to use.

When you configure a channel to use the default EventPartitioner, you specify the name of an event property by which the channel partitions events. The default EventPartitioner calculates a hash key using the event property value's Object.hashCode() as input to an internal hash function. The hashkey % number-of-listeners is used to calculate which listener will receive the event. This algorithm is based on the same algorithm used by HashMap to calculate in which bucket to place a new item. In practice, this means events with the same event property value are sent to the same listener.

Note:

The default event property-based EventPartitioner does not dispatch in Round Robin fashion.

Optionally, you can create your own event partitioner instance and configure a channel to use it instead to customize how events are dispatched to the channel's listeners.

For more information, see:

25.1.2.1.2 EventPartitioner Initialization

By default, the Oracle Event Processing server initializes each event partitioner on deployment and will re-initialize event partitioners on re-deployment by invoking the EventPartitioner method activateConfiguration is before ActivatableBean.afterConfigurationActive and before your EventPartitioner class's partition method is invoked.

25.1.2.1.3 EventPartitioner Threading

Table 25-1 lists the threading options you can use with an event partitioner channel.

Table 25-1 Event Partitioner Channel Threading Options

Threads Allocated In Description When to Use

Channel

  • Channel max-threads set to the number of listeners.

Usually acceptable if conversion of the external message format into the internal event format is inexpensive.

Lets the multithreading be controlled at the channel granularity. Some channels may require a higher number of threads than others due to differences in volume.

Adapter

  • Channel max-threads set to 0.

  • Implement a multi-threaded adapter with at least one thread per partition listener.

Usually preferable if conversion of the external message format into the internal event format is expensive.

This approach is best when the adapter is multithreaded and the inbound event rate is high enough that the adapter becomes a bottleneck unless multiple threads can be used to scale the inbound processing.


Note:

In either approach, event order cannot be guaranteed. This is true whenever multiple threads are used.

25.1.2.1.4 EventPartitioner Restrictions

When configuring a channel to use an event partitioner, consider the following restrictions:

25.1.2.2 ActiveActiveGroupBean

Using the com.oracle.cep.cluster.hagroups.ActiveActiveGroupBean, you can partition an incoming JMS stream in Oracle Event Processing applications by utilizing the notification groups that the ActiveActiveGroupBean creates.

You add an ActiveActiveGroupBean to your EPN assembly file as Example 25-1 shows.

Example 25-1 ActiveActiveGroupBean bean Element

<bean id="clusterAdapter" class="com.oracle.cep.cluster.hagroups.ActiveActiveGroupBean">
</bean>

By default, the ActiveActiveGroupBean creates notification groups named:

ActiveActiveGroupBean_X

Where X is a string.

At runtime, the ActiveActiveGroupBean scans the existing groups defined on the Oracle Event Processing server and applies a default pattern match of:

ActiveActiveGroupBean_\\w+

When it finds a match, it creates a notification group of that name.

Optionally, you can define your own cluster group pattern match as Section 25.2.2.3, "How to Configure the ActiveActiveGroupBean Group Pattern Match" describes.

This section describes:

For more information, see:

25.1.2.2.1 Scalability in an Oracle Event Processing Application Using the ActiveActiveGroupBean Without High Availability

You can use the ActiveActiveGroupBean to partition an incoming JMS event stream by selector in an Oracle Event Processing application that is not configured for high availability.

Consider the multi-server domain that Figure 25-2 shows.

Figure 25-2 Oracle Event Processing ActiveActiveGroupBean Without High Availability

Description of Figure 25-2 follows
Description of "Figure 25-2 Oracle Event Processing ActiveActiveGroupBean Without High Availability"

In this scalability scenario, you define a cluster group in the Oracle Event Processing server config.xml on each server (ActiveActiveGroupBean_group1 on Host 1, ActiveActiveGroupBean_group2 on Host 2, and so on) and add an instance of the ActiveActiveGroupBean to your Oracle Event Processing application to define notification groups based on these cluster groups.

Each notification group is bound to a different JMS selector. The component configuration file in your Oracle Event Processing application contains the same jms-adapter configuration as Example 25-2 shows.

Example 25-2 Common jms-adapter Selector Definitions

<jms-adapter>
    <message-selector>${CONDITION}</message-selector>
    <bindings>
        <group-binding group-id="ActiveActiveGroupBean_group1">
            <param id="CONDITION">acctid > 400</param>
        </group-binding>
        <group-binding group-id="ActiveActiveGroupBean_group2">
            <param id="CONDITION">acctid BETWEEN 301 AND 400</param>
        </group-binding>
        <group-binding group-id="ActiveActiveGroupBean_group3">
            <param id="CONDITION">acctid BETWEEN 201 AND 300</param>
        </group-binding>
        <group-binding group-id="ActiveActiveGroupBean_group4">
            <param id="CONDITION">acctid <= 200</param>
        </group-binding>
     </bindings>
</jms-adapter>

At runtime, the ActiveActiveGroupBean instance in each Oracle Event Processing application instance on each Oracle Event Processing server finds its ActiveActiveGroupBean_ cluster group and creates a notification group based on it. The Oracle Event Processing application then configures itself with the message-selector that corresponds to the group-id that matches that notification group. This partitions the JMS topic so that each instance of App1 processes a subset of the total number of messages in parallel.

Note:

Within each instance of App1, you could further increase parallel processing by configuring an event partitioner channel as Section 25.1.2.1, "EventPartitioner" describes.

For more information, see Section 25.2.2.1, "How to Configure Scalability in a JMS Application Without Oracle Event Processing High Availability".

25.1.2.2.2 Scalability in an Oracle Event Processing Application Using the ActiveActiveGroupBean With High Availability

In addition to partitioning an incoming JMS event stream by selector, you can also use the ActiveActiveGroupBean to configure two or more Oracle Event Processing servers to function as a single, high availability unit.

Consider the multi-server domain with an Oracle Event Processing high availability application deployed to it that Figure 25-3 shows.

Figure 25-3 Oracle Event Processing ActiveActiveGroupBean With High Availability

Description of Figure 25-3 follows
Description of "Figure 25-3 Oracle Event Processing ActiveActiveGroupBean With High Availability"

In this scenario, you create the same ActiveActiveGroupBean_ cluster group on Host 1 and Host 2 (ActiveActiveGroupBean_group1) and the same ActiveActiveGroupBean_ cluster group on Host 3 and Host 4 (ActiveActiveGroupBean_group2).

At runtime, the ActiveActiveGroupBean instance in each Oracle Event Processing application instance on each Oracle Event Processing server finds its ActiveActiveGroupBean_ cluster group and creates a notification group based on it. Both Host 1 and Host 2 belong to one notification group (ActiveActiveGroupBean_group1) and both Host 3 and Host 4 belong to another notification group (ActiveActiveGroupBean_group2).

Each Oracle Event Processing application then configures itself with the message-selector that corresponds to the group-id that matches that notification group. This partitions the JMS topic so that each instance of App1 processes a subset of the total number of messages in parallel.

When more than one Oracle Event Processing server belongs to the same notification group, the ActiveActiveGroupBean ensures that only the primary server in each notification group outputs events. Within a given notification group, should the primary server go down, then an Oracle Event Processing high availability fail over occurs and one of the secondary servers in that notification group is declared the new primary and resumes outputting events according to the Oracle Event Processing high availability quality of service you configure.

Note:

Within each instance of App1, you could further increase parallel processing by configuring an event partitioner channel as Section 25.1.2.1, "EventPartitioner" describes.

For more information, see Section 25.2.2.2, "How to Configure Scalability in a JMS Application With Oracle Event Processing High Availability".

25.2 Configuring Scalability

This section describes how to configure scalability for yourOracle Event Processing application, including information on setting up event partitioning.

This section includes the following sections:

25.2.1 Configuring Scalability With a Channel EventPartitioner

This section describes how to configure a channel with an Oracle Event Processing event partitioner as Figure 25-4 shows, including:

Figure 25-4 EventPartitioner EPN

Description of Figure 25-4 follows
Description of "Figure 25-4 EventPartitioner EPN"

In this example, assume that the inbound adapter is sending events of type PriceEvent, defined as Example 25-3 shows:

Example 25-3 Definition of Event Type PriceEvent

<wlevs:event-type-repository>
    <wlevs:event-type type-name="PriceEvent">
        <wlevs:properties>
            <wlevs:property name="symbol" type="char" />
            <wlevs:property name="price" type="long" />
        </wlevs:properties>
    </wlevs:event-type>
</wlevs:event-type-repository>

For more information, see Section 25.1.2.1, "EventPartitioner".

25.2.1.1 How to Configure Scalability With the Default Channel EventPartitioner

You can configure a channel to use the default event property-based event partitioner. Each time an incoming event arrives, the channel selects a listener and dispatches the event to that listener instead of broadcasting each event to every listener.

Optionally, you can implement your own EventPartitioner class to customize how the channel dispatches events to its listeners as Section 25.2.1.2, "How to Configure Scalability With a Custom Channel EventPartitioner" describes.

To configure scalability with the default channel EventPartitioner:

  1. Add a channel to your EPN.

    In Figure 25-4, the channel is EventPartitionerChannel.

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

  2. Connect the channel to an upstream adapter.

    In Figure 25-4, the upstream adapter is inbound.

    For more information, see Section 7.4.2, "Connecting Nodes".

  3. Connect the channel to two or more listeners.

    In Figure 25-4, the channel is connected to Oracle CQL processors processor1, processor2, and processor3.

    For more information, see Section 7.4.2, "Connecting Nodes"

  4. Edit the EPN assembly file to add a partitionByEventProperty instance property to the channel element.

    The value of this instance-property is the name of the event property by which the channel partitions events.

    In this example, the channel partitions events by event property symbol.

    
    ...
        <wlevs:channel id="EventPartitionerChannel" event-type="PriceEvent">
            <wlevs:instance-property name="partitionByEventProperty" value="symbol" />
            <wlevs:listener ref="processor1" />
            <wlevs:listener ref="processor2" />
            <wlevs:listener ref="processor3" />
            <wlevs:source ref="inbound" />
        </wlevs:channel>
    ...
    

    For more information, see Section 25.1.2.1.1, "EventPartitioner Implementation".

  5. Decide how you want Oracle Event Processing to allocate threads as Section 25.1.2.1.3, "EventPartitioner Threading" describes:

    1. If you want the channel to allocate threads:

      • Edit the EPN assembly file to configure the channel to set max-threads to the number of listeners.

        
        ...
            <wlevs:channel id="EventPartitionerChannel" event-type="PriceEvent"        max-threads="3" >
                <wlevs:instance-property name="eventPartitioner" value="true" />
                <wlevs:listener ref="processor1" />
                <wlevs:listener ref="processor2" />
                <wlevs:listener ref="processor3" />
                <wlevs:source ref="inbound" />
            </wlevs:channel>
        ...
        
    2. If you want the upstream adapter to allocate threads:

      • Edit the EPN assembly file to configure the channel to set max-threads to 0.

        
        ...
            <wlevs:channel id="EventPartitionerChannel" event-type="PriceEvent"         max-threads="0" >
                <wlevs:instance-property name="eventPartitioner" value="true" />
                <wlevs:listener ref="processor1" />
                <wlevs:listener ref="processor2" />
                <wlevs:listener ref="processor3" />
                <wlevs:source ref="inbound" />
            </wlevs:channel>
        ...
        
      • Edit the Oracle Event Processing server config.xml file to add a work-manager element.

        If this work manager is shared by more than one component (such as other adapters and Jetty), then set the min-threads-constraint and max-threads-constraint elements each to a value greater than the number of listeners.

        If this work manager is not shared by more than one component (that is, it is dedicated to the upstream adapter in this configuration), then set the min-threads-constraint and max-threads-constraint elements equal to the number of listeners.

        ...
        <work-manager>
            <name>adapterWorkManager</name>
            <min-threads-constraint>3</min-threads-constraint>
            <max-threads-constraint>3</max-threads-constraint>
        </work-manager>
        ...
        

        For more information, see Section F.45, "work-manager".

      • Edit the component configuration file to configure the upstream adapter with this work-manager.

        
        ...
        <adapter>
            <name>inbound</name>
            <work-manager-name>adapterWorkManager</work-manager-name>
            ...
        </adapter>
        ...
        
  6. Assemble and deploy your application.

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

    At runtime, the channel uses the default event property-based EventPartitioner to determine how to dispatch each incoming event to its listeners.

25.2.1.2 How to Configure Scalability With a Custom Channel EventPartitioner

You can implement your own EventPartitioner class to customize how a channel dispatches events to its listeners.

Optionally, you can use the default event property-based EventPartitioner as Section 25.2.1.1, "How to Configure Scalability With the Default Channel EventPartitioner" describes.

To configure scalability with a custom channel EventPartitioner:

  1. Using the Oracle Event Processing IDE for Eclipse, open your Oracle Event Processing project.

    For more information, see Section 5.2, "Creating Oracle Event Processing Projects".

  2. Edit your MANIFEST.MF to import package com.bea.wlevs.channel.

    For more information, see Section 5.7.5, "How to Import a Package".

  3. Right-click your project's src folder and select New > Class.

    The New Java Class dialog appears as Figure 25-5 shows.

    Figure 25-5 New Java Class Dialog

    Description of Figure 25-5 follows
    Description of "Figure 25-5 New Java Class Dialog"

  4. Configure the New Java Class dialog as Table 25-2 describes.

    Table 25-2 New Java Class Options for EventPartitioner

    Option Description

    Package

    Enter the class's package name.

    Name

    Enter the class's name.

    Interfaces

    Click Add and use the Implemented Interfaces Selection dialog to locate the com.bea.wlevs.channel.EventPartitioner interface, select it in the Matching Items list, and then click OK.


  5. Click Finish.

    A new EventPartitioner class is created as Example 25-4 shows.

    Example 25-4 EventPartitioner Class

    package com.acme;
    
    import com.bea.wlevs.channel.EventPartitioner;
    import com.bea.wlevs.ede.api.EventProcessingException;
    import com.bea.wlevs.ede.api.EventType;
    
    public class MyEventPartitioner implements EventPartitioner {
    
        @Override
        public void activateConfiguration(int arg0, EventType arg1) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public int partition(Object arg0) throws EventProcessingException {
            // TODO Auto-generated method stub
            return 0;
        }
     
    }
    
  6. Complete the implementation of your EventPartitioner as Example 25-5 shows.

    Example 25-5 EventPartitioner Class Implementation

    package com.acme;
    
    import com.bea.wlevs.channel.EventPartitioner;
    import com.bea.wlevs.ede.api.EventProcessingException;
    import com.bea.wlevs.ede.api.EventType;
    
    public class MyEventPartitioner implements EventPartitioner {
    
        private final EventType eventType;
        private int numberOfPartitions;
    
        @Override
        public void activateConfiguration(int numberOfPartitions, EventType eventType) {
            this.numberOfPartitions = numberOfPartitions;
            this.eventType = eventType;
        }
    
        @Override
        public int partition(Object event) throws EventProcessingException {
            int dispatchToListener = 0;
            ... // Your implementation.
            return dispatchToListener;
        }
    
    }
    

    The activateConfiguration method is a callback that the Oracle Event Processing server invokes before ActivatableBean.afterConfigurationActive and before your EventPartitioner class's partition method is invoked.

    When you associate this EventPartitioner with a channel, the channel will invoke your EventPartitioner class's partition method each time the channel receives an event.

    Your partition method must return the index of the listener to which the channel should dispatch the event. The index must be an int between 0 and numberOfPartitions - 1.

  7. Add a channel to your EPN.

    In Figure 25-4, the channel is EventPartitionerChannel.

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

  8. Connect the channel to an upstream adapter.

    In Figure 25-4, the upstream adapter is inbound.

    For more information, see Section 7.4.2, "Connecting Nodes".

  9. Connect the channel to two or more listeners.

    In Figure 25-4, the channel is connected to Oracle CQL processors processor1, processor2, and processor3.

    If you want to the channel to perform load balancing, each listener must be identical.

    For more information, see:

  10. Edit the EPN assembly file to add an eventPartitioner instance property to the channel element.

    The value of this instance-property is the fully qualified class name of the EventPartitioner instance the channel will use to partition events.

    This class must be on your Oracle Event Processing application class path.

    In this example, the channel uses EventPartitioner instance com.acme.MyEventPartitioner to partition events.

    ...
        <wlevs:channel id="EventPartitionerChannel" event-type="PriceEvent" max-threads="0" >
            <wlevs:instance-property name="eventPartitioner"             value="com.acme.MyEventPartitioner" />
            <wlevs:listener ref="filterFanoutProcessor1" />
            <wlevs:listener ref="filterFanoutProcessor2" />
            <wlevs:listener ref="filterFanoutProcessor3" />
            <wlevs:source ref="PriceAdapter" />
        </wlevs:channel>
    ...
    
  11. Decide how you want Oracle Event Processing to allocate threads as Section 25.1.2.1.3, "EventPartitioner Threading" describes:

    1. If you want the channel to allocate threads:

      • Edit the EPN assembly file to configure the channel to set max-threads to the number of listeners.

        ...
            <wlevs:channel id="EventPartitionerChannel" event-type="PriceEvent"         max-threads="3" >
                <wlevs:instance-property name="eventPartitioner" value="true" />
                <wlevs:listener ref="processor1" />
                <wlevs:listener ref="processor2" />
                <wlevs:listener ref="processor3" />
                <wlevs:source ref="inbound" />
            </wlevs:channel>
        ...
        
    2. If you want the upstream adapter to allocate threads:

      • Edit the EPN assembly file to configure the channel to set max-threads to 0.

        ...
            <wlevs:channel id="EventPartitionerChannel" event-type="PriceEvent"         max-threads="0" >
                <wlevs:instance-property name="eventPartitioner" value="true" />
                <wlevs:listener ref="processor1" />
                <wlevs:listener ref="processor2" />
                <wlevs:listener ref="processor3" />
                <wlevs:source ref="inbound" />
            </wlevs:channel>
        ...
        
      • Edit the Oracle Event Processing server config.xml file to add a work-manager element.

        If this work manager is shared by more than one component (such as other adapters and Jetty), then set the min-threads-constraint and max-threads-constraint elements each to a value greater than the number of listeners.

        If this work manager is not shared by more than one component (that is, it is dedicated to the upstream adapter in this configuration), then set the min-threads-constraint and max-threads-constraint elements equal to the number of listeners.

        ...
        <work-manager>
            <name>adapterWorkManager</name>
            <min-threads-constraint>3</min-threads-constraint>
            <max-threads-constraint>3</max-threads-constraint>
        </work-manager>
        ...
        

        For more information, see Section F.45, "work-manager".

      • Edit the component configuration file to configure the upstream adapter with this work-manager.

        ...
        <adapter>
            <name>inbound</name>
            <work-manager-name>adapterWorkManager</work-manager-name>
            ...
        </adapter>
        ...
        
  12. Assemble and deploy your application.

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

    At runtime, the channel uses your EventPartitioner to determine how to dispatch each incoming event to its listeners.

25.2.2 Configuring Scalability With the ActiveActiveGroupBean

This section describes how to configure your Oracle Event Processing application to use the ActiveActiveGroupBean to partition an incoming JMS event stream by selector, including:

For more information, see Section 25.1.2.2, "ActiveActiveGroupBean".

25.2.2.1 How to Configure Scalability in a JMS Application Without Oracle Event Processing High Availability

You can use the ActiveActiveGroupBean to partition an incoming JMS event stream by selector in a multi-server domain for an application that does not use Oracle Event Processing high availability.

For information on how to use the ActiveActiveGroupBean in an Oracle Event Processing high availability application, see Section 25.2.2.2, "How to Configure Scalability in a JMS Application With Oracle Event Processing High Availability".

For more information, see Section 25.1.2.2.1, "Scalability in an Oracle Event Processing Application Using the ActiveActiveGroupBean Without High Availability".

To configure scalability in a JMS application without Oracle Event Processing high availability:

  1. Create a multi-server domain.

    For more information, see "Introduction to Multi-Server Domains" in the Oracle Fusion Middleware Administrator's Guide for Oracle Event Processing.

    In this example, the deployment group is named MyDeploymentGroup.

  2. Configure the Oracle Event Processing server configuration file on each Oracle Event Processing server to add the appropriate ActiveActiveGroupBean notification group to the groups child element of the cluster element.

    The Oracle Event Processing server configuration file, config.xml, is located in the DOMAIN_DIR/servername/config directory, where DOMAIN_DIR refers to the main domain directory and servername refers to a particular server instance.

    For example, Table 25-4 shows cluster elements for Oracle Event Processing servers ocep-server-1, ocep-server-2, ocep-server-3, and ocep-server-4. The deployment group is MyDeploymentGroup and notification groups are defined using default ActiveActiveGroupBean notification group naming.

    Optionally, you can specify your own group naming convention as Section 25.2.2.3, "How to Configure the ActiveActiveGroupBean Group Pattern Match" describes.

    Table 25-3 Oracle Event Processing Server Configuration File groups Element Configuration

    Partition cluster Element

    ocep-server-1

    <cluster>
        <server-name>ocep-server-1</server-name>
        ...
        <enabled>coherence</enabled>
        ...
        <groups>MyDeploymentGroup, ActiveActiveGroupBean_group1</groups>
    </cluster>
    

    ocep-server-2

    <cluster>
        <server-name>ocep-server-2</server-name>
        ...
        <enabled>coherence</enabled>
        ...
        <groups>MyDeploymentGroup, ActiveActiveGroupBean_group2</groups>
    </cluster>
    

    ocep-server-3

    <cluster>
        <server-name>ocep-server-3</server-name>
        ...
        <enabled>coherence</enabled>
        ...
        <groups>MyDeploymentGroup, ActiveActiveGroupBean_group3</groups>
    </cluster>
    

    ocep-server-4

    <cluster>
        <server-name>ocep-server-4</server-name>
        ...
        <enabled>coherence</enabled>
        ...
        <groups>MyDeploymentGroup, ActiveActiveGroupBean_group4</groups>
    </cluster>
    

  3. Create an Oracle Event Processing application.

  4. Configure the EPN assembly file to add an ActiveActiveGroupBean element as Example 25-10 shows.

    Example 25-6 ActiveActiveGroupBean bean Element

    <bean id="clusterAdapter" class="com.oracle.cep.cluster.hagroups.ActiveActiveGroupBean">
    </bean>
    
  5. Define a parameterized message-selector in the jms-adapter element for the JMS inbound adapters.

    Edit the component configuration file to add group-binding child elements to the jms-adapter element for the JMS inbound adapters.

    Add one group-binding element for each possible JMS message-selector value as Example 25-12 shows.

    Example 25-7 jms-adapter Selector Definition for ocep-server-1

    <jms-adapter>
        <name>JMSInboundAdapter</name>
        <event-type>StockTick</event-type>
        <jndi-provider-url>t3://ppurich-pc:7001</jndi-provider-url>
        <destination-jndi-name>./Topic1</destination-jndi-name>
        <user>weblogic</user>
        <password>weblogic1</password>
        <work-manager>JettyWorkManager</work-manager>
        <concurrent-consumers>1</concurrent-consumers>
        <session-transacted>true</session-transacted>
        <message-selector>${CONDITION}</message-selector>
        <bindings>
            <group-binding group-id="ActiveActiveGroupBean_group1">
                <param id="CONDITION">acctid > 400</param>
            </group-binding>
            <group-binding group-id="ActiveActiveGroupBean_group2">
                <param id="CONDITION">acctid BETWEEN 301 AND 400</param>
            </group-binding>
            <group-binding group-id="ActiveActiveGroupBean_group3">
                <param id="CONDITION">acctid BETWEEN 201 AND 300</param>
            </group-binding>
            <group-binding group-id="ActiveActiveGroupBean_group4">
                <param id="CONDITION">acctid <= 200</param>
            </group-binding>
         </bindings>
    </jms-adapter>
    

    In this configuration, when the application is deployed to an Oracle Event Processing server with a cluster element groups child element that contains ActiveActiveGroupBean_group1, then the CONDITION parameter is defined as acctid > 400 and the application processes events whose acctid property is greater than 400.

    Note:

    Each in-bound JMS adapter must listen to a different topic.

    For more information, see Chapter 11, "Integrating the Java Message Service".

  6. Deploy your application to the deployment group of your multi-server domain.

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

    At runtime, each Oracle Event Processing server configures its instance of the application with the message-selector that corresponds to its ActiveActiveGroupBean notification group. This partitions the JMS topic so that each instance of the application processes a subset of the total number of messages in parallel.

25.2.2.2 How to Configure Scalability in a JMS Application With Oracle Event Processing High Availability

You can use the ActiveActiveGroupBean to partition an incoming JMS event stream in a multi-server domain with Oracle Event Processing high availability.

This procedure uses the example application from Section 24.2.1.4, "How to Configure Precise Recovery With JMS", including the example EPN that Figure 25-6 shows, the corresponding EPN assembly file that Example 25-8 shows, and the corresponding component configuration file that Example 25-9 shows.

Figure 25-6 Precise Recovery With JMS EPN

Description of Figure 25-6 follows
Description of "Figure 25-6 Precise Recovery With JMS EPN"

Example 25-8 Precise Recovery With JMS EPN Assembly File

<?xml version="1.0" encoding="UTF-8"?>
<beans ... >

    <wlevs:event-type-repository>
        <wlevs:event-type type-name="StockTick">
            <wlevs:properties>
                <wlevs:property name="lastPrice" type="double" />
                <wlevs:property name="symbol" type="char" />
            </wlevs:properties>
        </wlevs:event-type>
    </wlevs:event-type-repository>

    <wlevs:adapter id="JMSInboundAdapter" provider="jms-inbound">
        <wlevs:listener ref="myHaInputAdapter"/>
    </wlevs:adapter>

    <wlevs:adapter id="myHaInputAdapter" provider="ha-inbound" >
        <wlevs:instance-property name="keyProperties" value="sequenceNo"/>
        <wlevs:instance-property name="timeProperty" value="inboundTime"/>
    </wlevs:adapter>

    <wlevs:channel id="channel1" event-type="StockTick">
        <wlevs:listener ref="processor1" />
        <wlevs:source ref="myHaInputAdapter"/>
        <wlevs:application-timestamped>
            <wlevs:expression>inboundTime</wlevs:expression>
        </wlevs:application-timestamped>
    </wlevs:channel>

    <wlevs:processor id="processor1">
        <wlevs:listener ref="channel2" />
    </wlevs:processor>

    <wlevs:channel id="channel2" event-type="StockTick">
        <wlevs:listener ref="myHaCorrelatingAdapter" />
    </wlevs:channel>

    <wlevs:adapter id="myHaCorrelatingAdapter" provider="ha-correlating" >
        <wlevs:instance-property name="correlatedSource" ref="clusterCorrelatingOutstream"/> 
        <wlevs:instance-property name="failOverDelay" value="2000"/> 
        <wlevs:listener ref="JMSOutboundAdapter"/>
    </wlevs:adapter>

    <wlevs:adapter id="JMSOutboundAdapter" provider="jms-outbound">
    </wlevs:adapter>

    <wlevs:adapter id="JMSInboundAdapter2" provider="jms-inbound">
    </wlevs:adapter>

    <wlevs:channel id="clusterCorrelatingOutstream" event-type="StockTick" advertise="true">
        <wlevs:source ref="JMSInboundAdapter2"/>
    </wlevs:channel> 
</beans>

Example 25-9 Precise Recovery With JMS Component Configuration Assembly File

<?xml version="1.0" encoding="UTF-8"?>
<wlevs:config 
        xmlns:wlevs="http://www.bea.com/ns/wlevs/config/application"
        xmlns:ha="http://www.oracle.com/ns/cep/config/cluster/">
    <processor>
        <name>processor1</name>
        <rules>
            <query id="helloworldRule">
                <![CDATA[ select * from channel1 [Now] ]]>
            </query>
        </rules>
    </processor>
    <jms-adapter>
        <name>JMSInboundAdapter</name>
        <event-type>StockTick</event-type>
        <jndi-provider-url>t3://ppurich-pc:7001</jndi-provider-url>
        <destination-jndi-name>./Topic1</destination-jndi-name>
        <session-transacted>true</session-transacted>
    ...
    </jms-adapter>
    <jms-adapter>
        <name>JMSInboundAdapter2</name>
        <event-type>StockTick</event-type>
        <jndi-provider-url>t3://ppurich-pc:7001</jndi-provider-url>
        <destination-jndi-name>./Topic2</destination-jndi-name>
        <session-transacted>true</session-transacted>
    ...
    </jms-adapter>
    <jms-adapter>
        <name>JMSOutboundAdapter</name>
        <event-type>StockTick</event-type>
        <jndi-provider-url>t3://ppurich-pc:7001</jndi-provider-url>
        <destination-jndi-name>./Topic2</destination-jndi-name>
        <session-transacted>true</session-transacted>
    ...
    </jms-adapter>
</wlevs:config>

This procedure will create the Oracle Event Processing high availability configuration that Figure 25-7 shows.

Figure 25-7 Oracle Event Processing ActiveActiveGroupBean With High Availability

Description of Figure 25-7 follows
Description of "Figure 25-7 Oracle Event Processing ActiveActiveGroupBean With High Availability"

For more information, see Section 25.1.2.2.2, "Scalability in an Oracle Event Processing Application Using the ActiveActiveGroupBean With High Availability".

To configure scalability in a JMS application with Oracle Event Processing high availability:

  1. Create a multi-server domain.

    For more information, see "Introduction to Multi-Server Domains" in the Oracle Fusion Middleware Administrator's Guide for Oracle Event Processing.

    In this example, the deployment group is named MyDeploymentGroup.

  2. Configure the Oracle Event Processing server configuration file on each Oracle Event Processing server to add the appropriate ActiveActiveGroupBean notification group to the groups child element of the cluster element.

    The Oracle Event Processing server configuration file, config.xml, is located in the DOMAIN_DIR/servername/config directory, where DOMAIN_DIR refers to the main domain directory and servername refers to a particular server instance.

    For example, Table 25-4 shows cluster elements for Oracle Event Processing servers ocep-server-1, ocep-server-2, ocep-server-3, and ocep-server-4. The deployment group is MyDeploymentGroup and notification groups are defined using default ActiveActiveGroupBean notification group names.

    Note that ocep-server-1 and ocep-server-2 use the same notification group name (ActiveActiveGroupBean_group1) and ocep-server-3 and ocep-server-4 use the same notification group name (ActiveActiveGroupBean_group2).

    Optionally, you can specify your own group naming convention as Section 25.2.2.3, "How to Configure the ActiveActiveGroupBean Group Pattern Match" describes.

    Table 25-4 Oracle Event Processing Server Configuration File groups Element Configuration

    Partition cluster Element

    ocep-server-1

    <cluster>
        <server-name>ocep-server-1</server-name>
        ...
        <enabled>coherence</enabled>
        ...
        <groups>MyDeploymentGroup, ActiveActiveGroupBean_group1</groups>
    </cluster>
    

    ocep-server-2

    <cluster>
        <server-name>ocep-server-2</server-name>
        ...
        <enabled>coherence</enabled>
        ...
        <groups>MyDeploymentGroup, ActiveActiveGroupBean_group1</groups>
    </cluster>
    

    ocep-server-3

    <cluster>
        <server-name>ocep-server-3</server-name>
        ...
        <enabled>coherence</enabled>
        ...
        <groups>MyDeploymentGroup, ActiveActiveGroupBean_group2</groups>
    </cluster>
    

    ocep-server-4

    <cluster>
        <server-name>ocep-server-4</server-name>
        ...
        <enabled>coherence</enabled>
        ...
        <groups>MyDeploymentGroup, ActiveActiveGroupBean_group2</groups>
    </cluster>
    

  3. Create an Oracle Event Processing high availability application.

    For more information, see Chapter 24, "Developing Applications for High Availability".

  4. Configure the EPN assembly file to add an ActiveActiveGroupBean element as Example 25-10 shows.

    Example 25-10 ActiveActiveGroupBean bean Element

    <bean id="clusterAdapter" class="com.oracle.cep.cluster.hagroups.ActiveActiveGroupBean">
    </bean>
    
  5. Edit the component configuration file to configure a jms-adapter element for the inbound JMS adapters as Example 25-11 shows:

    • Each in-bound JMS adapter must listen to a different topic.

    • Set session-transacted to true.

    Example 25-11 jms-adapter Element for Inbound JMS Adapters

    <?xml version="1.0" encoding="UTF-8"?>
    <wlevs:config 
            xmlns:wlevs="http://www.bea.com/ns/wlevs/config/application"
            xmlns:ha="http://www.oracle.com/ns/cep/config/cluster/">
        ...
        <jms-adapter>
            <name>JMSInboundAdapter</name>
            <event-type>StockTick</event-type>
            <jndi-provider-url>t3://ppurich-pc:7001</jndi-provider-url>
            <destination-jndi-name>./Topic1</destination-jndi-name>
            <session-transacted>true</session-transacted>
        ...    </jms-adapter>
        <jms-adapter>
            <name>JMSInboundAdapter2</name>
            <event-type>StockTick</event-type>
            <jndi-provider-url>t3://ppurich-pc:7001</jndi-provider-url>
            <destination-jndi-name>./Topic2</destination-jndi-name>
            <session-transacted>true</session-transacted>
        ...    </jms-adapter>
    </wlevs:config>
    

    For more information, see Chapter 11, "Integrating the Java Message Service".

  6. Define a parameterized message-selector in the jms-adapter element for each JMS inbound adapter.

    Edit the component configuration file to add group-binding child elements to the jms-adapter element for the JMS inbound adapters.

    Add one group-binding element for each possible JMS message-selector value as Example 25-12 shows.

    Example 25-12 jms-adapter Selector Definition for ocep-server-1

    <jms-adapter>
        <name>JMSInboundAdapter</name>
        <event-type>StockTick</event-type>
        <jndi-provider-url>t3://ppurich-pc:7001</jndi-provider-url>
        <destination-jndi-name>./Topic1</destination-jndi-name>
        <session-transacted>true</session-transacted>
        <message-selector>${CONDITION}</message-selector>
        <bindings>
            <group-binding group-id="ActiveActiveGroupBean_group1">
                <param id="CONDITION">acctid <= 1000</param>
            </group-binding>
            <group-binding group-id="ActiveActiveGroupBean_group2">
                <param id="CONDITION">acctid > 1000</param>
            </group-binding>
         </bindings>
    </jms-adapter>
    

    In this configuration, when the application is deployed to an Oracle Event Processing server with a cluster element groups child element that contains ActiveActiveGroupBean_group1, then the CONDITION parameter is defined as acctid <= 1000 and the application processes events whose acctid property is less than or equal to 1000. Similarly, when the application is deployed to an Oracle Event Processing server with a cluster element groups child element that contains ActiveActiveGroupBean_group2, then the CONDITION parameter is defined as acctid > 1000 and the application processes events whose acctid property is greater than 1000.

  7. Edit the component configuration file to configure a jms-adapter element for the outbound JMS adapter as Example 25-13 shows:

    • Configure the out-bound JMS adapter with the same topic as the correlating in-bound adapter (in this example, JMSInboundAdapter2: ./Topic2).

    • Set session-transacted to true.

    Example 25-13 jms-adapter Element for Outbound JMS Adapters

    <?xml version="1.0" encoding="UTF-8"?>
    <wlevs:config 
            xmlns:wlevs="http://www.bea.com/ns/wlevs/config/application"
            xmlns:ha="http://www.oracle.com/ns/cep/config/cluster/">
        ...
        <jms-adapter>
            <name>JMSInboundAdapter</name>
            <event-type>StockTick</event-type>
            <jndi-provider-url>t3://ppurich-pc:7001</jndi-provider-url>
            <destination-jndi-name>./Topic1</destination-jndi-name>
            <session-transacted>true</session-transacted>
        ...    </jms-adapter>
        <jms-adapter>
            <name>JMSInboundAdapter2</name>
            <event-type>StockTick</event-type>
            <jndi-provider-url>t3://ppurich-pc:7001</jndi-provider-url>
            <destination-jndi-name>./Topic2</destination-jndi-name>
            <session-transacted>true</session-transacted>
        ...    </jms-adapter>
        <jms-adapter>
            <name>JMSOutboundAdapter</name>
            <event-type>StockTick</event-type>
            <jndi-provider-url>t3://ppurich-pc:7001</jndi-provider-url>
            <destination-jndi-name>./Topic2</destination-jndi-name>
            <session-transacted>true</session-transacted>
        ...    </jms-adapter>
    </wlevs:config>
    

    For more information, see Chapter 11, "Integrating the Java Message Service".

  8. Deploy your application to the deployment group of your multi-server domain.

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

    At runtime, each Oracle Event Processing server configures its instance of the application with the message-selector that corresponds to its ActiveActiveGroupBean notification group. This partitions the JMS topic so that each instance of the application processes a subset of the total number of messages in parallel.

    If the active Oracle Event Processing server in an ActiveActiveGroupBean group goes down, the Oracle Event Processing server performs an Oracle Event Processing high availability failover to the standby Oracle Event Processing server in that ActiveActiveGroupBean group.

25.2.2.3 How to Configure the ActiveActiveGroupBean Group Pattern Match

By default, the ActiveActiveGroupBean creates notification groups named:

ActiveActiveGroupBean_X

Where X is a string.

At runtime, the ActiveActiveGroupBean scans the existing groups defined on the Oracle Event Processing server and applies a default pattern match of:

ActiveActiveGroupBean_\\w+

When it finds a match, it creates a notification group of that name.

Optionally, you can define your own group pattern to specify a different notification group naming pattern.

How to configure the ActiveActiveGroupBean group pattern match:

  1. Configure the EPN assembly file to add a groupPattern attribute to your ActiveActiveGroupBean element as Example 25-14 shows.

    Example 25-14 ActiveActiveGroupBean bean Element With groupPattern Attribute

    <bean id="clusterAdapter" class="com.oracle.cep.cluster.hagroups.ActiveActiveGroupBean">
        <property name="groupPattern" value="MyNotificationGroupPattern*"/>
    </bean>
    
  2. Specify a value for the groupPattern attribute that matches the cluster group naming convention you want to use for notification groups.