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

Previous
Previous
 
Next
Next
 

8 Configuring Custom Adapters, Event Beans, and Spring Beans

This section contains information on the following subjects:

8.1 Overview of Custom Adapters, Event Beans, and Spring Beans

This section provides an overview of adapter and event bean implementation, including:

8.1.1 Custom Adapters

One of the main roles of an adapter is to convert data coming from some channel, such as a market data feed, into Oracle CEP events. These events are then passed to other components in the application, such as processors. An adapter is usually the entry point to an Oracle CEP application. An adapter can also be the exit point of an application so that it receives events from an intermediate component, converts the data into something that an external application can read, and then sends it out.

"Foreign Exchange (FX) Example" in the Oracle CEP Getting Started shows three adapters that read in data from currency data feeds and then pass the data, in the form of a specific event type, to the processors, which are the next components in the network.

You can create adapters of different types, depending on the format of incoming data and the technology you use in the adapter code to do the conversion. The most typical types of adapters are those that:

  • Use a data vendor API, such as Reuters, Wombat, or Bloomberg.

  • Convert incoming JMS messages using standard JMS APIs.

  • Use other messaging systems, such as TIBCO Rendezvous.

  • Use a socket connection to the customer's own data protocol.

Adapters are Java classes that implement specific Oracle CEP interfaces. You register the adapter classes in the EPN assembly file that describes your entire application.

You can optionally change the default configuration of the adapter, or even extend the configuration and add new configuration elements and attributes. There are two ways to pass configuration data to the adapter; the method you chose depends on whether you want to dynamically change the configuration after deployment:

If you are not going to change the configuration data after the adapter is deployed, then you can configure the adapter in the EPN assembly file.

If, however, you do want to be able to dynamically change the configuration elements, then you should put this configuration in the adapter-specific configuration files.

For more information, see Section 8.1, "Overview of Custom Adapters, Event Beans, and Spring Beans".

8.1.2 Custom Event Beans

Event beans are very similar to standard Spring beans except that they can be managed by the Oracle CEP management framework. Standard Spring beans are managed by the Spring framework. You register event beans in the EPN assembly file using the Oracle CEP <wlevs:event-bean> stage rather than the standard <bean> tag.

An event bean is a type of Stage, it can be monitored by the Oracle CEP monitoring framework, make use of the configuration metadata annotations, and it can be set to record, and play-back events that pass through it. An event bean can also participate in the Event Server bean lifecycle by specifying methods in its XML declaration, rather than by implementing Event Server API interfaces.

You can use either an event bean or a Spring bean:

  • Use an event bean to actively use the capabilities of the Oracle CEP server container.

  • Use a Spring bean for legacy integration to Spring.

For more information, see:

8.1.3 Custom Spring Beans

Spring beans are managed by the Spring framework. You register Spring beans in the EPN assembly file using the standard <bean> tag.

A Spring bean cannot be monitored by the Oracle CEP monitoring framework, cannot use the configuration metadata annotations, and cannot be set to record and play-back events that pass through it.

You can use either a Spring bean or an event bean:

  • Use a Spring bean for legacy integration to Spring.

  • Use an event bean to actively use the capabilities of the Oracle CEP server container.

For more information, see:

8.1.4 Event Sources and Event Sinks

Standard Spring beans and event beans can be event sources, event sinks, or both. Event sources generate events, event sinks receive events.

This section describes:

For more information, see:

8.1.4.1 Event Beans as Event Sources

You specify that an event bean component in your EPN is an event source by implementing the com.bea.wlevs.ede.api.StreamSource or RelationSource API

The implementation class of an event bean that is an event source may be specified as private to the application or as an advertised OSGI service re-usable by other applications.

For the framework to be able to fully manage the bean as an EPN component, it must be specified as an event-bean rather than a standard Spring bean. Management tasks include monitoring and record/playback.

You register event beans in the EPN assembly file using the <wlevs:event-bean> tag. For example:

<wlevs:event-bean id="recplayEventSink"
                  class="com.bea.wlevs.example.recplayRecplayEventSink">
    <wlevs:listener ref="playbackHttpPublisher"/>
</wlevs:event-bean>

8.1.4.2 Spring Beans as Event Sources

You specify that a standard Spring bean component in your EPN is an event source by implementing the com.bea.wlevs.ede.api.StreamSource or RelationSource API.

The bean may also optionally implement the various lifecycle interfaces, such as InitializingBean, DisposableBean, and the active interfaces, such as RunnableBean. If a Spring-bean implements Runnable but not RunnableBean, Oracle CEP does not run it in a thread. This is different behavior from an event bean.

The Spring bean event source can make use of the configuration metadata annotations, such as @Prepare, @Rollback, and @Activate.

You register the Spring bean in the EPN assembly file in the standard way using the bean element. You can then specify this bean as an event source of some other stage in the EPN.

8.1.4.3 Event Beans as Event Sinks

