15 Integrating an External Component Using a Custom Adapter

This chapter describes how to implement and configure your own Oracle Event Processing adapters for sending and receiving event data between your application and external components, including how to pass login credentials from an adapter.

You can develop adapters to exchange event data with external components that aren't supported by the adapters included with Oracle Event Processing. For more information about included adapters, see Chapter 11, "Integrating the Java Message Service", Chapter 12, "Integrating an HTTP Publish-Subscribe Server", and Chapter 21, "Testing Applications With the Load Generator and csvgen Adapter".

This chapter includes the following sections:

15.1 Overview of Custom Adapters

You can develop custom adapters to exchange event data with external components that aren't supported by adapters included with Oracle Event Processing.

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.

  • Use messaging systems, such as TIBCO Rendezvous.

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

Adapters you build are likely to go at the beginning of an EPN, where they receive data, or at the end of an EPN, where they send event data elsewhere.

With a custom adapter, you can:

  • Receive raw event data from an external component, then convert the data into event type instances that your application can use to process the events. If necessary, your implementation can authenticate itself with the external component.

    One of the main roles of an adapter is to convert incoming data, such as a market data feed, into Oracle Event Processing events. These events are then passed to other components in the EPN.

  • Receive event type instances from within the event processing network, then convert the data to a form that's consumable by an external component. As the exit point of an application, an adapter receives events from another stage in the EPN, converts the event's data into something that an external application can read, and then sends it out.

You implement an adapter by creating an adapter class in Java. An adapter class implements Oracle Event Processing interfaces through which it can create, send, or receive events. For more information, see Section 15.2, "Implementing a Custom Adapter".

You add the adapter to the EPN by configuring it in the EPN assembly file. You can further specify runtime-editable configuration settings by configuring the adapter in a component configuration file. For more information, see Section 15.5, "Configuring a Custom Adapter".

The samples in the following list include source and sink example code

  • The Foreign Exchange (FX) sample includes three adapters that read 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. For more information, see Section 2.8, "Foreign Exchange (FX) Example".

  • The Oracle Spatial sample includes an adapter that reads data from a file and creates event type instances from the data. For more information, see Section 2.7, "Oracle Spatial Example".

15.2 Implementing a Custom Adapter

You implement a custom adapter by writing Java code that can communicate with the external component you're integrating. An adapter class implementation also includes code to receive or send event type instances, depending on where in an EPN the adapter is intended to go.

The implementation will likely use several classes from the Oracle Event Processing API. For Javadoc reference on those, see the Oracle Fusion Middleware Java API Reference for Oracle Event Processing. For example code, see Example 15-1, "High-Level View of Input Adapter Class".

The following lists the high-level steps you might typically take when creating a custom adapter:

  1. Implement a Java class that can communicate with the external component for which the adapter is intended. Of course, the specifics of your code will depend heavily on how the external component sends or receives the data your adapter is handling.

  2. If the adapter will support being suspended and resumed (for example, when it is undeployed and deployed), you can implement interfaces to handle these events. For more information, see Section 15.3.2, "Suspending and Resuming Adapter Event Processing".

  3. You might want be able to improve the application's scalability with finer control over adapter threading. For more information, see Section 15.3.1, "Improving Scalability with Multi-Threaded Adapters".

  4. In your Java code, implement the interfaces needed to support sending or receiving event type instances.

  5. If your custom adapter must authenticate itself with a data feed provider, as it might if it will be an input adapter, write Java logic to pass login credentials to the component providing event data. For more information, see Section 15.4, "Passing Login Credentials from an Adapter to a Data Feed Provider."

  6. Optionally create a factory class. You need to do this only if multiple applications are going to use instances of the custom adapter. For more information, see Section 15.6, "Creating a Custom Adapter Factory."

    If you want to bundle the custom adapter in its own JAR file so that it can be shared among multiple applications, see Section 23.2.4.1, "How to Assemble a Custom Adapter in its Own Bundle."

  7. Add the adapter to an event processing network by configuring it in an EPN assembly file. For more information, see Section 15.5, "Configuring a Custom Adapter."

15.2.1 Example: Input Adapter Implementation

This section provides a high-level illustration of an input adapter that retrieves raw event data from a file, converts the data into events, then sends the events to a downstream stage in the EPN.

The code here is excerpted from the Oracle Spatial sample application. Be sure to see its source code for the full implementation. For more information, see Section 2.7, "Oracle Spatial Example".

Example 15-1, "High-Level View of Input Adapter Class" is not a real-world scenario, but it does illustrate a basic flow for an input adapter. The following provides an overview of the work done by this class:

  • Through dependency injection, this class is injected with instances of classes with which it will do some of its work, including:

    • An EventTypeRepository instance (injected with the setEventTypeRepository method) with which to retrieve an instance of the event type specified in the adapter's configuration.

    • A StreamSender instance (injected with the setEventSender method) with which to send events it generates.

  • Through the setPath and setEventType methods, the class is injected with property values specified in the adapter's EPN assembly file configuration.

  • In implementing the RunnableBean interface, this class provides a run() method implementation that does the adapter's real work: retrieving raw event data, parsing the data into event type instances, and sending the new events to a downstream EPN stage.

Example 15-1 High-Level View of Input Adapter Class

package com.oracle.cep.sample.spatial;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.bea.wlevs.ede.api.EventProperty;
import com.bea.wlevs.ede.api.EventRejectedException;
import com.bea.wlevs.ede.api.EventType;
import com.bea.wlevs.ede.api.EventTypeRepository;
import com.bea.wlevs.ede.api.RunnableBean;
import com.bea.wlevs.ede.api.StreamSender;
import com.bea.wlevs.ede.api.StreamSink;
import com.bea.wlevs.ede.api.StreamSource;
import com.bea.wlevs.util.Service;
import java.lang.RuntimeException;

public class BusStopAdapter implements RunnableBean, StreamSource, StreamSink
{
    static final Log s_logger = 
        LogFactory.getLog("BusStopAdapter");

    private String m_filePath;
    private String m_eventTypeName;
    private EventType m_eventType;
    private StreamSender m_eventSender;
    private boolean m_stopped;

    private int m_repeat = 1;
    private EventTypeRepository m_etr = null;

    public BusStopAdapter()
    {
        super();
    }

    /**
     * Called by the server to pass in the path 
     * to the file with bus stop data.
     * 
     * @param path The value specified for the path
     * property in the adapter's configuration 
     * in the EPN assembly file.
     */
    public void setPath(String path) throws RuntimeException
    {
        // Code to create a File instance from the path. This
        // File object will be used to retrieve event data 
        // from the file.
    }
    
    /**
     * Called by the server to pass in the name of the event 
     * type to which event data should be bound.
     * 
     * @param path The value specified for the path
     * property in the adapter's configuration 
     * in the EPN assembly file.
     */
    public void setEventType(String typ)
    {
        m_eventTypeName = typ;
    }

    /**
     * Called by the server to set an event type 
     * repository instance that knows about event 
     * types configured for this application.
     * 
     * This repository instance will be used to retrieve an 
     * event type instance that will be populated 
     * with event data retrieved from the event data file.
     * 
     * @param etr The event repository.
     */
    @Service(filter = EventTypeRepository.SERVICE_FILTER)
    public void setEventTypeRepository(EventTypeRepository etr)
    {
        m_etr = etr;
    }

    /**
     * Executes to retrieve raw event data and 
     * create event type instances from it, then
     * sends the events to the next stage in the
     * EPN.
     * 
     * This method, implemented from the RunnableBean
     * interface, executes when this adapter instance
     * is active.
     */
    public void run()
    {
        if (m_etr == null)
        {
            throw new RuntimeException("EventTypeRepository is not set");
        }

        // Get the event type from the repository by using
        // the event type name specified as a property of
        // this adapter in the EPN assembly file.
        m_eventType = m_etr.getEventType(m_eventTypeName);        
        if (m_eventType == null)
        {
            throw new RuntimeException("EventType(" + 
                m_eventType + ") is not found.");
        }

        BufferedReader reader = null;

        System.out.println("Sending " + m_eventType + 
                " from " + m_filePath);
        while ((m_repeat != 0) && (!m_stopped))
        {
            try
            {
                reader = new BufferedReader(new FileReader(m_filePath));
            } catch (Exception e)
            {
                m_stopped = true;
                break;
            }
            while (!isStopped())
            {
                try
                {
                    // Create an object and assign to it 
                    // an event type instance generated 
                    // from event data retrieved by the 
                    // reader.
                    Object ev = null;
                    ev = readLine(reader);
                    if (ev == null)
                    {
                        reader.close();
                        break;
                    }
                    
                    // Send the newly created event type instance 
                    // to a downstream stage that is 
                    // listening to this adapter.
                    m_eventSender.sendInsertEvent(ev);
                    
                } catch (Exception e)
                {
                    m_stopped = true;
                    break;
                }
            }
        }
    }


    /**
     * Called by the server to pass in a 
     * sender instance that will be used to
     * send generated events to a downstream
     * stage.
     * 
     * @param sender A sender instance.
     */
    public void setEventSender(StreamSender sender)
    {
        m_eventSender = sender;
    }

    /**
     * Returns true if this adapter instance has
     * been suspended, such as because an exception
     * occurred.
     */
    private synchronized boolean isStopped()
    {
        return m_stopped;
    }

    /**
     * Reads data from reader, creating event type
     * instances from that data. This method is 
     * called from the run() method.
     * 
     * @param reader Raw event data from a file.
     * @return An instance of the event type specified
     * as a property of this adapter.
     */
    protected Object readLine(BufferedReader reader) throws Exception
    {
        // Code to read raw event data and return an event type
        // instance from it.
    }

    /**
     * Called by the server to pass in an
     * insert event received from an 
     * upstream stage in the EPN.
     */
    @Override
    public void onInsertEvent(Object event) throws EventRejectedException
    {
        // Code to begin executing the logic needed to 
        // convert incoming event data to event type instances.
    }
}

15.3 Implementing Support for Thread and Work Management

You can improve how your adapter's work is managed by implementing or configuring specific threading and work characteristics.

To improve scalability, for example, you might want to configure the adapter to be multi-threaded. To execute logic that responds well when the EPN is suspended or resumed, you can implement interfaces available in the Oracle Event Processing API.

For more information, see the following sections:

15.3.1 Improving Scalability with Multi-Threaded Adapters

You can implement or configure an adapter to use one or more threads for reading from its data source. For example, a multi-threaded adapter might improve performance if its event-processing work is expensive.

Note that when an adapter is single-threaded, event order is guaranteed. Event order is not guaranteed in a multi-threaded adapter.

The simplest way to manage threading is to configure the adapter with a work manager. A work manager is a server feature through which your application can prioritize the execution of its work. You can specify a dedicated work manager used only by the adapter or you can share a work manager among several components such as other adapters.

For more information, see:

You can also create a single-threaded adapter by implementing the com.bea.wlevs.ede.api.RunnableBean interface. In your implementation of its run() method, you put the code that reads incoming data, converts it into Oracle Event Processing event type instances, and then send the events to the next stage in the EPN. For reference information on this interface, see the Oracle Fusion Middleware Java API Reference for Oracle Event Processing.

15.3.2 Suspending and Resuming Adapter Event Processing

You can implement your adapter's Java class so that the adapter supports having its work be suspended or resumed by the server. For example, when an event processing network that the adapter part of is suspended, you might want the adapter to stop processing events. When the EPN's work is resumed, other code in the adapter can resume processing events. Supporting these cases might also mean managing resources that the adapter acquires in order to do its work.

To support being suspended or resumed, an adapter implements interfaces in the Oracle Event Processing API. These include the interfaces described in Table 15-1, "Interfaces to Support Suspending and Resuming an Adapter":

Table 15-1 Interfaces to Support Suspending and Resuming an Adapter

Interface Description

com.bea.wlevs.ede.api.SuspendableBean

Implement this to provide logic that executes when the EPN is suspended. The interface's suspend method, you might suspend resources or stop processing events.

com.bea.wlevs.ede.api.ResumeableBean

Implement this to provide logic that executes when the EPN resumes work. In your implementation of the beforeResume method, you can provide code that should execute before the adapter's work resumes.


