The release of SOA Suite 12c sees the addition of a Coherence Adapter to the list of Technology Adapters that are licensed with the SOA Suite. In this entry I provide an introduction to configuring the adapter and using the different operations it supports.
The Coherence Adapter provides access to Oracles Coherence Data Grid. The adapter provides access to the cache capabilities of the grid, it does not currently support the many other features of the grid such as entry processors – more on this at the end of the blog.
Previously if you wanted to use Coherence from within SOA Suite you either used the built in caching capability of OSB or resorted to writing Java code wrapped as a Spring component. The new adapter significantly simplifies simple cache access operations.
When creating a SOA domain the Coherence adapter is shipped with a very basic configuration that you will probably want to enhance to support real requirements. In this section I look at the configuration required to use Coherence adapter in the real world.
The Coherence Adapter is not targeted at the SOA server by default, so this targeting needs to be performed from within the WebLogic console before the adapter can be used.
The Coherence Adapter provides a default connection factory to connect to an out-of-box Coherence cache and also a cache called adapter-local. This is helpful as an example but it is good practice to only have a single type of object within a Coherence cache, so we will need more than one. Without having multiple caches then it is hard to clean out all the objects of a particular type. Having multiple caches also allows us to specify different properties for each cache. The following is a sample cache configuration file used in the example.
<!DOCTYPE cache-config SYSTEM "cache-config.dtd">
This defines a single cache called TestCache. This is a distributed cache, meaning that the entries in the cache will distributed across the grid. This enables you to scale the storage capacity of the grid by adding more servers. Additional caches can be added to this configuration file by adding additional <cache-mapping> elements.
The cache configuration file is reference by the adapter connection factory and so needs to be on a file system accessed by all servers running the Coherence Adapter. It is not referenced from the composite.
We find the correct cache configuration by using a Coherence Adapter connection factory. The adapter ships with a few sample connection factories but we will create new one. To create a new connection factory we do the following:
You may will need to stop and restart the adapter to get it to recognize the new connection factory.
To demonstrate the different operations I created a WSDL with the following operations:
I created a composite based on this WSDL that calls a different adapter reference for each operation. Details on configuring the adapter within a composite are provided in the Configuring the Coherence Adapter section of the documentation.
I used a Mediator to map the input WSDL operations to the individual adapter references.
The input schema is shown below.
This type of pattern is likely to be used in all XML types stored in a Coherence cache. The XMLCacheKey element represents the cache key, in this schema it is a string, but could be another primitive type. The other fields in the cached object are represented by a single XMLCacheContent field, but in a real example you are likely to have multiple fields at this level. Wrapper elements are provided for lists of elements (XMLCacheEntryList) and lists of cache keys (XMLCacheEntryKeyList). XMLEmpty is used for operation that don’t require an input.
The put operation takes an XMLCacheEntry as input and passes this straight through to the adapter. The XMLCacheKey element in the entry is also assigned to the jca.coherence.key property. This sets the key for the cached entry. The adapter also supports automatically generating a key, which is useful if you don’t have a convenient field in the cached entity. The cache key is always returned as the output of this operation.
The get operation takes an XMLCacheKey as input and assigns this to the jca.coherence.key property. This sets the key for the entry to be retrieved.
The remove operation takes an XMLCacheKey as input and assigns this to the jca.coherence.key property. This sets the key for the entry to be deleted.
This is similar to the remove operation but instead of using a key as input to the remove operation it uses a filter. The filter could be overridden by using the jca.coherence.filter property but for this operation it was permanently set in the adapter wizard to be the following query:
key() != ""
This selects all objects whose key is not equal to the empty string. All objects should have a key so this query should select all objects for deletion.
Note that there appears to be a bug in the return value. The return value is entry rather than having the expected RemoveResponse element with a Count child element. Note the documentation states that
When using a filter for a Remove operation, the Coherence Adapter does not report the count of entries affected by the remove operation, regardless of whether the remove operation is successful.
When using a key to remove a specific entry, the Coherence Adapter does report the count, which is always 1 if a Coherence Remove operation is successful.
Although this could be interpreted as meaning an empty part is returned, an empty part is a violation of the WSDL contract.
The list operation takes no input and returns the result list returned by the adapter. The adapter also supports querying using a filter. This filter is essentially the where clause of a Coherence Query Language statement. When using XML types as cached entities then only the key() field can be tested, for example using a clause such as:
key() LIKE “Key%1”
This filter would match all entries whose key starts with “Key” and ends with “1”.
The listKeys operation is essentially the same as the list operation except that only the keys are returned rather than the whole object.
To test the composite I used the new 12c Test Suite wizard to create a number of test suites. The test suites should be executed in the following order:
One example of using the Coherence Adapter is to create a shared memory region that allows SOA composites to share information. An example of this is provided by Lucas Jellema in his blog entry First Steps with the Coherence Adapter to create cross instance state memory.
However there is a problem in creating global variables that can be updated by multiple instances at the same time. In this case the get and put operations provided by the Coherence adapter support a last write wins model. This can be avoided in Coherence by using an Entry Processor to update the entry in the cache, but currently entry processors are not supported by the Coherence Adapter. In this case it is still necessary to use Java to invoke the entry processor.
The sample code I refer to above is available for download and consists of two JDeveloper projects, one with the cache config file and the other with the Coherence composite.
The Coherence Adapter is a really exciting new addition to the SOA developers toolkit, hopefully this article will help you make use of it.