The functionality of event beans as event sinks is very similar to that of event sources except that event bean sinks must implement the com.bea.wlevs.ede.api.StreamSink or RelationSink API.

Event sinks are not active which means that if they implement the Runnable interface, Oracle CEP does not run them in a separate thread.

You reference event sinks in the EPN assembly file using the wlevs:listener element:

<wlevs:channel id="myStream" >
    <wlevs:listener ref="myEventSink" />
</wlevs:channel>

8.1.4.4 Spring Beans as Event Sinks

You specify that a standard Spring bean component in your EPN is an event sink by implementing the com.bea.wlevs.ede.api.StreamSink or RelationSinkn API.

The bean may also optionally implement the various lifecycle interfaces, such as InitializingBean, DisposableBean, and the active interfaces, such as RunnableBean. If a Spring-bean implements Runnable but not RunnableBean, Oracle CEP does not run it in a thread. This is different behavior from an event bean.

The Spring bean event source can make use of the configuration metadata annotations, such as @Prepare, @Rollback, and @Activate.

You register the Spring bean in the EPN assembly file in the standard way using the bean element. You can then specify this bean as an event sink of some other stage in the EPN.

You reference event sinks in the EPN assembly file using the wlevs:listener element:

<wlevs:channel id="myStream" >
    <wlevs:listener ref="myEventSink" />
</wlevs:channel>

8.1.5 Adapter and Event Bean Factories

If your adapter or event bean is going to be used only by a single Oracle CEP application, then you do not need to create a factory. However, if multiple applications are going to use the same adapter or event bean, then you should also program a factory. In this case, every application gets its own instance of the adapter.

Adapter or event bean factories must implement the com.bea.wlevs.ede.api.Factory interface. This interface has a single method, create(), that you implement to create an adapter or event bean instance.

You register factories in the EPN assembly file using the wlevs:factory element:

<wlevs:factory provider-name="myprovider" class="my.Implementation"/>

Note that if you need to specify service properties, then you must use the <osgi:service> tag to register the factory.

For more information, see Section 8.5, "Implementing an Adapter or Event Bean Factory"

8.2 Implementing an Adapter or Event Bean

The following procedure describes the typical steps for creating an adapter.

To implement an adapter or event bean:

  1. Program the adapter or event bean Java class.

    If your adapter or event bean is an event source, see Section 8.3, "Implementing an Adapter or Event Bean as an Event Source."

    If your adapter or event bean is an event sink, see Section 8.4, "Implementing an Adapter or Event Bean as an Event Sink."

  2. Optionally program the factory class. You only need to do this if many applications are going to use the adapter or event bean.

    See Section 8.5, "Implementing an Adapter or Event Bean Factory."

  3. Update the EPN assembly file with adapter, event bean, and adapter factory registration info.

    See Section 8.7, "Updating the EPN Assembly File."

  4. Optionally change the default configuration of the adapter.

    See Section 8.8, "Configuring an Adapter or Event Bean."

  5. Optionally extend the configuration of the adapter if its basic one is not adequate.

    See Section 8.9, "Extending the Configuration of an Adapter or Event Bean."

In the preceding procedure, it is assumed that the adapter or event bean is bundled in the same application JAR file that contains the other components of the event network, such as the processor, streams, and business logic POJO. If you want to bundle the adapter or event bean in its own JAR file so that it can be shared among many applications, see Section 8.11, "Assembling an Adapter or Event Bean in Its Own Bundle."

8.3 Implementing an Adapter or Event Bean as an Event Source

This section describes how to create an inbound adapter that acts as an event source because it receives incoming data and generates events that it sends to the next component in the EPN. Because event beans are functionally the same, the guidelines also apply to programming event beans that act as event sources.

The inbound adapter class typically reads the stream of incoming data, such as from a market data feed, converts it into an Oracle CEP event type that is understood by the rest of the application, and sends the event to the next component in the network.

The following example shows the adapter class of the HelloWorld sample; see the explanation after the example for coding guidelines that correspond to the Java code in bold.

package com.bea.wlevs.adapter.example.helloworld;

import java.text.DateFormat;
import java.util.Date;

import com.bea.wlevs.ede.api.RunnableBean;
import com.bea.wlevs.ede.api.StreamSender;
import com.bea.wlevs.ede.api.StreamSource;
import com.bea.wlevs.event.example.helloworld.HelloWorldEvent;

public class HelloWorldAdapter implements RunnableBean, StreamSource {

    private static final int SLEEP_MILLIS = 300;

    private DateFormat dateFormat;
    private String message;
    private boolean suspended;

    private StreamSender eventSender;

    public HelloWorldAdapter() {
        super();
        dateFormat = DateFormat.getTimeInstance();
    }

