7.1 Introduction

The com.tangosol.util.ObservableMapinterface enables you to observe and act on the changes made to cache entries. It extends java.util.EventListener and uses the standard JavaBeans event model. All types of NamedCache instances implement this interface. To listen for an event, you register a MapListener (com.tangosol.util.MapListener) instance on the cache. MapListener instances are called on the client; that is, the listener code is executed in your client process.

There are multiple ways to listen for events:

Listen for all events

Listen for all events that satisfy a filter

Listen for events on a particular object key

These listener tasks can be performed on a NamedCache by the addMapListener methods listed in Example 7-1.

The com.tangosol.util.MapEventclass captures the object key, and the old and new values. You can specify a Lite event, in which the new and old values might not be present. Example 7-2 describes a pattern for registering these methods against a NamedCache. This has been done as an anonymous class. You can use the getOldValue or getNewValue methods in the MapEvent class to get the entry for which the event gets fired.

7.2 Creating a Cache Listener

7.2.1 Create a Class to Listen for Changes in the Cache

In the Loading project, create the class that will listen for a new Contact object entry.Name the class ObserverExample and ensure that it has a main method. See "Creating a Java Class" for detailed information.

Within this class, add a listener to display a message whenever a new Contact is updated to the cache. For example, use the following code to keep the Java process running until you read from the console. Otherwise, your program will immediately exit.

Within the class, create an inner class to extend AbstractMapListner. Implement the methods to insert, update, and delete the cache values. In this case, most of the work should be done in the entryUpdated method, based on the old and new values contained in a MapEvent.

Example 7-3 illustrates a possible implementation of a listener class.

7.2.2 Run the Cache Listener Example

To run the Cache Listener example:

Create a run configuration for ObserverExample. Right click ObserverExample in the ProjectExplorer and select RunAs. In the RunConfigurations dialog box select Oracle Coherence and click the NewConfiguration icon.

In the Name field, enter ObserverExample.

In the Project field in the Main tab, enter Loading. In the Mainclass field, enter com.oracle.handson.ObserverExample.

In the General tab of the Coherence tab, browse to the c:\home\oracle\workspace\Contacts\appClientModule\coherence-cache-config.xml file in the Cacheconfigurationdescriptor field. Select the Disabled (cache client) button. Enter 3155 in the Clusterport field. Click Apply.

In the Other tab, scroll down to the tangosol.pof.config field. Enter the absolute path to the POF configuration file contacts-pof-config.xml. Click Apply.

In the Common tab, select Shared file and browse for the Loading directory.

Check that the classes for the Loading project (C:\home\oracle\workspace\Loading\build\classes) and the path to the configuration files (C:\home\oracle\workspace) are present in the contacts-cache-server.cmd file.

7.3 Responding to Changes in the Cache

In this section, you will create a Java class to modify entries in the cache and return the changed records.

Until now, to perform actions on the entries in a cache, you used the put and get operations. However, there is a better way to perform operations on data that ensure consistent behavior when concurrent data access is required. Entry processors (com.tangosol.util.InvocableMap.EntryProcessor) are agents that perform processing against entries. The entries are processed directly where the data is being held. The processing you perform can change the data: it can create, update, remove data, or only perform calculations. The processing can occur in parallel in a partitioned cache with multiple nodes, so it is scalable. Processing in the cache also saves I/O expense because data is not pulled to the client for processing.

Entry processors that work on the same key are logically queued. This allows lock-free (high performance) processing. The com.tangosol.util.InvocableMap interface (which the NamedCache implements) has the following methods for operating on data:

• Object invoke(Object oKey, InvocableMap.EntryProcessor processor), which invokes the passed EntryProcessor against an individual object and returns the result of the invocation.

• Map invokeAll(Collection keys, InvocableMap.EntryProcessor processor), which invokes the EntryProcessor against the collection of keys and returns the result for each invocation.

• Map invokeAll(Filter filter, InvocableMap.EntryProcessor processor), which invokes the EntryProcessor against the entries that match the filter and returns the result for each invocation.

Note:

EntryProcessor classes must be available in the class path for each cluster node.

To create an entry process, you can extend com.tangosol.util.processes.AbstractProcessor and implement the process() method. For example, the following code creates an EntryProcessor instance to change the work address of employees in the Contacts data set:

7.3.1 Create a Class to Update Entries in the Cache

In the Loading project, create a class called ProcessorExample with a main method that updates the address of a Contact object in the cache. See "Creating a Java Class" for detailed information.

Write code to find the records of the Contacts object that live in Massachusetts and update their work addresses to an in-state office.

Include an inner class that implements the PortableObject interface (for serializing and deserializing data from the cache) and contains an EntryProcessor instance to set the work addresses. Use methods from the Filter class to isolate the Contacts members whose home addresses are in Massachusetts.

Example 7-5 illustrates a possible implementation of the ProcessorExample class.

7.3.3 Run the Cache Update Example

To run the cache update example.

Create a run configuration for ProcessorExample. Right click ObserverExample in the ProjectExplorer and select RunAs. In the RunConfigurations dialog box select OracleCoherence and click the NewConfiguration icon

In the Name field, enter ProcessorExample.

In the Project field in the Main tab, enter Loading. In the Mainclass field, enter com.oracle.handson.ProcessorExample.

In the General tab of the Coherence tab, browse to the c:\home\oracle\workspace\Contacts\appClientModule\coherence-cache-config.xml file in the Cacheconfigurationdescriptor field. Select the Disabled (cache client) button. Enter 3155 in the Clusterport field. Click Apply.

In the Other tab, scroll down to the tangosol.pof.config field. Enter the absolute path to the POF configuration file contacts-pof-config.xml. Click Apply.

In the Common tab, select Shared file and browse for the Loading directory.

Perform the following steps to test the ObserverExample and ProcessorExample classes.