13 Integrating a Cache

This chapter describes how to configure a caching system for use with Oracle Event Processing event processing networks. It includes information on how to configure caches that are based on Oracle Coherence, Oracle Event Processing, and third-party caching providers and to access them from Oracle Continuous Query Language, Java classes, and other code.

This chapter includes the following sections:

13.1 Overview of Integrating a Cache

You can integrate a cache system with your Oracle Event Processing application so that the cache is available as source or destination for data your application uses, including event data. Integrating a cache can provide access to relatively static data at a speed that is well suited to an application that handles streaming data.

A cache is a temporary storage area for events, created to improve the overall performance of your Oracle Event Processing application (a cache is not necessary for the application to function correctly). To increase the availability of the events and increase the performance of their applications, Oracle Event Processing applications can publish to or consume events from a cache.

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.

By integrating a cache, you can:

  • Load into the cache frequently-used data for access from application code, improving application performance.

  • Write to the cache processed event data for use by another application.

For more complete cache integration uses case descriptions, see Section 13.1.3, "Caching Use Cases".

Note that a cache 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.

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

Although configuration steps vary for each of the caching implementations, the high-level steps are as follows:

To integrate caching:

  1. Configure the caching system and caches. How you do this will vary depending on the caching implementation you're using.

    For more information, see Section 13.1.2, "Overview of Cache Configuration".

  2. Declare the caching system and its caches by updating a component configuration file.

    For more information, see Section 13.1.2, "Overview of Cache Configuration".

  3. Add the caching system and caches to the event provcessing network by editing the EPN assembly file. Note that you can use the IDE's EPN editor to add a cache.

    For more information, see Section 13.5, "Adding Caching to an Event Processing Network".

  4. Write code to access the cache in your Oracle Event Processing application.

    For more information, see Section 13.6, "Accessing a Cache from Application Code".

13.1.1 Caching Implementations Supported by Oracle Event Processing

Oracle Event Processing supports the following caching implementations:

  • Oracle Event Processing local cache: a local, in-memory single-JVM cache. This implementation is best for local use (it cannot be used in a cluster). It might also be useful for development in the early stages because it is relatively simple to set up.

  • 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 Event Processing 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 Event Processing to work with other, third-party cache implementations.

13.1.2 Overview of Cache Configuration

You configure caching systems and caches before adding them to the event processing network (EPN). How you add configuration depends on which caching implementation you will be using.

You integrate caching systems and caches by updating the following configuration files:

Basically, though, you create, configure, and wire caching systems and caches using component configuration and EPN assembly files. By default, when you create a project, the IDE creates one component configuration file and one EPN assembly file. When you add a cache to the EPN using the IDE, it adds a cache element to the EPN assembly file. You must manually add caching-system elements to the EPN assembly and component configuration files.

When adding configured caching systems and caches to an application's event processing network, you specify entries in the EPN assembly file with entries in the component configuration file by referencing configured names.

In Example 13-1 (a component configuration file excerpt) and Example 13-2 (an EPN assembly file excerpt), EPN id attribute values must have the same values as configuration name attribute values:

Example 13-1 Component Configuration File Name Values

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

Example 13-2 EPN Assembly File ID and Ref Values

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

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

If your application has more than one caching system, you can create a caching-system element for each of them in a config.xml file. You can use one XML file or several, putting all in the META-INF/wlevs directory. Choose the method that best suits your development environment.

For more information, see:

For more information on configuring caching, see:

13.1.3 Caching Use Cases

Caching technology is a great fit for streaming data use cases, where high throughput can be particularly important. Getting data from a cache will usually be much faster than getting the same data from a relational database.

The following describes common use cases for caching in Oracle Event Processing applications.

  • 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 Event Processing 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 Event Processing application that generates events (input adapter, channel, business POJO, or processor) to publish its events to the cache.

  • Consuming data from a cache

    Oracle Event Processing 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 Event Processing 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.4.3, "Configuring Oracle Event Processing 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 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.

  • Updating and deleting data in a cache

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

  • Using a cache in a multi-server domain

    If you build an Oracle Event Processing 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:

13.1.4 Caching APIs

Oracle Event Processing provides caching APIs that you can use in your application to perform certain tasks. The APIs are in the com.bea.cache.jcache package, which includes the APIs used to access a cache and create cache loader, listeners, and stores. Also, if you intend to use that functionality, you will need to import the com.tangosol.net and com.tangosol.net.cache packages.

You create, configure, and wire caching systems and caches 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 Event Processing local cache, then the 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 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 beans you write must implement the appropriate third-party cache interfaces.

For more information, see:

13.2 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 Event Processing will ignore any other caching systems you might configure.

Note:

Before you can legally use Oracle Event Processing 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.

To configure an Oracle Coherence caching system and cache:

  1. Decide whether or not your Oracle Coherence cache will be used exclusively by this application or shared amongst two or more applications.

    For more information, see Section 13.2.2, "Configuring a Shared Oracle Coherence Cache".

  2. Configure the cache and caching system using a coherence-cache-config.xml file (and possibly a tangosol-coherence-override.xml file) and place the file in your application's META-INF/wlevs/coherence directory.

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

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

  4. Configure the caching system and its caches by updating the EPN assembly file with one or more cache element child elements.

  5. Before assembling and deploying the application, edit your META-INF/MANIFEST.MF to import packages that might be required in your implementation. If your applications implements cache listeners, loaders or stores, your manifest should import com.tangosol.net.cache packages.

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

13.2.1 Configuring the Oracle Coherence Caching System and Caches

When configuring an Oracle Coherence cache for integration with an Oracle Event Processing application, you use Coherence configuration files, then reference those files in Oracle Event Processing component configuration.

Oracle Event Processing leverages the native configuration provided by Oracle Coherence. You do this by packaging the following two Oracle Coherence configuration files, using the file names indicated in the following list, in the application bundle that uses the Oracle Coherence cache:

  • coherence-cache-config.xml—Oracle Coherence cache configuration information. Individual caches are identified with the cache-name element; the value of this element maps to the id attribute of the wlevs:cache element in the EPN assembly file. See Section 13.2.1.1, "The coherence-cache-config.xml File" for information about this file as well as an example of the mapping.

    This 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 Event Processing caching provider (META-INF/wlevs).

  • tangosol-coherence-override.xml—Oracle Coherence cluster configuration. See Section 13.2.1.2, "The tangosol-coherence-override.xml File" for information about this file as well as an example.

    This is a global per-server file (referred to as "operational configuration" in the Oracle Coherence documentation); put this file in the Oracle Event Processing server config directory.

Once you have configured Oracle Coherence using the files in the preceding list, update your component configuration file as shown in Example 13-3. Here, you declare a Coherence caching system for use in the application by referencing the coherence-cache-config.xml file where you configured the cache.

Example 13-3 Component 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 Event Processing local configuration. Otherwise, Oracle Event Processing will throw an exception. For reference information on this file, see Section D.23, "coherence-caching-system" and Section D.22, "coherence-cache-config".

13.2.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 Event Processing: 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 Event Processing 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.

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.

13.2.1.2 The tangosol-coherence-override.xml File

The tangosol-coherence-override.xml file configures Oracle Coherence caching. Include 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 Event Processing starts up; this can cause problems and sometimes even prevent Oracle Event Processing 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 Event Processing clusters, see "Administrating Multi-Server Domains With Oracle Event Processing Native Clustering" in the Oracle Fusion Middleware Administrator's Guide for Oracle Event Processing.

13.2.2 Configuring a Shared Oracle Coherence Cache

When declaring Oracle Coherence caches in the EPN assembly files of one or more applications deployed to the same Oracle Event Processing 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 Event Processing 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.

To export both the caching system and the cache as an OSGi service, set the advertise attribute to true.

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

13.3 Configuring an Oracle Event Processing Local Caching System and Cache

You can configure your application to use the Oracle Event Processing local caching system and cache. The Oracle Event Processing 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 13.2, "Configuring an Oracle Coherence Caching System and Cache").

To configure an Oracle Event Processing local caching system and cache:

  1. Declare the caching system and caches by updating a component configuration file by adding caching-system and cache elements.

    For more information, see Section 13.3.1, "Configuring an Oracle Event Processing Caching System"

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

    For more information, see Section 13.5, "Adding Caching to an Event Processing Network".

  3. Before assembling and deploying the application, verify that the META-INF/MANIFEST.MF file includes the following import:

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

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

13.3.1 Configuring an Oracle Event Processing Caching System

In order to use an Oracle Event Processing caching system cache in an application, you need to first configure the cache. Afterward, you can reference the cache in other places, such as an event processing network. This section describes the settings you can make in a component configuration file. For reference information on the file, see Section D.18, "caching-system" and Section D.17, "cache".

In a component configuration file (such as a config.xml file), to the config root element, add a caching-system child element; use its name child element to uniquely identify the caching system. This name will match the EPN assembly file's wlevs:caching-system element id attribute. This is how Oracle Event Processing 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 from this example 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>

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

This name must match the wlevs:cache element id attribute you specify in the EPN assembly file. This is how Oracle Event Processing knows to which particular cache in the EPN assembly file this configuration applies.

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 more information, see Section F.45, "work-manager".

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>

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 (<write-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.

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

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

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

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

13.4 Configuring a Third-Party Caching System and Cache

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

To configure a third-party caching system and cache:

  1. Create a plug-in to define the third-party caching system as an Oracle Event Processing 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 attribute to specify additional information.

    For simplicity, you can include the third-party implementation code inside the Oracle Event Processing 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 Fusion Middleware Java API Reference for Oracle Event Processing.

    Sometimes, however, you might not be able, or want, to include the third-party caching implementation in the same bundle as the Oracle Event Processing 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. When you assemble your application, verify that the META-INF/MANIFEST.MF file includes the following import:

    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.

13.5 Adding Caching to an Event Processing Network

Once you have configured the caching provider your application will be using, you can add it to the applications event processing network (EPN).

For information about adding caching to the EPN and configuring it to be reused, see the following sections:

When you add a cache to the EPN, you can specify other functionality, as described in the following sections:

13.5.1 Adding the Caching System and Caches to an EPN

To declare a caching system that uses the Oracle Coherence implementation declaratively in the EPN assembly file, use the wlevs:caching-system element, whose id attribute must match the name you specified for the caching system in the application's component configuration file.

After you have declared a caching system for an application, you configure one or more caches using the wlevs:cache element. The element's mandatory id attribute maps to the name of a cache in the configuration file.

The following example illustrates a caching system and cache declared in an EPN assembly file:

<wlevs:caching-system id="caching-system-id" provider="coherence" advertise="false"/>
...
<wlevs:cache id="myCache" advertise="false"> 
    <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.

13.5.2 Configuring a Cache for Reuse Among Applications

You can export both the caching system and the cache as OSGI services using the advertise attribute. 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 illustrates 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>

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>

For more information, see Section 13.2.2, "Configuring a Shared Oracle Coherence Cache".

13.5.3 Configuring a Cache as an Event Listener

You can configure a cache in an EPN to receive events as they pass through the network.

For example, to specify that a cache listens to a channel, configure the channel with a wlevs:listener element that has a reference to the cache, 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: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 the channel sends a remove event (an old event that exits the output window), then the event is removed from the cache.

13.5.3.1 Specifying the Key Used to Index a Cache

When you configure a 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:

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

To use a metadata annotation to specify a key:

  1. Import the com.bea.wlevs.ede.api.Key package.

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

  2. Apply the @Key annotation to a method.

    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 {
        private String key;
        public MyEvent() {
        }
        public MyEvent(String key) {
            this.key = key;
        }
        public String getKey() {
            return key;
        }
        @Key
        public void setKey(String key) {
            this.key = key;
        }
    }
    
13.5.3.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>

13.5.4 Configuring a Cache as an Event Source

You can configure a 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 bean.

A class that listens to a cache must implement an interface that provides methods for receiving events, as follows:

  • A class that listens to a Coherence cache must implement the com.tangosol.util.MapListener interface.

  • A class that listens to an Oracle Event Processing local cache must implement the com.bea.cache.jcache.CacheListener interface.

<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="cacheListenerId" class="wlevs.example.LocalListener"/>

In the example, the cacheListenerId Spring bean listens to events coming from the cache. In this case, the class that implements this component, com.bea.wlevs.example.MyCacheListener, is listening to an Oracle Coherence cache. It must implement the appropriate Oracle Coherence-specific Java interfaces, including com.tangosol.util.MapListener. Example 13-4 illustrates this implementation.

Example 13-4 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++;
    }
}

13.5.5 Exchanging Data Between a Cache and Another Data Source

You can have a cache in an EPN exchange data with another data source, including a database. For example, you can load a cache with data when the application starts or create a read/write relationship between the cache and a database.

If the cache will only be reading data, including when the backing store is read-only, you should use a cache loader. If the cache will read and write data, use a cache store. In both cases, creating the relationship involves specific configuration and a Java class that knows how to communicate with the data source.

For more information, see the following topics:

13.5.5.1 Loading Cache Data from a Read-Only Data Source

Using a cache loader, you can have a cache in your EPN load data from a read-only data source. A cache loader is a Java class that loads cache objects into a cache. You create a cache loader by writing a Java class that implements the appropriate interfaces to enable the loader class to communicate with the cache. Then 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.

If the backing store is read-write, use a cache store instead (see Section 13.5.5.2, "Exchanging Data with a Read-Write Data Source").

When creating a cache loader, you implement interfaces as follows:

  • To load cache data into an Oracle Coherence cache, create a class that implements the appropriate Oracle Coherence-specific Java interfaces, including com.tangosol.net.cache.CacheLoader. See Example 13-6 for an example.

  • To load cache data into an Oracle Event Processing local cache, create a class that implements com.bea.cache.jcache.CacheLoader interface. This interface includes the load method to customize loading a single object into the cache; Oracle Event Processing 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.

In Example 13-5, the localLoader bean loads events into an Oracle Coherence cache when the backing store is read-only.

When working with a Coherence cache, note that if you specify a cache loader in your configuration file, you must also specify the corresponding class factory method name in your Coherence cache configuration file. For a cache loader, you specify the getLoader method of com.bea.wlevs.cache.coherence.configuration.SpringFactory. For example code, see Section 13.2.1.1, "The coherence-cache-config.xml File".

Example 13-5 Oracle Coherence Cache EPN Assembly File for a Cache Loader

<wlevs: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 13-6 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;
    }
}

13.5.5.2 Exchanging Data with a Read-Write Data Source

Using a cache store, you can have a cache in your EPN exchange data with a read-write data source. A cache store is a Java class that exchanges cache objects with a cache. You create a cache store by writing a Java class that implements the appropriate interfaces to enable the it to communicate with the data source. Then you add the cache store to the EPN by using the wlevs:cache-loader child element of the wlevs:cache element to specify the bean that communicates with the data source.

If the backing store is read-only, use a cache loader instead (see Section 13.5.5.1, "Loading Cache Data from a Read-Only Data Source").

When creating a cache store, you implement interfaces as follows:

  • To exchange cache data with an Oracle Coherence cache, create a class that implements the appropriate Oracle Coherence-specific Java interfaces, including com.tangosol.net.cache.CacheStore. See Example 13-8 for an example.

  • To exchange cache data with an Oracle Event Processing local cache, create a class that implements 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 Event Processing 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.

In Example 13-7, the localStore bean loads events into the cache when the backing store is read-write.

Note that if you specify a cache store in your Spring configuration file, you must also specify the corresponding class factory method name in your Coherence cache configuration file. For a cache store, you specify the getStore method of com.bea.wlevs.cache.coherence.configuration.SpringFactory. For example code, see Section 13.2.1.1, "The coherence-cache-config.xml File".

Example 13-7 Oracle Coherence Cache EPN Assembly File for a Cache Store

<wlevs: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 13-8 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;
    }
}

13.6 Accessing a Cache from Application Code

Once you have configured a cache, you can access the cache from several components in an Oracle Event Processing application. This section describes how to do that.

