12 Configuring Caching

This section contains information on the following subjects:

12.1 Overview of Oracle CEP Cache Configuration

A cache is a temporary storage area for events, created exclusively to improve the overall performance of your Oracle CEP application; it is not necessary for the application to function correctly. Oracle CEP applications can optionally publish or consume events to and from a cache to increase the availability of the events and increase the performance of their applications.

A caching system refers to a configured instance of a caching implementation. A caching system defines a named set of configured caches as well as the configuration for remote communication if any of the caches are distributed across multiple machines.

Oracle CEP supports the following caching systems:

  • Oracle CEP local cache: a local, in-memory single-JVM cache.

  • Oracle Coherence: a JCache-compliant in-memory distributed data grid solution for clustered applications and application servers. It coordinates updates to the data using cluster-wide concurrency control, replicates data modifications across the cluster using the highest performing clustered protocol available, and delivers notifications of data modifications to any servers that request them. You take advantage of Oracle Coherence features using the standard Java collections API to access and modify data, and use the standard JavaBean event model to receive data change notifications.

    Note:

    Before you can use Oracle CEP with Oracle Coherence, you must obtain a valid Oracle Coherence license such as a license for Coherence Enterprise Edition, Coherence Grid Edition, or Oracle WebLogic Application Grid. For more information on Oracle Coherence, see http://www.oracle.com/technology/products/coherence/index.html.
  • Third-party caches: you can create a plug-in to allow Oracle CEP to work with other, third-party cache implementations.

A cache can be considered a stage in the event processing network in which an external element (the cache) consumes or produces events; this is similar to an adapter that uses a JMS destination. A cache, however, does not have to be an actual stage in the network; another component or Spring bean can access a cache programmatically using the caching APIs.

A caching system is always configured at the application level. Other Oracle CEP applications in separate bundles can also use the caching system.

For each caching system in your application, you must create a caching-system element in a component configuration file. In this caching-system element you specify the caching system name and one or more cache elements. In the cache elements, you define optional cache configuration such as:

  • Maximum cache size

  • Eviction policy

  • Time-to-live

  • Idle time

  • Write policy (write-none, write-through, or write-behind)

  • Work manager

The component configuration file caching-system element's name element must match the EPN assembly file caching-system element's id attribute. For example, given the EPN assembly file caching-system element shown in Example 12-1, the corresponding component configuration file caching-system element is shown in Example 12-2.

Example 12-1 EPN Assembly File Caching System Id: cacheSystem

<wlevs:caching-system id="cacheSystem">
    ...
</wlevs:caching-system>

<wlevs:cache id="cache1">
    <wlevs:caching-system ref="cacheSystem"/>
</wlevs:cache>

Example 12-2 Component Configuration File Caching System Name: cacheSystem

<caching-system>
    <name>cacheSystem</name>
    <cache>
        <name>cache1</name>
        ...
    </cache>
</caching-system>

Similarly, the component configuration file cache element's name element must match the EPN assembly file cache element's id attribute. For example, given the EPN assembly file cache element shown in Example 12-1, the corresponding component configuration file cache element is shown in Example 12-2.

Example 12-3 EPN Assembly File Caching Id: cache1

<wlevs:caching-system id="cacheSystem">
    ...
</wlevs:caching-system>

<wlevs:cache id="cache1">
    <wlevs:caching-system ref="cacheSystem"/>
</wlevs:cache>

Example 12-4 Component Configuration File Caching Name: cache1

<caching-system>
    <name>cacheSystem</name>
    <cache>
        <name>cache1</name>
        ...
    </cache>
</caching-system>

You can create a caching-system element in any of the following component configuration files:

  • The default Oracle CEP application configuration file (by default, META-INF/wlevs/config.xml).

  • A separate configuration file.

If your application has more than one caching system, you can create a caching-system element for each of them in the default config.xml file, you can create separate XML files in META-INF/wlevs for each, or create a single XML file in META-INF/wlevs that contains the configuration for all caching systems, or even all components of your application (adapters, processors, and channels). Choose the method that best suits your development environment.

By default, Oracle CEP IDE for Eclipse creates one component configuration file and one EPN assembly file. When you add a cache to the EPN using Oracle CEP IDE for Eclipse, it adds a cache element to the EPN assembly file. You must manually add caching-system elements to the EPN assembly file and component configuration file.

Component configuration files are deployed as part of the Oracle CEP application bundle. You can later update this configuration at runtime using Oracle CEP Visualizer, the wlevs.Admin utility, or manipulating the appropriate JMX Mbeans directly.

For more information, see:

For more information on configuring caching, see:

12.1.1 Caching Use Cases

The following sections describe the principal Oracle CEP caching use cases.

12.1.1.1 Use Case: Publishing Events to a Cache

An example of this use case is a financial application that publishes events to a cache while the financial market is open and then processes data in the cache after the market closes.

Publishing events to a cache makes them highly available or available to other Oracle CEP applications running in the server. Publishing events to a cache also allows for asynchronous writes to a secondary storage by the cache implementation. You can configure any stage in an Oracle CEP application that generates events (input adapter, channel, business POJO, or processor) to publish its events to the cache.

12.1.1.2 Use Case: Consuming Data From a Cache

Oracle CEP applications may sometimes need to access non-streaming data in order to do its work; caching this data can increase the performance of the application.

The standard components of an Oracle CEP application that are allowed direct programming access to a cache are input- and output-adapters and business POJOs.

Additionally, applications can access a cache from Oracle CQL or EPL, either by a user-defined function or directly from an Oracle CQL or EPL statement.

In the case of a user-defined function, programmers use Spring to inject the cache resource into the implementation of the function. For more information, see Section 1.6, "Configuring Oracle CEP Resource Access".

Applications can also query a cache directly from anOracle CQL or EPL statement that runs in a processor. In this case, the cache essentially functions as another type of stream data source to a processor so that querying a cache is very similar to querying a channel except that data is pulled from a cache.

An example of using Oracle CQL to query a cache is from a financial application that publishes orders and the trades used to execute the orders to a cache. At the end of the day when the markets are closed, the application queries the cache in order to find all the trades related to a particular order.

12.1.1.3 Use Case: Updating and Deleting Data in a Cache

An Oracle CEP application can both update and delete data in a cache when required.

For example, a financial application may need to update an order in the cache each time individual trades that fulfill the order are executed, or an order may need to be deleted if it has been cancelled. The components of an application that are allowed to consume data from a cache are also allowed to update it.

12.1.1.4 Use Case: Using a Cache in a Multi-Server Domain

If build an Oracle CEP application that uses a cache, and you plan to deploy that application in a multi-server domain, then you must use a caching-system that supports a distributed cache.

In this case, you must use either Oracle Coherence or a third-party caching system that supports a distributed cache.

For more information, see:

12.1.2 Additional Caching Features

In addition to the major caching features described in the preceding sections, Oracle CEP caching includes the following features:

  • Pre-load a cache with data before an application is deployed.

  • Periodically refresh, invalidate, and flush the data in a cache. All these tasks happen incrementally and without halting the application or causing latency spikes.

  • Dynamically update a cache's configuration.

12.1.3 Caching APIs

Oracle CEP provides a number of caching APIs that you can use in your application to perform certain tasks. The APIs are in two packages:

  • com.bea.cache.jcache—Includes the APIs used to access a cache and create cache loader, listeners, and stores.

  • com.bea.wlevs.cache.spi—Includes the API used to access a caching system.

The creation, configuration, and wiring of the caching systems and caches is all done using the EPN assembly file and component configuration files. This means that you typically never explicitly use the Cache and CachingSystem interfaces in your application; the only reason to use them is if you have additional requirements than the standard configuration. For example: if you want to provide integration with a third-party cache provider, then you must use the CachingSystem interface; if you want to perform operations on a cache that are not part of the java.util.Map interface, then you can use the Cache interface.

If you create cache listeners, loaders, or stores for an Oracle CEP local cache, then the Spring beans you write must implement the CacheListener, CacheLoader, or CacheStore interfaces.

If you create cache listeners, loaders, or stores for an Oracle Coherence cache, then the Spring beans you write must implement the appropriate Oracle Coherence interfaces.

If you create cache listeners, loaders, or stores for a third-party cache, then the Spring beans you write must implement the appropriate third-party cache interfaces.

For more information, see:

12.2 Configuring an Oracle CEP Local Caching System and Cache

You can configure your application to use the Oracle CEP local caching system and cache. The Oracle CEP local caching system is appropriate if you do not plan to deploy your application to a multi-server domain. If you plan to deploy your application to a multi-server domain, consider using an Oracle Coherence cache (see Section 12.3, "Configuring an Oracle Coherence Caching System and Cache").

Note:

It is assumed in this section that you have already created an Oracle CEP application along with its EPN assembly file and that you want to update the application to use caching. If you have not, refer to Chapter 1, "Overview of Creating Oracle CEP Applications" for details.

To configure an Oracle CEP local caching system and cache:

  1. Declare the caching system in the EPN assembly file.

    To declare a caching system that uses the Oracle CEP implementation declaratively in the EPN assembly file, use the wlevs:caching-system element without any additional attributes, as shown in the following example:

    <wlevs:caching-system id="caching-system-id"/>
    

    The value of the id attribute must match the name specified for the caching system in the external configuration metadata.

    To allow other applications to use the caching system, specify that the caching system be advertised using the advertise attribute (by default set to false):

    <wlevs:caching-system id="caching-system-id" advertise="true"/>
    
  2. Declare one or more caches for this caching system in the EPN assembly file.

    After you have declared a caching system for an application, you configure one or more caches using the wlevs:cache element:

    <wlevs:caching-system id="caching-system-id"/>
    ...
    <wlevs:cache id="cache-id" name="alternative-cache-name">
        <wlevs:caching-system ref="caching-system-id"/>
    </wlevs:cache>
    

    The name attribute is optional; specify it only if the name of the cache in the caching system is different from its ID. The wlevs:caching-system child element references the already-declared caching system that contains the cache. You must specify this child element only if the caching system is ambiguous: there is more than one caching system declared (either implicitly or explicitly) or if the caching system is in a different application or bundle.

    You can export both the caching system and the cache as an OSGI service using the advertise attribute.

    <wlevs:caching-system id="caching-system-id" advertise="true"/>
    ...
    <wlevs:cache id="cache-id" name="alternative-cache-name" advertise="true" >
        <wlevs:caching-system ref="caching-system-id"/>
    </wlevs:cache>
    

    If the cache is advertised, then a component in the EPN of an application in a separate bundle can then reference it. The following example shows how a processor in one bundle can use as a cache source the cache with ID cache-id located in a separate bundle (called cacheprovider):

    <wlevs:processor id="myProcessor2">
        <wlevs:cache-source ref="cacheprovider:cache-id"/>
    </wlevs:processor>
    

    The caching system is responsible for creating the cache associated with a particular name and returning a reference to the cache. The resulting cache bean implements the java.util.Map interface.

  3. Open your application's component configuration XML file using your favorite XML editor.

  4. Update the config root element to add a caching-system child element; use the name child element to uniquely identify it.

    This name must match the wlevs:caching-system element id attribute you specified in the EPN assembly file in step 1. This is how Oracle CEP knows to which particular caching system in the EPN assembly file this caching configuration applies.

    For example, assume your configuration file already contains a processor and an adapter (contents removed for simplicity); then the updated file might look like the following

    <?xml version="1.0" encoding="UTF-8"?>
    <n1:config xmlns:n1="http://www.bea.com/ns/wlevs/config/application"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <processor>
        ...
        </processor>
        <adapter>
        ...
        </adapter
        <caching-system>
            <name>caching-system-id</name>
        </caching-system>
    </n1:config>
    
  5. For each cache you want to create, update the caching-system element to add a cache child element; use the name child element to uniquely identify it.

    This name must match the wlevs:cache element id attribute you specified in the EPN assembly file in step 2. This is how Oracle CEP knows to which particular cache in the EPN assembly file this configuration applies.

    The following example shows two caches in the caching system:

    <caching-system>
        <name>caching-system-id</name>
        <cache>
            <name>cache-id</name>
            ...
        </cache>
        <cache>
            <name>second-cache-id</name>
            ...
        </cache>
    </caching-system>
    
  6. For each cache, optionally add the following elements that take simple data types to configure the cache:

    • max-size : The number of cache elements in memory after which eviction/paging occurs. The maximum cache size is 231-1 entries; default is 64.

    • eviction-policy : The eviction policy to use when max-size is reached. Supported values are: FIFO, LRU, LFU, and NRU; default value is LFU.

    • time-to-live: The maximum amount of time, in milliseconds, that an entry is cached. Default value is infinite.

    • idle-time: Amount of time, in milliseconds, after which cached entries are actively removed from the cache. Default value is infinite.

    • work-manager-name : The work manager to be used for all asynchronous operations. The value of this element corresponds to the name child element of the work-manager element in the server's config.xml configuration file.

    For example:

    <caching-system>
        <name>caching-system-id</name>
        <cache>
            <name>cache-id</name>
            <max-size>100000</max-size>
            <eviction-policy>LRU</eviction-policy
            <time-to-live>3600</time-to-live>
        </cache>
    </caching-system>
    
  7. Optionally add either write-through or write-behind as a child element of cache to specify synchronous or asynchronous writes to the cache store, respectively. By default, writes to the store are synchronous (<rite-through) which means that as soon as an entry is created or updated the write occurs.

    If you specify the write-behind element, then the cache store is invoked from a separate thread after a create or update of a cache entry. Use the following optional child elements to further configure the asynchronous writes to the store:

    • work-manager-name : The work manager that handles asynchronous writes to the cache store. If a work manager is specified for the cache itself, this value overrides it for store operations only. The value of this element corresponds to the name child element of the work-manager element in the server's config.xml configuration file.

    • batch-size : The number of updates that are picked up from the store buffer to write back to the backing store. Default value is 1.

    • buffer-size : The size of the internal store buffer that temporarily holds the asynchronous updates that need to be written to the store. Default value is 100.

    • buffer-write-attempts : The number of attempts that the user thread makes to write to the store buffer. The user thread is the thread that creates or updates a cache entry. If all attempts by the user thread to write to the store buffer fail, it will invoke the store synchronously. Default value is 1.

    • buffer-write-timeout : The time in milliseconds that the user thread waits before aborting an attempt to write to the store buffer. The attempt to write to the store buffer fails only in case the buffer is full. After the timeout, further attempts may be made to write to the buffer based on the value of buffer-write-attempts. Default value is 100.

    For example:

    <caching-system>
        <name>caching-system-id</name>
        <cache>
            <name>cache-id</name>
            <max-size>100000</max-size>
            <eviction-policy>LRU</eviction-policy
            <time-to-live>3600</time-to-live>
            <write-behind>
                <buffer-size>200</buffer-size>
                <buffer-write-attempts>2</buffer-write-attempts>
                <buffer-write-timeout>200</buffer-write-timeout>
            </write-behind>
        </cache>
    </caching-system>
    
  8. Optionally add a cache element listeners child element to configure the behavior of components that listen to the cache.

    Use the asynchronous Boolean attribute to specify whether listeners should be invoked:

    • asynchronously: true.

    • synchronously: false, which means listeners are invoked synchronously (Default).

    The listeners element has a single child element, work-manager-name, that specifies the work manager to be used for asynchronously invoking listeners. This value is ignored if synchronous invocations are enabled. If a work manager is specified for the cache itself, this value overrides it for invoking listeners only. The value of this element corresponds to the work-manager element name child element in the Oracle CEP server config.xml configuration file.

    For example:

    <caching-system>
         <name>caching-system-id</name>
         <cache>
            <name>cache-id</name>
            <max-size>100000</max-size>
            <eviction-policy>LRU</eviction-policy
            <time-to-live>3600</time-to-live>
            <write-behind>
                <buffer-size>200</buffer-size>
                <buffer-write-attempts>2</buffer-write-attempts>
                <buffer-write-timeout>200</buffer-write-timeout>
            </write-behind>
            <listeners asynchronous="true">
                <work-manager-name>cachingWM</work-manager-name>
            </listeners>
         </cache>
    </caching-system>
    
  9. Optionally, override the default cache configuration by updating the EPN assembly file with one or more additional cache element child elements.

  10. Access the Oracle CEP local cache:

  11. When you assemble your application, verify that the META-INF/MANIFEST.MF file includes the following import as Figure 12-1 shows:

    com.bea.wlevs.cache.spi; version ="11.1.0.0"
    

    If the MANIFEST.MF files does not include this import, update the MANIFEST.MF file to add this import before deploying your application.

    Figure 12-1 Editing the MANIFEST.MF File

    Description of Figure 12-1 follows
    Description of "Figure 12-1 Editing the MANIFEST.MF File"