For reference information on these interfaces, see the Oracle Fusion Middleware Java API Reference for Oracle Event Processing.

15.4 Passing Login Credentials from an Adapter to a Data Feed Provider

If your adapter accesses an external data feed, the adapter might need to pass login credentials, such as a 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 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 first 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 an 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:

For more information, see Chapter 26, "Extending Component Configuration".

15.4.1 How to Pass Static Login Credentials to the Data Feed Provider

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

To pass static credentials to the data feed provider

  1. Open a command window and set your environment as described in Section 3.2, "Setting Your Development Environment."

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

  3. Edit the EPN assembly XML 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. In the command prompt, 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 aesinternal.dat_file
    

    This command includes the following parts:

    • ORACLE_CEP_HOME refers to the main directory into which you installed Oracle Event Processing, 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 aesinternal.dat_file parameter refers to the location of the .aesinternal.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 Fusion Middleware Administrator's Guide for Oracle Event Processing.

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

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

    See Section 15.4.3, "How to Access Login Credentials From an Adapter at Runtime."

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

  8. Re-assemble and deploy your application as usual. See Chapter 23, "Assembling and Deploying Oracle Event Processing Applications."

15.4.2 How to Pass Dynamic Login Credentials to the Data Feed Provider

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

To pass dynamic login credentials 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 Chapter 26, "Extending Component Configuration" for detailed instructions.

  2. Open a command window and set your environment as described in Section 3.2, "Setting Your Development Environment."

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

  4. Update this component configuration XML file by adding the required login credentials using the <user> and <password> elements you defined in the configuration extension. 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 of the password element in the adapter configuration file:

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

    This command includes the following parts:

    • ORACLE_CEP_HOME refers to the main directory into which you installed Oracle Event Processing, 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 aesinternal.dat_file parameter refers to the location of the .aesinternal.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 Fusion Middleware Administrator's Guide for Oracle Event Processing.

    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 15.4.3, "How to Access Login Credentials From an Adapter at Runtime."

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

  9. Re-assemble and deploy your application as usual. See Chapter 23, "Assembling and Deploying Oracle Event Processing Applications."

15.4.3 How to Access Login Credentials From an Adapter at Runtime

This section describes how update your custom 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.

To access login credential properties from an adapter at runtime:

  1. 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;
    
  2. Use the @Service annotation to get a reference to the EncryptionService:

    private EncryptionService encryptionService;
    
    @Service
    public void setEncryptionService(EncryptionService encryptionService) {
        this.encryptionService = encryptionService;
    }
    
  3. 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 26.3, "Programming Access to the Configuration of a Custom Adapter or Event Bean" for information about accessing the extended adapter configuration.

  4. 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
    
  5. Pass these credentials to the data feed provider using the vendor API.

15.5 Configuring a Custom Adapter

When you create a custom adapter, you can add it to an EPN by configuring it in the EPN assembly file. You can also add adapter configuration to a component configuration file to support runtime configuration changes to certain features.

For more information, see the following sections:

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

15.5.1 Configuring a Custom Adapter in an EPN Assembly File

In the EPN assembly file, you use the wlevs:adapter element to declare an adapter as a component in the event processor network. Note that the configuration code will differ for event beans created from a factory. For more information, see Section 15.6, "Creating a Custom Adapter Factory".

Note:

The simplest way to create a custom adapter is using the Oracle Event Processing IDE for Eclipse adapter wizard. For more information, see Section 7.4.1.2, "How to Create an Adapter Node".

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

In the following example, the BusStopAdapter class is configured as an adapter to set properties implemented as methods in the class (setPath, setEventType, and setBuffer):

<wlevs:adapter id="BusStopAdapter" 
    class="com.oracle.cep.sample.spatial.BusStopAdapter" >
    <wlevs:instance-property name="path" value="bus_stops.csv"/>
    <wlevs:instance-property name="eventType" value="BusStop"/>
    <wlevs:instance-property name="buffer" value="30.0"/>
</wlevs:adapter>

You reference an adapter that is an event sink by using the wlevs:listener element. In the following example, a BusPositionGen CSV adapter sends events to the BusStopAdapter:

<wlevs:adapter id="BusPositionGen" provider="csvgen">
    <!-- Code omitted -->
    <wlevs:listener ref="BusStopAdapter"/>
</wlevs:adapter>

15.5.2 Configuring a Custom Adapter in a Component Configuration File

You can add configuration for an adapter in a component configuration file. Configuration you add here is available to be updated at runtime. Adding configuration in a component configuration file assumes that you have added the adapter to the EPN by configuring it in the EPN assembly file (see Section 15.5.1, "Configuring a Custom Adapter in an EPN Assembly File" for more information).

You can also create a separate component configuration XML file as needed according to your development environment. For example, if your application has more than one custom event bean, you can create separate XML files for each, or create a single XML file that contains the configuration for all custom event beans, or even all components of your application (beans, adapters, processors, and streams).

In the following example, a BusStopAdapter adapter is configured for event recording. Each adapter configuration should have a separate adapter child element of the config element.

<?xml version="1.0" encoding="UTF-8"?>
<wlevs:config 
    xmlns:wlevs="http://www.bea.com/ns/wlevs/config/application">
    <adapter>
        <name>BusStopAdapter</name>
        <record-parameters>
            <dataset-name>spatial_sample</dataset-name>
            <event-type-list>
                <event-type>BusPos</event-type>
                <event-type>BusStop</event-type>
                <event-type>BusPosEvent</event-type>
                <event-type>BusStopArrivalEvent</event-type>
                <event-type>BusStopPubEvent</event-type>
                <event-type>BusStopPubEvent</event-type>
            </event-type-list>
            <batch-size>1</batch-size>
            <batch-time-out>10</batch-time-out>
        </record-parameters>
    </event-bean>
</wlevs: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 Event Processing knows to which particular custom adapter component in the EPN assembly file this configuration applies.

You can also extend component configuration with your own elements. For more information, see Section 26, "Extending Component Configuration".

For more information, see:

15.6 Creating a Custom Adapter Factory

You can use a single adapter implementation in multiple event processing networks by implementing and configuring an adapter factory. The factory class provides adapter instances for the applications that request one.

For detail on the APIs described here, see the Oracle Fusion Middleware Java API Reference for Oracle Event Processing.

Creating an adapter factory involves the following steps:

  1. In your adapter class, implement the com.bea.wlevs.ede.api.Adapter interface so that the adapter can be returned by the factory. This is a marker interface, so there are no methods to implement.

    public class BusStopAdapter implements Adapter, StreamSource {
        // Adapter implementation code.
    }
    
  2. Implement an adapter factory class to create and return instances of the adapter.

    Your adapter factory class must implement the com.bea.wlevs.ede.api.AdapterFactory interface. In your implementation of its create method, create an instance of your adapter.

    import com.oracle.cep.sample.spatial.BusStopAdapter;
    import com.bea.wlevs.ede.api.AdapterFactory;
    
    public class BusStopAdapterFactory implements AdapterFactory {
        public BusStopAdapterFactory() {}
        public synchronized BusStopAdapter create() 
            throws IllegalArgumentException {
    
            // Your code might have a particular way to create the instance.
            return new BusStopAdapter();
    
        }
    }
    
  3. In an EPN assembly file, configure the factory class.

    You register factories in the EPN assembly file using the wlevs:factory element, as shown in the following example:

    <wlevs:factory provider-name="busStopAdapterProvider" 
        class="com.oracle.cep.sample.spatial.BusStopAdapterFactory"/>
    

    If you need to specify service properties, then you must also 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 all of Oracle Event Processing. 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 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 your specific adapter class in the Spring application context.

    <osgi:service interface="com.bea.wlevs.ede.api.AdapterFactory">
        <osgi:service-properties>
            <entry key="type" value="busStopAdapterProvider"</entry>
        </osgi:service-properties>
        <bean class="com.oracle.cep.sample.spatial.BusStopAdapterFactory" />
    </osgi:service>
    
  4. In applications that will use instances of the adapter, configure the adapter by specifying the configured factory as a provider (rather than specifying the adapter by its class name), as shown in the following example:

    <wlevs:adapter id="BusStopAdapter"
        provider="busStopAdapterProvider">
        // ...
    </wlevs:adapter>