For more information, see the following sections:

13.6.1 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 an event source such as a channel; this feature enables you to enrich standard streaming data with data from a separate source. Example 13-9 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 13-9 Valid Oracle CQL Query Against a Cache

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

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

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

    The following example 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 Event Processing server error "external relation must be joined with s[now]".

    
    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 Event Processing pulls the data rather than it being pushed, as is the case with a channel. This means that, continuing with Example 13-9, 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 specify the key property needed to do a lookup based on the cache key.

    Consider two streams S and C with schemas (id, group, value) where the cache key is id. A valid query is:

    select count(*) as n from S [now], C
    where S.id = C.id
    

    For instructions on specifying the cache key, see:

  • Joins must be executed only by referencing the cache key.

  • You cannot use a cache in a view. Instead, use a join.

  • Only a single channel source may occur in the FROM clause of an Oracle CQL statement that joins cache data source(s).

  • If the cache is a processor source, you connect the cache directly to the processor on the EPN as Figure 13-1 shows.

  • If the cache is a processor sink, you connect the processor to the cache using a channel as Figure 13-2 shows.

13.6.1.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 9.3, "Creating Event Types".

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

    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:

    1. If the cache is a processor source: you connect the cache directly to the processor on the EPN as Figure 13-1 shows.

      Figure 13-1 Cache as Processor Source

      Description of Figure 13-1 follows
      Description of "Figure 13-1 Cache as Processor Source"

      Update the wlevs:processor element a wlevs:cache-source child element that references the cache. For example:

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

      In the example, the processor will have data pushed to it from the S1 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.

    2. If the cache is a processor sink: you must connect the processor to the cache using a channel on the EPN (that is, there must be a channel between the processor and the cache sink) as Figure 13-2 shows.

      Figure 13-2 Cache as Processor Sink

      Description of Figure 13-2 follows
      Description of "Figure 13-2 Cache as Processor Sink"

      In this case, the application assembly file looks like this:

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

13.6.2 Accessing a Cache From an EPL Statement

You can reference a cache from an Event Processing Language (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.

Note:

The EPL language is deprecated. For new development, use Oracle CQL. For information on accessing a cache from CQL, see Section 13.6.1, "Accessing a Cache from an Oracle CQL Statement".

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 Event Processing 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:

  • You must specify the key properties for data in the cache.

    For instructions on specifying the cache key, see:

  • Joins must be executed only by referencing the cache key.

  • You cannot specify a RETAIN clause for data pulled from a cache. If an event type that gets its data from a cache is included in a RETAIN clause, Oracle Event Processing ignores it.

  • You cannot use a cache in a correlated sub-query. Instead, use a join.

  • Only a single channel source may occur in the FROM clause of an EPL statement that joins cache data source(s). Using multiple cache sources and parameterized SQL queries is supported.

13.6.2.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 9.3, "Creating 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.

13.6.3 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 Event Processing 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) {...}
}

13.6.4 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 Section 2.5, "HelloWorld 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 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 Event Processing 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) {...}
}

13.6.5 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 Event Processing 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 Fusion Middleware CQL Language Reference for Oracle Event Processing.

13.6.6 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 Event Processing 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 Fusion Middleware EPL Language Reference for Oracle Event Processing.

13.6.7 Accessing a Cache Using JMX

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

This section describes:

For more information, "Configuring JMX for Oracle Event Processing" in the Oracle Fusion Middleware Administrator's Guide for Oracle Event Processing

13.6.7.1 How to Access a Cache With JMX Using Oracle Event Processing Visualizer

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

For more information, see "Server and Domain Tasks" in the Oracle Fusion Middleware Visualizer User's Guide for Oracle Event Processing.

13.6.7.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 Event Processing Visualizer (see Section 13.6.7.1, "How to Access a Cache With JMX Using Oracle Event Processing Visualizer"). Alternatively, you can access a caching system or cache with JMX using Java code that you write.

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

    For more information, see "Configuring JMX for Oracle Event Processing" in the Oracle Fusion Middleware Administrator's Guide for Oracle Event Processing

  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.