12.2.1 Configuring an Oracle CEP Local Cache as an Event Listener

An Oracle CEP local cache can be configured as an explicit listener in the event processing network in order to receive events.

For example, to specify that a cache listens to a channel, specify the wlevs:listener element with a reference to the cache as a child of the wlevs:channel element as shown below:

<wlevs:caching-system id="caching-system-id"/>
...
<wlevs:cache id="cache-id" name="alternative-cache-name">
    <wlevs:caching-system ref="caching-system-id"/>
</wlevs:cache>
...
<wlevs:channel id="tradeStream">
    <wlevs:listener ref="cache-id"/>
</wlevs:channel>

As the channel sends new events to the cache, they are inserted into the cache. If a remove event (an old event that exits the output window) is sent by the channel, then the event is removed from the cache.

12.2.1.1 Specifying the Key Used to Index an Oracle CEP Local Cache

When you configure an Oracle CEP local cache to be a listener, events are inserted into the cache. This section describes the variety of options available to you to specify the key used to index a cache in this instance.

If you do not explicitly specify a key, the event object itself serves as both the key and value when the event is inserted into the cache. In this case, the event class must include a valid implementation of the equals and hashcode methods that take into account the values of the key properties.

See the following for ways to explicitly specify a key:

12.2.1.1.1 Specifying a Key Property in EPN Assembly File

The first option is to specify a property name for the key property when a cache is declared in the EPN assembly file using the key-properties attribute, as shown in the following example:

<wlevs:cache id="cache-id" key-properties="key-property-name">
    <wlevs:caching-system ref="caching-system-id"/>
</wlevs:cache>

In this case, all events that are inserted into the cache are required to have a property of this name at runtime, otherwise Oracle CEP throws an exception.

For example, assume the event type being inserted into the cache looks something like the following; note the key property (only relevant Java source shown):

public class MyEvent {
    private String key;
    public MyEvent() {
    }
    public MyEvent(String key) {
        this.key = key;
    }
    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
 ...
}

The corresponding declaration in the EPN assembly file would look like the following:

<wlevs:cache id="cache-id" key-properties="key">
    <wlevs:caching-system ref="caching-system-id"/>
</wlevs:cache>
12.2.1.1.2 Using a Metadata Annotation to Specify a Key

The second option is to use the metadata annotation com.bea.wlevs.ede.api.Key to annotate the event property in the Java class that implements the event type. This annotation does not have any attributes.

The following example shows how to specify that the key property of the MyEvent event type is the key; only relevant code is shown:

import com.bea.wlevs.ede.api.Key;
public class MyEvent {
    @Key
    private String key;
    public MyEvent() {
    }
    public MyEvent(String key) {
        this.key = key;
    }
    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
 ...
}
12.2.1.1.3 Specifying a Composite Key

The final option is to use the key-class attribute of the wlevs:cache element to specify a composite key in which multiple properties form the key. The value of the key-class attribute must be a JavaBean whose public fields match the fields of the event class. The matching is done according to the field name. For example:

<wlevs:cache id="cache-id" key-class="key-class-name">
    <wlevs:caching-system ref="caching-system-id"/>
</wlevs:cache>

12.2.2 Configuring an Oracle CEP Local Cache as an Event Source

An Oracle CEP local cache can be configured as a source of events to which another component in the event processing network listens. The listening component can be an adapter or a standard Spring bean. Any component that listens to a cache must implement the com.bea.cache.jcache.CacheListener interface. The following example shows how to configure a cache to be an event source for a Spring bean:

<wlevs:caching-system id="caching-system-id"/>
...
<wlevs:cache id="cache-id" name="alternative-cache-name">
    <wlevs:caching-system ref="caching-system-id"/>
    <wlevs:cache-listener ref="cache-listener-id" />
</wlevs:cache>
...
<bean id="cache-listener-id" class="wlevs.example.MyCacheListener"/>

In the example, the cache-listener-id Spring bean listens to events coming from the cache; the class that implements this component, wlevs.example.MyCacheListener, must implement the com.bea.jcache.CacheListener interface. You must program the wlevs.example.MyCacheListener class yourself.

12.2.3 Configuring an Oracle CEP Local Cache Loader

An Oracle CEP local cache loader is an object that loads objects into an Oracle CEP local cache. You configure a cache loader by using the wlevs:cache-loader child element of the wlevs:cache element to specify the bean that does the loading work, as shown in the following example:

<wlevs:caching-system id="caching-system-id"/>
...
<wlevs:cache id="cache-id" name="alternative-cache-name">
    <wlevs:caching-system ref="caching-system-id"/>
    <wlevs:cache-loader ref="cache-loader-id" />
</wlevs:cache>
...
<bean id="cache-loader-id" class="wlevs.example.MyCacheLoader"/>

In the example, the cache-loader-id Spring bean does the cache loading work; it is referenced by the cache using the ref attribute of the wlevs:cache-loader child element.

You must program the wlevs.example.MyCacheLoader class yourself, and it must implement the com.bea.cache.jcache.CacheLoader interface. This interface includes the load() method to customize the loading of a single object into the cache; Oracle CEP calls this method when the requested object is not in the cache. The interface also includes loadAll() methods that you implement to customize the loading of the entire cache.

12.2.4 Configuring an Oracle CEP Local Cache Store

You can configure an Oracle CEP local cache with a custom store that is responsible for writing data from the cache to a backing store, such as a table in a database. You configure a cache store by using the wlevs:cache-store child element of the wlevs:cache element to specify the bean that does the actual storing work, as shown in the following example:

<wlevs:caching-system id="caching-system-id"/>
...
<wlevs:cache id="cache-id" name="alternative-cache-name">
    <wlevs:caching-system ref="caching-system-id"/>
    <wlevs:cache-store ref="cache-store-id" />
</wlevs:cache>
...
<bean id="cache-store-id" class="wlevs.example.MyCacheStore"/>

In the example, the cache-store-id Spring bean does the work of writing the data from the cache to the backing store; it is referenced by the cache using the ref attribute of the wlevs:cache-store child element.

You must program the wlevs.example.MyCacheStore class yourself, and it must implement the com.bea.cache.jcache.CacheStore interface. This interface includes the store() method that stores the data in the backing store using the passed key; Oracle CEP calls this method when it inserts data into the cache. The interface also includes the storeAll() method for storing a batch of data to a backing store in the case that you have configured asynchronous writes for a cache with the write-behind configuration element.

12.3 Configuring an Oracle Coherence Caching System and Cache

You can configure your application to use the Oracle Coherence caching system and cache. Use this caching system if you plan to deploy your application to a multi-server domain.

Using Oracle Coherence, only the first caching-system can be configured in a server. Oracle CEP will ignore any other caching systems you might configure.

Note:

Before you can legally use Oracle CEP with Oracle Coherence, you must obtain a valid Coherence license such as a license for Coherence Enterprise Edition, Coherence Grid Edition, or Oracle WebLogic Application Grid. For more information on Oracle Coherence, see http://www.oracle.com/technology/products/coherence/index.html.

Note:

It is assumed in this section that you have already created an Oracle CEP application along with its EPN assembly file and that you want to update the application to use caching. If you have not, refer to Chapter 1, "Overview of Creating Oracle CEP Applications" for details.

To configure an Oracle Coherence caching system and cache:

  1. Declare the Oracle Coherence caching system in the EPN assembly file.

    To declare a caching system that uses the Oracle Coherence implementation declaratively in the EPN assembly file, use the wlevs:caching-system element as shown in the following example:

    <wlevs:caching-system id="caching-system-id" provider="coherence"/>
    

    The value of the id attribute must match the name you specify for the caching system in the application's component configuration file (see step 3).

    To allow other applications to use the caching system, specify that the caching system be advertised using the advertise attribute (by default set to false):

    <wlevs:caching-system id="caching-system-id" provider="coherence" advertise="true"/>
    
  2. Declare one or more caches for this caching system in the EPN assembly file.

    After you have declared a caching system for an application, you configure one or more caches using the wlevs:cache element:

    <wlevs:caching-system id="caching-system-id" provider="coherence" />
    ...
    <wlevs:cache id="myCache" advertise="false"> 
        <wlevs:caching-system ref="caching-system-id"/>
    </wlevs:cache>
    

    The wlevs:cache element id attribute is mandatory. This attribute maps to the name of a cache in the Oracle Coherence configuration files (see step 3).

    The name attribute is optional; specify it only if the name of the cache in the caching system is different from its ID. The wlevs:caching-system child element references the already-declared caching system that contains the cache. You must specify this child element only if the caching system is ambiguous: there is more than one caching system declared (either implicitly or explicitly) or if the caching system is in a different application or bundle.

    You can export both the caching system and the cache as an OSGi service using the advertise attribute.

    <wlevs:caching-system id="caching-system-id" provider="coherence" advertise="true"/>
    ...
    <wlevs:cache id="cache-id" name="alternative-cache-name" advertise="true" >
        <wlevs:caching-system ref="caching-system-id"/>
    </wlevs:cache>
    

    If the cache is advertised, then a component in the EPN of an application in a separate bundle can then reference it. The following example shows how a processor in one bundle can use as a cache source the cache with ID cache-id located in a separate bundle called cacheprovider:

    <wlevs:processor id="myProcessor2">
        <wlevs:cache-source ref="cacheprovider:cache-id"/>
    </wlevs:processor>
    

    The caching system is responsible for creating the cache associated with a particular name and returning a reference to the cache. The resulting cache bean implements the java.util.Map interface.

  3. Configure the caching system and its caches by updating the caching configuration file for the application.

    See Section 12.3.1, "Configuring the Oracle Coherence Caching System and Caches."

  4. Optionally, override the default cache configuration by updating the EPN assembly file with one or more additional cache element child elements.

  5. Access the Oracle Coherence cache:

  6. When you assemble your application, verify that the META-INF/MANIFEST.MF file includes the following import as Figure 12-1 shows:

    com.bea.wlevs.cache.spi; version ="11.1.0.0"
    

    If the MANIFEST.MF files does not include this import, update the MANIFEST.MF file to add this import before deploying your application.

    Figure 12-2 Editing the MANIFEST.MF File

    Description of Figure 12-2 follows
    Description of "Figure 12-2 Editing the MANIFEST.MF File"

12.3.1 Configuring the Oracle Coherence Caching System and Caches

Oracle CEP leverages the native configuration provided by Oracle Coherence. You do this by packaging the following two Oracle Coherence configuration files, with the indicated names, in the application bundle that uses the Oracle Coherence cache:

When assembling your application, consider the following:

  • coherence-cache-config.xml is a per-application configuration file; put this file in the META-INF/wlevs/coherence directory of the bundle JAR. Note that this directory is different from the directory that stores the component configuration file for the local in-memory Oracle CEP caching provider (META-INF/wlevs).

  • tangosol-coherence-override.xml is a global per-server file (referred to as "operational configuration" in the Oracle Coherence documentation); put this file in the Oracle CEP server config directory.

Update your application configuration file as Example 12-5 shows:

Example 12-5 Application Configuration File: Coherence Cache

<coherence-caching-system>
    <name>caching-system-id</name>
    <coherence-cache-config>
        ../wlevs/coherence/coherence-cache-config.xml
    </coherence-cache-config>
</coherence-caching-system>

When you declare that a caching system uses the Oracle Coherence provider, be sure that all of the caches of this caching system also map to an Oracle Coherence configuration and not an Oracle CEP local configuration, or Oracle CEP throws an exception.

12.3.1.1 The coherence-cache-config.xml File

The coherence-cache-config.xml file is the basic Oracle Coherence configuration file and must conform to the Oracle Coherence DTDs, as is true for any Oracle Coherence application.

The following sample shows a simple configuration. See the explanation after the sample for information about the sections in bold.

<?xml version="1.0"?>
<!DOCTYPE cache-config SYSTEM "cache-config.dtd">
<cache-config>
  <caching-scheme-mapping>
    <cache-mapping>
       <cache-name>myCoherenceCache</cache-name>
       <scheme-name>new-replicated</scheme-name>
     </cache-mapping>
     <cache-mapping>
       <cache-name>myLoaderCache</cache-name>
       <scheme-name>test-loader-scheme</scheme-name>
     </cache-mapping>
     <cache-mapping>
       <cache-name>myStoreCache</cache-name>
       <scheme-name>test-store-scheme</scheme-name>
     </cache-mapping>
  </caching-scheme-mapping>
  <caching-schemes>
    <replicated-scheme>
      <scheme-name>new-replicated</scheme-name>
      <service-name>ReplicatedCache</service-name>
      <backing-map-scheme>
        <local-scheme>
          <scheme-ref>my-local-scheme</scheme-ref>
        </local-scheme>
      </backing-map-scheme>
    </replicated-scheme>
    <local-scheme>
       <scheme-name>my-local-scheme</scheme-name>
       <eviction-policy>LRU</eviction-policy>
       <high-units>100</high-units>
       <low-units>50</low-units> 
    </local-scheme>
    <local-scheme>
       <scheme-name>test-loader-scheme</scheme-name>
       <eviction-policy>LRU</eviction-policy>
       <high-units>100</high-units>
       <low-units>50</low-units>
       <cachestore-scheme>
          <class-scheme>
             <class-factory-name>
                 com.bea.wlevs.cache.coherence.configuration.SpringFactory
             </class-factory-name>
            <method-name>getLoader</method-name>
            <init-params>
              <init-param>
                <param-type>java.lang.String</param-type>
                <param-value>{cache-name}</param-value>
              </init-param>
            </init-params>
          </class-scheme>
       </cachestore-scheme>
    </local-scheme>
    <local-scheme>
      <scheme-name>test-store-scheme</scheme-name>
      <eviction-policy>LRU</eviction-policy>
      <high-units>100</high-units>
      <low-units>50</low-units>
      <cachestore-scheme>
        <class-scheme>
           <class-factory-name>
               com.bea.wlevs.cache.coherence.configuration.SpringFactory
           </class-factory-name>
          <method-name>getStore</method-name>
          <init-params>
            <init-param>
               <param-type>java.lang.String</param-type>
               <param-value>{cache-name}</param-value>
            </init-param>
          </init-params>
        </class-scheme>
      </cachestore-scheme>
    </local-scheme>
  </caching-schemes>
</cache-config>

In the Oracle Coherence configuration file, the cache-name element that is a child element of cache-mapping identifies the name of the Oracle Coherence cache. The value of this element must exactly match the value of the id attribute of the wlevs:cache element in the EPN assembly file. For example, the following EPN assembly file snippet refers to the myCoherenceCache cache in the Oracle Coherence configuration file:

<wlevs:cache id="myCoherenceCache" advertise="false"> 
    <wlevs:caching-system ref="coherence-cache"/>
    <wlevs:cache-loader ref="localLoader"/> 
    <wlevs:cache-listener ref="localListener"/>
</wlevs:cache>

The Oracle Coherence configuration file illustrates another requirement when using Oracle Coherence with Oracle CEP: an Oracle Coherence factory must be declared when using Spring to configure a loader or store for a cache. You do this using the cachestore-scheme element in the Oracle Coherence configuration file to specify a factory class that allows Oracle Coherence to call into Oracle CEP and retrieve a reference to the loader or store that is configured for the cache. The only difference between configuring a loader or store is that the method-name element has a value of getLoader when a loader is used and getStore when a store is being used. You pass the cache name to the factory as an input parameter.

When declaring Oracle Coherence caches in the EPN assembly files of one or more applications deployed to the same Oracle CEP server, you should never configure multiple instances of the same cache with a loader or store. You might inadvertently do this by employing multiple applications that each configure the same Oracle Coherence cache with a loader or store in their respective EPN assembly file. If you do this, Oracle CEP throws an exception.

If multiple application bundles need to share Oracle Coherence caches, then you should put the EPN assembly file that contains the appropriate wlevs:cache and wlevs:caching-system in a separate bundle and set their advertise attributes to true.

Refer to your Oracle Coherence documentation (see http://www.oracle.com/technology/products/coherence/index.html) for detailed information about the coherence-cache-config.xml file.

12.3.1.2 The tangosol-coherence-override.xml File

The tangosol-coherence-override.xml file configures Oracle Coherence caching. You may includes this file if you are using Oracle Coherence for caching only. Do not include this file if you are using Oracle Coherence for clustering.

The following sample shows a simple configuration. See the explanation after the sample for information about the sections in bold.

<?xml version='1.0'?>
<coherence xml-override="/tangosol-coherence-override.xml">
  <cluster-config>
    <member-identity>
      <cluster-name>com.bea.wlevs.example.provider</cluster-name>
    </member-identity>
...
</coherence>

This configuration file is fairly standard. The main thing to note is that you should specify a cluster-name element to prevent Oracle Coherence from attempting to join existing Oracle Coherence clusters when Oracle CEP starts up; this can cause problems and sometimes even prevent Oracle CEP from starting.

Refer to your Oracle Coherence documentation (see http://www.oracle.com/technology/products/coherence/index.html) for detailed information about the tangosol-coherence-override.xml file.

For more information on Oracle CEP clusters, see "Administrating Oracle CEP Multi-Server Domains" in the Oracle CEP Administrator's Guide.

12.3.2 Configuring an Oracle Coherence Cache as an Event Listener

An Oracle Coherence cache can be configured as an explicit listener in the event processing network in order to receive events.

For example, to specify that a cache listens to a channel, specify the wlevs:listener element with a reference to the cache as a child of the wlevs:channel element as shown below:

<wlevs:coherence-caching-system id="caching-system-id"/>
...
<wlevs:cache id="cache-id" name="alternative-cache-name">
    <wlevs:caching-system ref="caching-system-id"/>
</wlevs:cache>
...
<wlevs:channel id="tradeStream">
    <wlevs:listener ref="cache-id"/>
</wlevs:channel>

As the channel sends new events to the cache, they are inserted into the cache. If a remove event (an old event that exits the output window) is sent by the channel, then the event is removed from the cache.

12.3.2.1 Specifying the Key Used to Index an Oracle Coherence Cache

When you configure an Oracle Coherence cache to be a listener, events are inserted into the cache. This section describes the variety of options available to you to specify the key used to index a cache in this instance.

If you do not explicitly specify a key, the event object itself serves as both the key and value when the event is inserted into the cache. In this case, the event class must include a valid implementation of the equals and hashcode methods that take into account the values of the key properties.

See the following for ways to explicitly specify a key:

12.3.2.1.1 Specifying a Key Property in EPN Assembly File

The first option is to specify a property name for the key property when a cache is declared in the EPN assembly file using the key-properties attribute, as shown in the following example:

<wlevs:cache id="myCache" key-properties="key-property-name">
    <wlevs:caching-system ref="caching-system-id"/>
</wlevs:cache>

In this case, all events that are inserted into the cache are required to have a property of this name at runtime, otherwise Oracle CEP throws an exception.

For example, assume the event type being inserted into the cache looks something like the following; note the key property (only relevant Java source shown):

public class MyEvent {
    private String key;
    public MyEvent() {
    }
    public MyEvent(String key) {
        this.key = key;
    }
    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
...
}

The corresponding declaration in the EPN assembly file would look like the following:

<wlevs:cache id="myCache" key-properties="key">
    <wlevs:caching-system ref="caching-system-id"/>
</wlevs:cache>
12.3.2.1.2 Using a Metadata Annotation to Specify a Key

The second option is to use the metadata annotation com.bea.wlevs.ede.api.Key to annotate the event property in the Java class that implements the event type. This annotation does not have any attributes.

The following example shows how to specify that the key property of the MyEvent event type is the key; only relevant code is shown:

import com.bea.wlevs.ede.api.Key;
public class MyEvent {
    @Key
    private String key;
    public MyEvent() {
    }
    public MyEvent(String key) {
        this.key = key;
    }
    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
 ...
}
12.3.2.1.3 Specifying a Composite Key

The final option is to use the key-class attribute of the <wlevs:cache> element to specify a composite key in which multiple properties form the key. The value of the key-class attribute must be a JavaBean whose public fields match the fields of the event class. The matching is done according to the field name. For example:

<wlevs:cache id="myCache" key-class="key-class-name">
    <wlevs:caching-system ref="caching-system-id"/>
</wlevs:cache>

12.3.3 Configuring an Oracle Coherence Cache as an Event Source

You can configure an Oracle Coherence cache as a source of events to which another component in the event processing network listens. The listening component can be an adapter or a standard Spring bean. Any component that listens to a cache must implement the com.tangosol.util.MapListener interface. The following example shows how to configure an Oracle Coherence cache to be an event source for a Spring bean:

<wlevs:coherence-caching-system id="caching-system-id"/>
...
<wlevs:cache id="myCache" advertise="false"> 
    <wlevs:caching-system ref="caching-system-id"/>
    <wlevs:cache-loader ref="localLoader"/> 
    <wlevs:cache-listener ref="localListener"/>
</wlevs:cache>
<bean id="localListener" 
      class="com.bea.wlevs.example.provider.coherence.LocalListener"/>

In the example, the cache-listener-id Spring bean listens to events coming from the cache; the class that implements this component, com.bea.wlevs.example.provider.coherence.LocalListener, must implement the appropriate Oracle Coherence-specific Java interfaces such as com.tangosol.util.MapListener. You must program this LocalListener class yourself as Example 12-6 shows.

Example 12-6 Oracle Coherence Cache LocalListener Implementation

package com.bea.wlevs.example.provider.coherence;

import com.tangosol.util.MapEvent;
import com.tangosol.util.MapListener;

public class LocalListener implements MapListener {
    public static int deleted = 0;
    public static int inserted = 0;
    public static int updated = 0;

    public void entryDeleted(MapEvent event) {
        deleted++;
    }
    public void entryInserted(MapEvent event) {
        inserted++;
    }
    public void entryUpdated(MapEvent event) {
        updated++;
    }
}

12.3.4 Configuring an Oracle Coherence Cache Loader or Store

Using an Oracle Coherence cache, you may configure either a wlevs:cache-loader or a wlevs:cache-store child element of the wlevs:cache element in the EPN assembly file, but not both. This is because Oracle Coherence combines the loader and store into a single component:

12.3.4.1 Configuring an Oracle Coherence Cache Loader

In Example 12-7, the localLoader Spring bean loads events into the oracle Coherence cache when the backing store is read-only. If the backing store is read-write, use a cache store (see Section 12.3.4.2, "Configuring an Oracle Coherence Cache Store").

The class that implements this component, com.bea.wlevs.example.provider.coherence.LocalLoader, must implement the appropriate Oracle Coherence-specific Java interfaces such as com.tangosol.net.cache.CacheLoader. You must program this LocalLoader class yourself as Example 12-8 shows.

Example 12-7 Oracle Coherence Cache EPN Assembly File for a Cache Loader

<wlevs:coherence-caching-system id="caching-system-id"/>
<wlevs:cache id="myCache" advertise="false"> 
    <wlevs:caching-system ref="caching-system-id"/>
    <wlevs:cache-loader ref="localLoader"/> 
</wlevs:cache>
<bean id="localLoader" 
      class="com.bea.wlevs.example.provider.coherence.LocalLoader"/>

Example 12-8 Oracle Coherence Cache LocalLoader Implementation

package com.bea.wlevs.example.provider.coherence;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.bea.wlevs.example.provider.event.ProviderData;
import com.tangosol.net.cache.CacheLoader;

public class LocalLoader implements CacheLoader {
    public static int loadCount = 0;
    public static Set keys = new HashSet();

    public LocalLoader() {
    }
    public Object load(Object key) {
        loadCount++;
        keys.add(key);
        return new ProviderData((String) key);
    }
    public Map loadAll(Collection keys) {
        Map result = new HashMap();

        for (Object key : keys) {
            result.put(key, load(key));
        }
        return result;
    }
}

12.3.4.2 Configuring an Oracle Coherence Cache Store

In Example 12-9, the localStore Spring bean loads events into the cache when the backing store is read-write. If the backing store is read-only, use a cache loader (see Section 12.3.4.1, "Configuring an Oracle Coherence Cache Loader").

The class that implements this component, com.bea.wlevs.example.provider.coherence.LocalStore, must implement the appropriate Oracle Coherence-specific Java interfaces such as com.tangosol.net.cache.CacheStore. You must program this LocalStore class yourself as Example 12-10 shows.

Example 12-9 Oracle Coherence Cache EPN Assembly File for a Cache Store

<wlevs:coherence-caching-system id="caching-system-id"/>
<wlevs:cache id="myCache" advertise="false"> 
    <wlevs:caching-system ref="caching-system-id"/>
    <wlevs:cache-store ref="localStore"/> 
</wlevs:cache>
<bean id="localStore" 
      class="com.bea.wlevs.example.provider.coherence.LocalStore"/>

Example 12-10 Oracle Coherence Cache LocalStore Implementation

package com.bea.wlevs.example.provider.coherence;
 
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
 
import com.bea.wlevs.example.provider.event.ProviderData;
import com.tangosol.net.cache.CacheStore;
 
public class LocalStore implements CacheStore {
    public static int eraseCount = 0;
    public static int storeCount = 0;
    public static int loadCount = 0;

    public void erase(Object key) {
        eraseCount++;
    }
    public void eraseAll(Collection keys) {
        for (Object key : keys) {
            erase(key);
        }
    }
    public void store(Object key, Object value) {
        //
        // Do the store operation here.
        //
    }
    public void storeAll(Map entries) {
        for (Map.Entry entry : (Set <Map.Entry>)entries.entrySet()) {
            store(entry.getKey(), entry.getValue());
        }
    }
    public Object load(Object key) {
        loadCount++;
        return new ProviderData((String) key);
    }
    public Map loadAll(Collection keys) {
        Map result = new HashMap();
        for (Object key : keys) {
            result.put(key, load(key));
        }
        return result;
    }
}

12.4 Configuring a Third-Party Caching System and Cache

You can configure your application to use a third-party caching system and cache.

Note:

It is assumed in this section that you have already created an Oracle CEP application along with its EPN assembly file and that you want to update the application to use caching. If you have not, refer to Chapter 1, "Overview of Creating Oracle CEP Applications" for details.

To configure a third-party caching system and cache:

  1. Create a plug-in to define the third-party caching system as an Oracle CEP caching system provider.

    This involves:

    • Implementing the com.bea.wlevs.cache.spi.CachingSystem interface

    • Creating a factory that creates caching systems of this type.

    • Registering the factory with an attribute that identifies its provider type.

  2. Declare the caching system in the EPN assembly file.

    Use the wlevs:caching-system element to declare a third-party implementation; use the class or provider attributes to specify additional information.

    For simplicity, you can include the third-party implementation code inside the Oracle CEP application bundle itself to avoid having to import or export packages and managing the lifecycle of a separate bundle that contains the third-party implementation. In this case the wlevs:caching-system element appears in the EPN assembly file as shown in the following example:

    <wlevs:caching-system id="caching-system-id" 
                          class="third-party-implementation-class"/>
    

    The class attribute specifies a Java class that must implement the com.bea.wlevs.cache.spi.CachingSystem interface. For details about this interface, see the Oracle CEP Java API Reference.

    Sometimes, however, you might not be able, or want, to include the third-party caching implementation in the same bundle as the Oracle CEP application that is using it. In this case, you must create a separate bundle whose Spring application context includes the wlevs:caching-system element, with the advertise attribute mandatory:

    <wlevs:caching-system id ="caching-system-id" 
                          class="third-party-implementation-class"
                          advertise="true"/>
    

    Alternatively, if you want to decouple the implementation bundle from the bundle that references it, or you are plugging in a caching implementation that supports multiple caching systems per Java process, you can specify a factory as a provider:

    <wlevs:caching-system id ="caching-system-id" provider="caching-provider"/>
    <factory id="factory-id" provider-name="caching-provider">
        <class>the.factory.class.name</class>
    </factory>
    

    The factory class (the.factory.class.name in the example) must implement the com.bea.wlevs.cache.spi.CachingSystemFactory interface. This interface has a single method, create(), that returns a com.bea.wlevs.cache.spi.CachingSystem instance.

    You must deploy this bundle alongside the application bundle so that the latter can start using it.

  3. Declare one or more caches for this caching system in the EPN assembly file.

    After you have declared a caching system for an application, you configure one or more caches using the wlevs:cache element:

    <wlevs:caching-system id ="caching-system-id" provider="caching-provider"/>
    ...
    <wlevs:cache id="cache-id" name="alternative-cache-name">
        <wlevs:caching-system ref="caching-system-id"/>
    </wlevs:cache>
    

    The name attribute is optional; specify it only if the name of the cache in the caching system is different from its ID. The wlevs:caching-system child element references the already-declared caching system that contains the cache. You must specify this child element only if the caching system is ambiguous: there is more than one caching system declared (either implicitly or explicitly) or if the caching system is in a different application or bundle.

    You can export both the caching system and the cache as an OSGI service using the advertise attribute.

    <wlevs:caching-system id="caching-system-id" advertise="true"/>
    ...
    <wlevs:cache id="cache-id" name="alternative-cache-name" advertise="true" >
        <wlevs:caching-system ref="caching-system-id"/>
    </wlevs:cache>
    

    If the cache is advertised, then a component in the EPN of an application in a separate bundle can then reference it. The following example shows how a processor in one bundle can use as a cache source the cache with ID cache-id located in a separate bundle (called cacheprovider):

    <wlevs:processor id="myProcessor2">
        <wlevs:cache-source ref="cacheprovider:cache-id"/>
    </wlevs:processor>
    

    The caching system is responsible for creating the cache associated with a particular name and returning a reference to the cache. The resulting cache bean implements the java.util.Map interface.

  4. Configure the third-party caching system and its caches by updating the third-party caching configuration file or files for the application.

    Refer to your third-party cache documentation.

  5. Optionally, override the default third-party cache configuration by updating the appropriate configuration file with one or more additional cache element child elements.

    • Specify that a cache is an event sink by configuring it as a listener to another component in the event processing network.

      Refer to your third-party cache documentation.

    • Specify that a cache is an event source to which another component in the event processing network listens.

      Refer to your third-party cache documentation.

    • Configure a cache loader or store.

      Refer to your third-party cache documentation.

  6. Access the third-party cache:

  7. When you assemble your application, verify that the META-INF/MANIFEST.MF file includes the following import as Figure 12-1 shows:

    com.bea.wlevs.cache.spi; version ="11.1.0.0"
    

    If the MANIFEST.MF files does not include this import, update the MANIFEST.MF file to add this import before deploying your application.

    Figure 12-3 Editing the MANIFEST.MF File

    Description of Figure 12-3 follows
    Description of "Figure 12-3 Editing the MANIFEST.MF File"

12.5 Accessing a Cache From an Oracle CQL Statement

You can reference a cache from an Oracle CQL statement in much the same way you reference a channel; this feature enables you to enrich standard streaming data with data from a separate source. Example 12-11 shows a valid Oracle CQL query that joins trade events from a standard channel named S1 with stock symbol data from a cache named stockCache:

Example 12-11 Valid Oracle CQL Query Against a Cache

SELECT  S1.symbol, S1.lastPrice, stockCache.description
FROM    S1 [Now], stockCache
WHERE   S1.symbol = stockCache.symbol 

Whenever you query a cache, you must join against the [Now] window. This guarantees that the query will execute against a snapshot of the cache. If you join against any other window type, then if the cache changes before the window expires, the query will be incorrect.

Example 12-12 shows an invalid Oracle CQL query that joins a Range window against a cache. If the cache changes before this window expires, the query will be incorrect. Consequently, this query will raise Oracle CEP server error "external relation must be joined with s[now]".

Example 12-12 Invalid Oracle CQL Query Against a Cache

SELECT trade.symbol, trade.price, trade.numberOfShares, company.name
FROM TradeStream [Range 8 hours] as trade, CompanyCache as company
WHERE trade.symbol = company.id

When you use data from a cache in an Oracle CQL query, Oracle CEP pulls the data rather than it being pushed, as is the case with a channel. This means that, continuing with Example 12-11, the query executes only when a channel pushes a trade event to the query; the stock symbol data in the cache never causes a query to execute, it is only pulled by the query when needed.

You must abide by these restrictions when using a cache in an Oracle CQL query:

12.5.1 How to Access a Cache From an Oracle CQL Statement

This section describes how to reference a cache in an Oracle CQL query statement.

This procedure assumes that you have already configured the caching system and caches. For more information, see:

To access a cache from an Oracle CQL statement:

  1. If you have not already done so, create the event type that corresponds to the cache data and register it in the event repository.

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

  2. Specify the key properties for the data in the cache.

    There are a variety of ways to do this.

    For instructions on specifying the cache key, see:

  3. In the EPN assembly file, update the configuration of the cache to declare the event type of its values; use the value-type attribute of the wlevs:cache element. For example:

    <wlevs:caching-system id="caching-system-id"/>
    ...
    <wlevs:cache id="cache-id" 
                 name="alternative-cache-name"
                 value-type="CompanyEvent">
        <wlevs:caching-system ref="caching-system-id"/>
    </wlevs:cache>
    

    The value-type attribute specifies the type for the values contained in the cache. This must be a valid type name in the event type repository.

    This attribute is required only if the cache is referenced in an Oracle CQL query. This is because the query processor needs to know the type of events in the cache.

  4. In the EPN assembly file, update the configuration of the processor that executes the Oracle CQL query that references a cache, adding a wlevs:cache-source child element that references the cache. For example:

    <wlevs:channel id="stream-id"/>
    
    <wlevs:processor id="processor-id">
        <wlevs:cache-source ref="cache-id">
        <wlevs:source ref="stream-id">
    </wlevs:processor>
    

    In the example, the processor will have data pushed to it from the stream-id channel as usual; however, the Oracle CQL queries that execute in the processor can also pull data from the cache-id cache. When the query processor matches an event type in the FROM clause to an event type supplied by a cache, such as CompanyEvent, the processor pulls instances of that event type from the cache.

12.6 Accessing a Cache From an EPL Statement

You can reference a cache from an EPL statement in much the same way you reference a channel; this feature enables you to enrich standard streaming data with data from a separate source. For example, the following EPL query joins trade events from a standard channel with company data from a cache:

INSERT INTO EnrichedTradeEvent
SELECT trade.symbol, trade.price, trade.numberOfShares, company.name
FROM TradeEvent trade RETAIN 8 hours, Company company
WHERE trade.symbol = company.id

In the example, both TradeEvent and Company are event types registered in the repository, but they have been configured in such a way that TradeEvents come from a standard stream of events but Company maps to a cache in the event processing network. This configuration happens outside of the EPL query, which means that the source of the data is transparent in the query itself.

When you use data from a cache in an EPL query, Oracle CEP pulls the data rather than it being pushed, as is the case with a channel. This means that, continuing with the preceding sample, the query executes only when a channel pushes a trade event to the query; the company data in the cache never causes a query to execute, it is only pulled by the query when needed.

You must abide by these restrictions when using a cache in an EPL query:

12.6.1 How To Access a Cache From an EPL Statement

This section describes how to reference a cache in an EPL query statement.

This procedure assumes that you have already configured the caching system and caches. For more information, see:

To access a cache from an EPL statement:

  1. If you have not already done so, create the event type that corresponds to the cache data, such as Company in the preceding example, and registered it in the event repository. See Section 1.5, "Creating Oracle CEP Event Types."

  2. Specify the key properties for the data in the cache. There are a variety of ways to do this; see

  3. In the EPN assembly file, update the configuration of the cache in the EPN assembly file to declare the event type of its values; use the value-type attribute of the wlevs:cache element. For example:

    <wlevs:caching-system id="caching-system-id"/>
    ...
    <wlevs:cache id="cache-id" 
                 name="alternative-cache-name"
                 value-type="Company">
        <wlevs:caching-system ref="caching-system-id"/>
    </wlevs:cache>
    

    The value-type attribute specifies the type for the values contained in the cache. This must be a valid type name in the event type repository.

    This attribute is required only if the cache is referenced in an EPL query. This is because the query processor needs to know the type of events in the cache.

  4. In the EPN assembly file, update the configuration of the processor that executes the EPL query that references a cache, adding a wlevs:cache-source child element that references the cache. For example:

    <wlevs:channel id="stream-id"/>
    <wlevs:processor id="processor-id">
        <wlevs:cache-source ref="cache-id">
        <wlevs:source ref="stream-id">
    </wlevs:processor>
    

    In the example, the processor will have data pushed to it from the stream-id channel as usual; however, the EPL queries that execute in the processor can also pull data from the cache-id cache. When the query processor matches an event type in the FROM clause to an event type supplied by a cache, such as Company, the processor pulls instances of that event type from the cache.

12.7 Accessing a Cache From an Adapter

An adapter can also be injected with a cache using the standard Spring mechanism for referencing another bean. A cache bean implements the java.util.Map interface which is what the adapter uses to access the injected cache.

First, the configuration of the adapter in the EPN assembly file must be updated with a wlevs:instance-property child element, as shown in the following example:

<wlevs:caching-system id="caching-system-id"/>
    ...
<wlevs:cache id="cache-id" name="alternative-cache-name">
    <wlevs:caching-system ref="caching-system-id"/>
</wlevs:cache>
...
<wlevs:adapter id="myAdapter" provider="myProvider">
    <wlevs:instance-property name="map" ref="cache-id"/>
</wlevs:adapter>

In the example, the ref attribute of wlevs:instance-property references the id value of the wlevs:cache element. Oracle CEP automatically injects the cache, implemented as a java.util.Map, into the adapter.

In the adapter Java source, add a setMap (Map) method with the code that implements whatever you want the adapter to do with the cache:

package com.bea.wlevs.example;
…
import java.util.Map;
public class MyAdapter implements Runnable, Adapter, EventSource, SuspendableBean  {
...
    public void setMap (Map map) {...}
}

12.8 Accessing a Cache From a Business POJO

A business POJO, configured as a standard Spring bean in the EPN assembly file, can be injected with a cache using the standard Spring mechanism for referencing another bean. In this way the POJO can view and manipulate the cache. A cache bean implements the java.util.Map interface which is what the business POJO uses to access the injected cache. A cache bean can also implement a vendor-specific sub-interface of java.util.Map, but for portability it is recommended that you implement Map.

First, the configuration of the business POJO in the EPN assembly file must be updated with a property child element, as shown in the following example based on the Output bean of the FX example (see "HelloWorld Example" in the Oracle CEP Getting Started):

<wlevs:caching-system id="caching-system-id"/>
...
<wlevs:cache id="cache-id" name="alternative-cache-name">
    <wlevs:caching-system ref="caching-system-id"/>
</wlevs:cache>
...
<bean class="com.bea.wlevs.example.helloworld.HelloWorldBean">
    <property name="map" ref="cache-id"/>
</bean>

In the example, the ref attribute of the property element references the id value of the wlevs:cache element. Oracle CEP automatically injects the cache, implemented as a java.util.Map, into the business POJO bean.

In the business POJO bean Java source, add a setMap (Map) method with the code that implements whatever you want the POJO to do with the cache:

package com.bea.wlevs.example.helloworld;
…
import java.util.Map;
public class HelloWorldBean implements EventSink {
...
    public void setMap (Map map) {...}
}

12.9 Accessing a Cache From an Oracle CQL User-Defined Function

In addition to standard event streams, Oracle CQL rules can also invoke the member methods of a user-defined function.

These user-defined functions are implemented as standard Java classes and are declared in the component configuration file of the Oracle CQL processor, as shown in the following example:

<bean id="orderFunction" class="orderFunction-impl-class"/>

The processor in which the relevant Oracle CQL rule runs must then be injected with the user-defined function using the wlevs:function child element, referencing the Spring bean with the ref attribute:

<wlevs:processor id= "tradeProcessor">
    <wlevs:function ref="orderFunction"/>
</wlevs:processor>

Alternatively, you can specify the bean class in the wlevs:function element:

<wlevs:processor id="testProcessor">
    <wlevs:listener ref="providerCache"/>
    <wlevs:listener ref="outputCache"/>
    <wlevs:cache-source ref="testCache"/>
    <wlevs:function function-name="mymod" exec-method=”execute” />
        <bean class="com.bea.wlevs.example.function.MyMod"/>
    </wlevs:function>
</wlevs:processor>

The following Oracle CQL rule, assumed to be configured for the tradeProcessor processor, shows how to invoke the existsOrder() method of the orderFunction user-defined function:

INSERT INTO InstitutionalOrder
SELECT er.orderKey AS key, er.symbol AS symbol, er.shares as cumulativeShares
FROM ExecutionRequest er [Range 8 hours]
WHERE NOT orderFunction.existsOrder(er.orderKey)

You can also configure the user-defined function to access a cache by injecting the function with a cache using the standard Spring mechanism for referencing another bean. A cache bean implements the java.util.Map interface which is what the user-defined function uses to access the injected cache.

First, the configuration of the user-defined function in the EPN assembly file must be updated with a wlevs:property child element, as shown in the following example:

<wlevs:caching-system id="caching-system-id"/>
    ...
<wlevs:cache id="cache-id" name="alternative-cache-name">
    <wlevs:caching-system ref="caching-system-id"/>
</wlevs:cache>
    ...
<bean id="orderFunction" class="orderFunction-impl-class">
    <wlevs:property name="cache" ref="cache-id"/>
</bean>

In the example, the ref attribute of the wlevs:property element references the id value of the wlevs:cache element. Oracle CEP automatically injects the cache, implemented as a java.util.Map, into the user-defined function.

In the user-defined function's Java source, add a setMap (Map) method with the code that implements whatever you want the function to do with the cache:

package com.bea.wlevs.example;
…
import java.util.Map;
public class OrderFunction {
...
    public void setMap (Map map) {...}
}

For more information on user-defined functions, see "Functions: User-Defined" in the Oracle CEP CQL Language Reference.

12.10 Accessing a Cache From an EPL User-Defined Function

In addition to standard event streams, EPL rules can also invoke the member methods of a user-defined function.

These user-defined functions are implemented as standard Java classes and are declared in the EPN assembly file using the standard Spring bean tags, as shown in the following example:

<bean id="orderFunction" class="orderFunction-impl-class"/>

The processor in which the relevant EPL rule runs must then be injected with the user-defined function using the wlevs:function child element, referencing the Spring with the ref attribute:

<wlevs:processor id= "tradeProcessor">
    <wlevs:function ref="orderFunction"/>
</wlevs:processor>

The following EPL rule, assumed to be configured for the tradeProcessor processor, shows how to invoke the existsOrder() method of the orderFunction user-defined function:

INSERT INTO InstitutionalOrder
SELECT er.orderKey AS key, er.symbol AS symbol, er.shares as cumulativeShares
FROM ExecutionRequest er RETAIN 8 HOURS WITH UNIQUE KEY
WHERE NOT orderFunction.existsOrder(er.orderKey)

You can also configure the user-defined function to access a cache by injecting the function with a cache using the standard Spring mechanism for referencing another bean. A cache bean implements the java.util.Map interface which is what the user-defined function uses to access the injected cache.

First, the configuration of the user-defined function in the EPN assembly file must be updated with a wlevs:property child element, as shown in the following example:

<wlevs:caching-system id="caching-system-id"/>
...
<wlevs:cache id="cache-id" name="alternative-cache-name">
    <wlevs:caching-system ref="caching-system-id"/>
</wlevs:cache>
...
<bean id="orderFunction" class="orderFunction-impl-class">
    <wlevs:property name="cache" ref="cache-id"/>
</bean>

In the example, the ref attribute of the wlevs:property element references the id value of the wlevs:cache element. Oracle CEP automatically injects the cache, implemented as a java.util.Map, into the user-defined function.

In the user-defined function's Java source, add a setMap (Map) method with the code that implements whatever you want the function to do with the cache:

package com.bea.wlevs.example;
…
import java.util.Map;
public class OrderFunction {
...
    public void setMap (Map map) {...}
}

For more information on user-defined functions, see "User-Defined Functions" in the Oracle CEP EPL Language Reference.

12.11 Accessing a Cache Using JMX

At runtime, you can access a cache programatically using JMX and the MBeans that Oracle CEP deploys for the caching systems and caches you define.

This section describes:

For more information, "Configuring JMX for Oracle CEP" in the Oracle CEP Administrator's Guide

12.11.1 How to Access a Cache With JMX Using Oracle CEP Visualizer

The simplest and least error-prone way to access a caching system or cache with JMX is to use the Oracle CEP Visualizer.

For more information, see "Server and Domain Tasks" in the Oracle CEP Visualizer User's Guide.

12.11.2 How to Access a Cache With JMX Using Java

The simplest and least error-prone way to access a caching system or cache with JMX is to use the Oracle CEP Visualizer (see Section 12.11.1, "How to Access a Cache With JMX Using Oracle CEP Visualizer"). Alternatively, you can access a caching system or cache with JMX using Java code that you write.

Oracle CEP creates a StageMBean for each cache that your application uses as a stage. The Type of this MBean is Stage.

To access a cache with JMX using Java:

  1. Connect to the JMX service that Oracle CEP server provides.

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

  2. Get a list of cache StageMbean using either of:

    • CachingSystemMBean.getCacheMBeans()

    • ApplicationMBean.getStageMBeans()

  3. Get the ObjectName for a given StageMBean that represents a cache in your caching system:

    ObjectName cacheName = ObjectName.getInstance ('com.bea.wlevs:Name = newCache,Type=Stage,CachingSystem=newCachingSystem,Application=provider');
    
  4. Get a proxy instance for the StageMBean with this ObjectName:

    StageMBean cache = (StageMBean) MBeanServerInvocationHandler.newProxyInstance(
        server, cacheName, StageMBean.class, false
    );
    
  5. Use the methods of the StageMBean to access the cache.