    public void run() {
        suspended = false;
        while (!isSuspended()) { // Generate messages forever...

            generateHelloMessage();

            try {
                synchronized (this) {
                    wait(SLEEP_MILLIS);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void setMessage(String message) {
        this.message = message;
    }

    private void generateHelloMessage() {
        String message = this.message + dateFormat.format(new Date());
        HelloWorldEvent event = new HelloWorldEvent();
        event.setMessage(message);
    
        eventSender.sendInsertEvent(event);
    }

    public void setEventSender(StreamSender sender) {
        eventSender = sender;
    }

    public synchronized void suspend() {
        suspended = true;
    }
 
    private synchronized boolean isSuspended() {
        return suspended;
    }
}

Follow these guidelines when programming the adapter Java class; code snippets of the guidelines are shown in bold in the preceding example:

8.4 Implementing an Adapter or Event Bean as an Event Sink

The following sample code shows a Spring bean from HelloWorld application that acts as an event sink; see the explanation after the example for the code shown in bold:

package com.bea.wlevs.example.helloworld;
 
import com.bea.wlevs.ede.api.StreamSink;
import com.bea.wlevs.event.example.helloworld.HelloWorldEvent;
 
public class HelloWorldBean implements StreamSink {
 
    public void onInsertEvent(Object event) {
        if (event instanceof HelloWorldEvent) {
            HelloWorldEvent helloWorldEvent = (HelloWorldEvent) event;
            System.out.println("Message: " + helloWorldEvent.getMessage());
        }   
    }
 
}

The programming guidelines shown in the preceding example are as follows:

For complete API reference information about the Oracle CEP APIs described in this section, see the Oracle CEP Java API Reference.

8.5 Implementing an Adapter or Event Bean Factory

Your adapter factory class must implement the com.bea.wlevs.ede.api.AdapterFactory interface, which has a single method, create(), in which you code the creation of your specific adapter class. Event beans implement Factory.

The following is a possible adapter factory class for the HelloWorld example:

package com.bea.adapter.wlevs.example.helloworld;
import com.bea.wlevs.ede.api.Adapter;
import com.bea.wlevs.ede.api.AdapterFactory;
public class HelloWorldAdapterFactory implements Factory {
    public HelloWorldAdapterFactory() {
    }
    public synchronized Adapter create() throws IllegalArgumentException {
        return new HelloWorldAdapter();
    }
}

For full details of these APIs, see the Oracle CEP Java API Reference.

8.6 Accessing a Relational Database

You can use the Java Database Connectivity (JDBC) APIs (http://java.sun.com/javase/technologies/database/) in your adapters, event beans, and standard Spring beans to access data contained in a relational database. Oracle CEP supports JDBC 3.0. For more information, see http://java.sun.com/products/jdbc/download.html#corespec30.

To access a relational database:

  1. Configure JDBC for Oracle CEP.

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

  2. In your bean Java code, you can start using the JDBC APIs as usual, by using a DataSource or instantiating a DriverManager. For example:

    OracleDataSource ods = new OracleDataSource();
    ods.setURL("jdbc:oracle:thin:user/passwd@localhost:1521/XE");
    Connection conn = ods.getConnection();
    

    For additional programming information, see http://java.sun.com/j2se/1.5.0/docs/guide/jdbc/getstart/GettingStartedTOC.fm.html.

8.7 Updating the EPN Assembly File

The adapters, event beans, and adapter factory must be registered in the EPN assembly file, as discussed in the following sections:

For a complete description of the configuration file, including registration of other components of your application, see Section 1.4, "Creating the EPN Assembly File."

8.7.1 Registering the Adapter or Event Bean Factory

You register factories in the EPN assembly file using the wlevs:factory element:

<wlevs:factory provider-name="myprovider" class="my.Implementation"/>

If you need to specify service properties, then you must use the osgi:service element to register the factory as an OSGI service in the EPN assembly file. The scope of the OSGI service registry is the entire Oracle CEP. This means that if more than one application deployed to a given server is going to use the same adapter factory, be sure to register the adapter factory only once as an OSGI service.

Add an entry to register the service as an implementation of the com.bea.wlevs.ede.api.AdapterFactory interface. Provide a property, with the key attribute equal to type, and the name by which this adapter provider will be referenced. Finally, add a nested standard Spring bean element to register the your specific adapter class in the Spring application context

For example, the following segment of the EPN assembly file registers the HelloWorldAdapterFactory as the provider for type hellomsgs:

<osgi:service interface="com.bea.wlevs.ede.api.AdapterFactory">
    <osgi:service-properties>
        <entry key="type" value="hellomsgs"</entry>
    </osgi:service-properties>
    <bean  class="com.bea.adapter.wlevs.example.helloworld.HelloWorldAdapterFactory" />
</osgi:service>

8.7.2 Declaring the Adapter and Event Bean Components in your Application

In the EPN assembly file, you use the wlevs:adapter element to declare an adapter as a component in the event processor network. Similarly, you use the wlevs:event-bean element for event beans. For example:

<wlevs:event-bean id="recplayEventSink"
                  class="com.bea.wlevs.example.recplayRecplayEventSink">
    <wlevs:listener ref="playbackHttpPublisher"/>
</wlevs:event-bean>

If you registered an optional factory as an OSGI service, then use the provider attribute to point to the name you specified as the type in your osgi:service entry; for example:

<wlevs:adapter id="helloworldAdapter" provider="hellomsgs"/>

This means that an adapter will be instantiated by the factory registered for the type hellomsgs.

You can also use a wlevs:instance-property child element of wlevs:adapter to set any static properties in the adapter bean. Static properties are those that you will not dynamically change after the adapter is deployed.

For example, if your adapter class has a setPort() method, you can pass it the port number as shown:

<wlevs:adapter id="myAdapter" provider="myProvider">
    <wlevs:instance-property name="port" value="9001" />
</wlevs:adapter>

8.8 Configuring an Adapter or Event Bean

This section applies to both adapters and event beans. For simplicity the text mentions only adapters. The configuration of an event bean would be enclosed in the event-bean element.

Each adapter in your application has a default configuration.

The default adapter configuration is typically adequate for most applications. However, if you want to change this configuration, you must create an XML file that is deployed as part of the Oracle CEP application bundle. You can later update this configuration at runtime using the wlevs.Admin utility or manipulating the appropriate JMX Mbeans directly.

For more information, see:

If your application has more than one adapter, you can create separate XML files for each adapter, or create a single XML file that contains the configuration for all adapters, or even all components of your application (adapters, processors, and streams). Choose the method that best suits your development environment.

The following procedure describes the main steps to create the adapter configuration file. For simplicity, it is assumed in the procedure that you are going to configure all components of an application in a single XML file

See Section B.1, "Component Configuration Schema wlevs_application_config.xsd" for the complete XSD Schema that describes the adapter configuration file.

To configure an adapter or event bean:

  1. Create an XML file using your favorite XML editor.You can name this XML file anything you want, provided it ends with the .xml extension.

    The root element of the configuration file is config, with namespace definitions shown in the next step.

  2. For each adapter in your application, add an adapter child element of config.

    Uniquely identify each adapter with the name child element. This name must be the same as the value of the id attribute in the wlevs:adapter element of the EPN assembly file that defines the event processing network of your application. This is how Oracle CEP knows to which particular adapter component in the EPN assembly file this adapter configuration applies. See Section 1.4, "Creating the EPN Assembly File" for details.

    For example, if your application has two adapters, the configuration file might initially look like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <helloworld:config
      xmlns:helloworld="http://www.bea.com/xml/ns/wlevs/example/helloworld">
      <processor>
       ...
      </processor>
      <adapter>
        <name>firstAdapter</name>
        ...
      </adapter>
      <adapter>
        <name>secondAdapter</name>
        ...
      </adapter>
    </helloworld:config>
    

    In the example, the configuration file includes two adapters called firstAdapter and secondAdapter. This means that the EPN assembly file must include at least two adapter registrations with the same identifiers:

    <wlevs:adapter id="firstAdapter" ...>
      ...
    </wlevs:adapter>
    <wlevs:adapter id="secondAdapter" ...>
      ...
    </wlevs:adapter>
    

    Caution:

    Identifiers and names in XML files are case sensitive, so be sure you specify the same case when referencing the component's identifier in the EPN assembly file.

8.8.1 Example of an Adapter Configuration File

The following sample XML file shows how to configure two adapters, firstAdapter and secondAdapter.

<?xml version="1.0" encoding="UTF-8"?>
<sample:config
  xmlns:sample="http://www.bea.com/xml/ns/wlevs/example/sample">
  <adapter>
    <name>firstAdapter</name>
  </adapter>
  <adapter>
    <name>secondAdapter</name>
  </adapter>
</sample:config>

8.9 Extending the Configuration of an Adapter or Event Bean

This section applies to both adapters and event beans. For simplicity the text mentions only adapters.

Adapters have default configuration data, as described in Section 8.8, "Configuring an Adapter or Event Bean" and Section B.1, "Component Configuration Schema wlevs_application_config.xsd". This default configuration is typically adequate for simple and basic applications.

However, you can also extend this configuration by using XSD Schema to specifying a new XML format of an adapter configuration file that extends the built-in XML type provided by Oracle CEP. By extending the XSD Schema, you can add as many new elements to the adapter configuration as you want, with few restrictions other than each new element must have a name attribute. This feature is based on standard technologies, such as XSD Schema and Java Architecture for XML Binding (JAXB). For more information, see https://jaxb.dev.java.net/.

To extend the configuration of an adapter or event bean:

  1. Create the new XSD Schema file that describes the extended adapter configuration. This XSD file must also include the description of the other components in your application (processors and streams), although you typically use built-in XSD types, defined by Oracle CEP, to describe them.

    See Section 8.9.1, "Creating the XSD Schema File" for details.

  2. As part of your application build process, generate the Java representation of the XSD schema types using a JAXB binding compiler, such as the com.sun.tools.xjc.XJCTask Ant task (see https://jaxb.dev.java.net/jaxb20-ea/docs/xjcTask.html) from Sun's GlassFish reference implementation. This Ant task is included in the Oracle CEP distribution for your convenience.

    The following sample build.xml file shows how to do this:

    <property name="base.dir" value="." />
    <property name="output.dir" value="output" />
    <property name="sharedlib.dir" value="${base.dir}/../../../../../modules" />
    <property name="wlrtlib.dir" value="${base.dir}/../../../../modules"/>
    <path id="classpath">
            <pathelement location="${output.dir}" />
            <fileset dir="${sharedlib.dir}">
                    <include name="*.jar" />
            </fileset>
            <fileset dir="${wlrtlib.dir}">
                   <include name="*.jar"/>
            </fileset>
    </path>
    <taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask">
          <classpath refid="classpath" />
    </taskdef>
    <target name="generate" depends="clean, init">
       <copy file="../../../../xsd/wlevs_base_config.xsd"
             todir="src/main/resources/extension" />
       <copy file="../../../../xsd/wlevs_application_config.xsd"
              todir="src/main/resources/extension" />
       <xjc extension="true" destdir="${generated.dir}">
          <schema dir="src/main/resources/extension" 
                  includes="helloworld.xsd"/>
          <produces dir="${generated.dir}" includes="**/*.java" />
       </xjc>
    </target>
    

    In the example, the extended XSD file is called helloworld.xsd. The build process copies the Oracle CEP XSD files (wlevs_base_config.xsd and wlevs_application_config.xsd) to the same directory as the helloworld.xsd file because helloworld.xsd imports the Oracle CEP XSD files.

  3. Compile these generated Java files into classes.

  4. Package the compiled Java class files in your application bundle.

    See Section 14.2, "Assembling an Oracle CEP Application" for details.

  5. Program your adapter as described in Section 8.3, "Implementing an Adapter or Event Bean as an Event Source." Within your adapter code, you access the extended configuration as usual, as described in Section 8.9.3, "Programming Access to the Configuration of an Adapter or Event Bean."

  6. When you create the configuration XML file that describes the components of your application, be sure you use the extended XSD file as its description. In addition, be sure you identify the namespace for this schema rather than the default schema. For example:

    <?xml version="1.0" encoding="UTF-8"?>
    <helloworld:config
      xmlns:helloworld="http://www.bea.com/xml/ns/wlevs/example/helloworld">
      <adapter>
        <name>helloworldAdapter</name>
        <message>HelloWorld - the current time is:</message>
      </adapter>
    </helloworld:config>
    

8.9.1 Creating the XSD Schema File

The new XSD schema file extends the wlevs_application_config.xsd XSD schema (see Section B.1, "Component Configuration Schema wlevs_application_config.xsd") and then adds new custom information, such as new configuration elements for an adapter. Use standard XSD schema syntax for your custom information.

Oracle recommends that you use the XSD schema in Section 8.9.2, "Complete Example of an Extended XSD Schema File" as a basic template, and modify the content to suit your needs. In addition to adding new configuration elements, other modifications include changing the package name of the generated Java code and the element name for the custom adapter. You can control whether the schema allows just your custom adapter or other components like processors.

To create a new XSD schema file:

  1. Using your favorite XML Editor, create the basic XSD file with the required namespaces, in particular those for JAXB. For example:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema targetNamespace="http://www.bea.com/xml/ns/wlevs/example/helloworld"
            xmlns="http://www.bea.com/xml/ns/wlevs/example/helloworld"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
            xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
            xmlns:wlevs="http://www.bea.com/xml/ns/wlevs/config/application"
            jxb:extensionBindingPrefixes="xjc" jxb:version="1.0"
            elementFormDefault="unqualified" attributeFormDefault="unqualified">
    ...
    </xs:schema>
    
  2. Import the wlevs_application_config.xsd XSD schema:

    <xs:import 
       namespace="http://www.bea.com/xml/ns/wlevs/config/application"
       schemaLocation="wlevs_application_config.xsd"/>
    

    The wlevs_application_config.xsd in turn imports the wlevs_base_config.xsd XSD file.

  3. Use the complexType XSD element to describe the XML type of the extended adapter configuration.

    The new type must extend the AdapterConfig type, defined in wlevs_application_config.xsd. AdapterConfig extends ConfigurationObject. You can then add new elements or attributes to the basic adapter configuration as needed. For example, the following type called HelloWorldAdapterConfig adds a message element to the basic adapter configuration:

    <xs:complexType name="HelloWorldAdapterConfig">
        <xs:complexContent>
            <xs:extension base="wlevs:AdapterConfig">
                <xs:sequence>
                    <xs:element name="message" type="xs:string"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    
  4. Define a top-level element that must be named config.

    In the definition of the config element, define a sequence of child elements that correspond to the components in your application. Typically the name of the elements should indicate what component they configure (adapter, processor, channel) although you can name then anything you want.

    Each element must extend the ConfigurationObject XML type, either explicitly using the xs:extension element with base attribute value base:ConfigurationObject or by specifying an XML type that itself extends ConfigurationObject. The ConfigurationObject XML type, defined in wlevs_base_config.xsd, defines a single attribute: name.

    The type of your adapter element should be the custom one you created in a preceding step of this procedure.

    You can use the following built-in XML types that wlevs_application_config.xsd describes, for the child elements of config that correspond to processors or streams:

    For example:

    <xs:element name="config">
      <xs:complexType>
        <xs:choice maxOccurs="unbounded">
          <xs:element name="adapter" type="HelloWorldAdapterConfig"/>
            <xs:element name="processor" type="wlevs:DefaultProcessorConfig"/>
        </xs:choice>
      </xs:complexType>
    </xs:element>
    
  5. Optionally use the jxb:package child element of jxb:schemaBindings to specify the package name of the generated Java code:

    <xs:annotation>
      <xs:appinfo>
         <jxb:schemaBindings>
             <jxb:package name="com.bea.adapter.wlevs.example.helloworld"/>
         </jxb:schemaBindings>
      </xs:appinfo>
    </xs:annotation> 
    

8.9.2 Complete Example of an Extended XSD Schema File

Use the following extended XSD file as a template:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.bea.com/xml/ns/wlevs/example/helloworld"
        xmlns="http://www.bea.com/xml/ns/wlevs/example/helloworld"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
        xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
        xmlns:wlevs="http://www.bea.com/xml/ns/wlevs/config/application"
        jxb:extensionBindingPrefixes="xjc" jxb:version="1.0"
        elementFormDefault="unqualified" attributeFormDefault="unqualified">
        <xs:annotation>
                <xs:appinfo>
                        <jxb:schemaBindings>
                                <jxb:package name="com.bea.adapter.wlevs.example.helloworld"/>
                        </jxb:schemaBindings>
                </xs:appinfo>
        </xs:annotation>
        <xs:import namespace="http://www.bea.com/xml/ns/wlevs/config/application"
                schemaLocation="wlevs_application_config.xsd"/>
        <xs:element name="config">
                <xs:complexType>
                        <xs:choice maxOccurs="unbounded">
                                <xs:element name="adapter" type="HelloWorldAdapterConfig"/>
                                <xs:element name="processor" type="wlevs:DefaultProcessorConfig"/>
                                <xs:element name="channel" type="wlevs:DefaultStreamConfig"/>
                         </xs:choice>
                </xs:complexType>
        </xs:element>
        <xs:complexType name="HelloWorldAdapterConfig">
                <xs:complexContent>
                        <xs:extension base="wlevs:AdapterConfig">
                                <xs:sequence>
                                        <xs:element name="message" type="xs:string"/>
                                </xs:sequence>
                        </xs:extension>
                </xs:complexContent>
        </xs:complexType>
</xs:schema>

8.9.3 Programming Access to the Configuration of an Adapter or Event Bean

This section applies to both adapters and event beans. For simplicity the text mentions only adapters.

When you deploy your application, Oracle CEP maps the configuration of each component (specified in the component configuration XML files) into Java objects using the Java Architecture for XML Binding (JAXB) standard (for more information, see https://jaxb.dev.java.net/). Because there is a single XML element that contains the configuration data for each component, JAXB in turn also produces a single Java class that represents this configuration data. Oracle CEP passes an instance of this Java class to the component (processor, channel, or adapter) at runtime when the component is initialized, and also whenever there is a dynamic change to the component's configuration.

In your adapter implementation, you can use metadata annotations to specify the Java methods that are invoked by Oracle CEP at runtime. Oracle CEP passes an instance of the configuration Java class to the specified methods; you can then program these methods to get specific runtime configuration information about the adapter. The following example shows how to annotate the activateAdapter() method with the @Activate annotation to specify the method invoked when the adapter configuration is first activated:

@Activate
public void activateAdapter(HelloWorldAdapterConfig adapterConfig) {
    this.message = adapterConfig.getMessage();
}

By default, the date type of the adapter configuration Java class is com.bea.wlevs.configuration.application.DefaultAdapterConfig. If, however, you have extended the configuration of your adapter by creating your own XSD file that describes the configuration XMLfile, then you specify the type in the XSD file. In the preceding example, the data type of the Java configuration object is com.bea.wlevs.example.helloworld.HelloWorldAdapterConfig.

The metadata annotations provided are as follows:

8.10 Passing Login Credentials from an Adapter to the Data Feed Provider

If your adapter accesses an external data feed, the adapter might need to pass login credentials (username and password) to the data feed for user authentication.

The simplest, and least secure, way to do this is to hard-code the non-encrypted login credentials in your adapter Java code. However, this method does not allow you to encrypt the password or later change the login credentials without recompiling the adapter Java code.

The following procedures describe a different method that takes these two issues into account. In the procedure, it is assumed that the username to access the data feed is juliet and the password is superSecret.

You must decide whether you want the login credentials to be configured statically in the EPN assembly file, or dynamically by extending the configuration of the adapter. Configuring the credentials statically in the EPN assembly file is easier, but if the credentials later change you must restart the application for the update to the EPN assembly file to take place. Extending the adapter configuration allows you to change the credentials dynamically without restarting the application, but extending the configuration involves additional steps, such as creating an XSD file and compiling it into a JAXB object.

This section describes:

8.10.1 How to Pass Static Login Credentials from an Adapter to the Data Feed Provider

This procedure describes how to pass login credentials that you configure statically in the EPN assembly file.

To pass static credentials from an adapter to the data feed provider:

  1. Open a command window and set your environment as described in "Setting Your Development Environment" in the Oracle CEP Getting Started.

  2. Change to the directory that contains the EPN assembly file for your application.

  3. Using your favorite XML editor, edit the EPN assembly file by updating the wlevs:adapter element that declares your adapter.

    In particular, add two instance properties that correspond to the username and password of the login credentials. For now, specify the cleartext password value; you will encrypt it in a later step. Also add a temporary password element whose value is the cleartext password. For example:

    <wlevs:adapter id="myAdapter" provider="myProvider">
      <wlevs:instance-property name="user" value="juliet"/>
      <wlevs:instance-property name="password" value="superSecret"/>
      <password>superSecret</password>
    </wlevs:adapter>
    
  4. Save the EPN assembly file.

  5. Use the encryptMSAConfig command to encrypt the value of the password element in the EPN assembly file:

    prompt> ORACLE_CEP_HOME/ocep_11.1/bin/encryptMSAConfig . epn_assembly_file msainternal.dat_file
    

    where ORACLE_CEP_HOME refers to the main directory into which you installed Oracle CEP, such as d:\oracle_cep. The second argument refers to the directory that contains the EPN assembly file; because this procedure directs you to change to the directory, the example shows ".". The epn_assembly_file parameter refers to the name of your EPN assembly file. Finally, the msainternal.dat_file parameter refers to the location of the .msainternal.dat file associated with your domain; by default this file is located in the DOMAIN_DIR/servername directory, where DOMAIN_DIR refers to the domain directory such as /oracle_cep/user_projects/domains/mydomain and servername refers to the server instance.

    For more information, see "The encryptMSAConfig Command-Line Utility" in the Oracle CEP Administrator's Guide.

    After you run the command, the value of the password element of the EPN assembly file will be encrypted.

  6. Edit the EPN assembly file:

    Copy the encrypted value of the password element to the value attribute of the password instance property.

    Remove the password element from the XML file.

    For example:

    <wlevs:adapter id="myAdapter" provider="myProvider">
        <wlevs:instance-property name="user" value="juliet"/>
        <wlevs:instance-property name="password"
            value="{Salted-3DES}B7L6nehu7dgPtJJTnTJWRA=="/>
    </wlevs:adapter>
    
  7. Update your adapter Java code to access the login credentials properties you have just configured and decrypt the password.

    See Section 8.10.1, "How to Pass Static Login Credentials from an Adapter to the Data Feed Provider."

  8. Edit the MANIFEST.MF file of the application and add the com.bea.core.encryption package to the Import-Package header. See Section 14.2.2.1, "Creating the MANIFEST.MF File."

  9. Re-assemble and deploy your application as usual. See Chapter 14, "Assembling and Deploying Oracle CEP Applications."

8.10.2 How to Pass Dynamic Login Credentials from an Adapter to the Data Feed Provider

This procedure describes how to pass login credentials that you configure dynamically by extending the configuration of the adapter.

To pass dynamic login credentials from an adapter to the data feed provider:

  1. Extend the configuration of your adapter by adding two new elements: user and password, both of type string.

    For example, if you were extending the adapter in the HelloWorld example, the XSD file might look like the following:

    <xs:complexType name="HelloWorldAdapterConfig">
       <xs:complexContent>
         <xs:extension base="wlevs:AdapterConfig">
           <xs:sequence>
             <xs:element name="message" type="xs:string"/>
             <xs:element name="user" type="xs:string"/>
             <xs:element name="password" type="xs:string"/>
           </xs:sequence>
         </xs:extension>
       </xs:complexContent>
    </xs:complexType>
    

    See Section 8.9, "Extending the Configuration of an Adapter or Event Bean" for detailed instructions.

  2. Open a command window and set your environment as described in "Setting Your Development Environment" in the Oracle CEP Getting Started.

  3. Change to the directory that contains the component configuration XML file for your adapter.

  4. Using your favorite XML editor, update this component configuration XML file by adding the required login credentials using the <user> and <password> elements. For now, specify the cleartext password value; you will encrypt it in a later step. For example:

    <?xml version="1.0" encoding="UTF-8"?>
    <myExample:config
      xmlns:myExample="http://www.bea.com/xml/ns/wlevs/example/myExample">
      <adapter>
        <name>myAdapter</name>
        <user>juliet</user>
        <password>superSecret</password>
      </adapter>
    </myExample:config>
    
  5. Save the adapter configuration file.

  6. Use the encryptMSAConfig command to encrypt the value the password element in the adapter configuration file:

    prompt> ORACLE_CEP_HOME/ocep_11.1/bin/encryptMSAConfig . adapter_config_file msainternal.dat_file
    

    where ORACLE_CEP_HOME refers to the main directory into which you installed Oracle CEP, such as d:\oracle_cep. The second argument refers to the directory that contains the adapter configuration file; because this procedure directs you to change to the directory, the example shows ".". The adapter_config_file parameter refers to the name of your adapter configuration file. Finally, the msainternal.dat_file parameter refers to the location of the .msainternal.dat file associated with your domain; by default this file is located in the DOMAIN_DIR/servername directory, where DOMAIN_DIR refers to the domain directory such as /oracle_cep/user_projects/domains/mydomain and servername refers to the server instance.

    For more information, see "The encryptMSAConfig Command-Line Utility" in the Oracle CEP Administrator's Guide.

    After you run the command, the value of the password element will be encrypted.

  7. Update your adapter Java code to access the login credentials properties you have just configured and decrypt the password.

    See Section 8.10.1, "How to Pass Static Login Credentials from an Adapter to the Data Feed Provider."

  8. Edit the MANIFEST.MF file of the application and add the com.bea.core.encryption package to the Import-Package header. See Section 14.2.2.1, "Creating the MANIFEST.MF File."

  9. Re-assemble and deploy your application as usual. See Chapter 14, "Assembling and Deploying Oracle CEP Applications."

8.10.3 Updating the Adapter Code to Access the Login Credential Properties

This section describes how update your adapter Java code to dynamically get the user and password values from the extended adapter configuration, and then use the com.bea.core.encryption.EncryptionService API to decrypt the encrypted password.

The code snippets below build on the HelloWorld adapter Java code, shown in Section 8.3, "Implementing an Adapter or Event Bean as an Event Source."

  • Import the additional APIs that you will need to decrypt the encrypted password:

    import com.bea.core.encryption.EncryptionService;
    import com.bea.core.encryption.EncryptionServiceException;
    import com.bea.wlevs.util.Service;
    
  • Use the @Service annotation to get a reference to the EncryptionService:

    private EncryptionService encryptionService;
    ...
    @Service
    public void setEncryptionService(EncryptionService encryptionService) {
        this.encryptionService = encryptionService;
    }
    
  • In the @Prepare callback method, get the values of the user and password properties of the extended adapter configuration as usual (only code for the password value is shown):

    private String password;
    ...
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    ...
    @Prepare
    public void checkConfiguration(HelloWorldAdapterConfig adapterConfig) {
        if (adapterConfig.getMessage() == null
                || adapterConfig.getMessage().length() == 0) {
            throw new RuntimeException("invalid message: " + message);
        }
        this.password= adapterConfig.getPassword();
        ...
    }
    

    See Section 8.9.3, "Programming Access to the Configuration of an Adapter or Event Bean" for information about accessing the extended adapter configuration.

  • Use the EncryptionService.decryptStringAsCharArray() method in the @Prepare callback method to decrypt the encrypted password:

    @Prepare
    public void checkConfiguration(HelloWorldAdapterConfig adapterConfig) {
        if (adapterConfig.getMessage() == null
                || adapterConfig.getMessage().length() == 0) {
            throw new RuntimeException("invalid message: " + message);
        }
        this.password= adapterConfig.getPassword();
        try {
            char[] decrypted = encryptionService.decryptStringAsCharArray(password);
            System.out.println("DECRYPTED PASSWORD is "+ new String(decrypted));
        } catch (EncryptionServiceException e) {
            throw new RuntimeException(e);
        }
    }
    

    The signature of the decryptStringAsCharArray() method is as follows:

    char[] decryptStringAsCharArray(String encryptedString)
                                    throws EncryptionServiceException
    
  • Pass these credentials to the data feed provider using the vendor API.

8.11 Assembling an Adapter or Event Bean in Its Own Bundle

This section applies to both adapters and event beans. For simplicity the text mentions only adapters.

In the procedure described in Section 8.2, "Implementing an Adapter or Event Bean," it is assumed that the adapter and adapter factory are bundled in the same application JAR file that contains the other components of the event network, such as the processor, streams, and business logic POJO.

However, you might sometimes want to bundle the adapter in its own JAR file and then reference the adapter in other application bundles. This is useful if, for example, two different applications read data coming from the same data feed provider and both applications use the same event types. In this case, it makes sense to share a single adapter and event type implementations rather than duplicate the implementation in two different applications.

There is no real difference in how you configure an adapter and an application that uses it in separate bundles; the difference lies in where you put the configuration, as described in the following guidelines: