OSB Web Service Response Caching by Service Operation

Oracle Service Bus has built in support for Service Result caching using Oracle Coherence, described here
http://docs.oracle.com/cd/E23943_01/admin.1111/e15867/configuringandusingservices.htm#CHDDCGEE


For each Business Service, a Cache Token can be defined as part of a unique key used to identfy the request/response.

Business Service
          Result Cache Diagram

The cache Token is a string value which is derived from an xpath expression.
The Cache Token Expression can be defined in the advanced settings for a given business service as shown below.

Business Service
          Configuration


But what if the business service supports multiple operations,
and there is no parameter common to all the operations that can serve as a cache key?

How can we set a specific cache key expression for each operation?
Luckily, there is a solution for this exact scenario, as decribed in the link below, the Cache Token can be set at runtime.

http://docs.oracle.com/cd/E23943_01/admin.1111/e15867/business_services.htm#i1141909

A cache-token value can be set in the $outbound/ctx:transport/ctx:request/ctx:cache-token element of the proxy service pipeline.


Setting the Cache Token at runtime

Let's consider a Department Finder web service that supports three operations.
(The web service can be built by following the steps in this earlier post ).

Here are the Java Methods that are exposed as a web service:
public DepartmentDetails getDepartmentDetails(String deptNumber) throws DepartmentFinderFault
public DepartmentDetails getDepartmentByMgrEmailId(String mgrEmailId) throws DepartmentFinderFault
public List<String>  getDepartments()

There is no common parameter in the three methods that can be used as a cache key.

We'll start from the DepartmentFinderProxy, which contains a branch node. 


Department
          Details Proxy


Each leg of the branch node contains a single Route action that calls the corresponding operation.

If we select the getDepartmentDetails link in the above diagram, OSB displays the getDepartmentDetails Branch.

GetDepartmentDetails Branch Leg


The branch contains a Route Node named RouteNode2.
In the Route Node, we will add a Request Action to fetch the parameter to be used as the cache key and set it in the Request.
Clicking on the RouteNode2 icon above, OSB displays the Route Node configuration below.



Route Node Insert
          Action


We add a new Request Insert Action to add the <tp:cache-token> element to the request in the $outbound context variable.
We specify that the  <tp:cache-token> element should be added after the existing <tp:headers> element.
The value of the token element is defined as an XPath expression that selects the correct parameter from the request. 
At runtime, the XPath expression will fetch the value of the deptNumber sent by the client and that value will be used as the unique
cache-token value for caching purposes.


We repeat this process for each Branch leg.  For example the next branch is the getDepartmentByMgrEmailId  branch

getDepartmentByMgrEmail Branch Leg


And it contains a Route Node named RouteNode3.



Route Node Two

The Insert action in the getDepartmentByMgrEmailId  route node is almost identical to the getDepartmentDetails route action.
The XPath expression has been modified to select the mgrEmailId from the request and use that as the cache-token value.

The third operation getDepartments has no parameters, so we can cache every result under the same cache-token value.
The cache-token expression can resolve to any value, as long as it does not conflict with the cache keys of other operations.
For example, a cache-token expression of  string(AllDepartments) would resolve to a string literal value of 'AllDepartments' 

    <tp:cache-token>
          string(AllDepartments)
    </tp:cache-token>

Once the Route node of each Branch operation has been configured it's time for a test.


Trace Examples

Here are some runtime trace examples:

The client  calls the getDepartmentDetails operation with a department id of 2,
The request and response are shown below.

Trace1


Further in the trace, we can see the Request contains  a <tran:cache-token> element with a value of 2, the department id sent by the client
This value is combined with the service name and operation name (as shown in the first diagram at the start of this article) to form a unique
key for the request and it's cached response.


Trace 1



Finally, near the bottom of the trace, we see the $outbound context has been updated to indicate that the request for department 2 details
was fulfilled, but not by the Cache.


Trace 2



The next test requesting the details of deparment 2 is fulfilled by the cache as shown below.


Trace Final


This example illustrated setting the Business Service cache-token at runtime.
This approach allows a different XPath expression to be used to generate a cachek-key value for each operation in a service.

The example in this article was tested using:
Oracle Service Bus Version: [Oracle Service Bus 11.1 Wed Apr 20 04:25:20 EDT 2011 1400736]
Oracle Weblogic Server Version: [WebLogic Server 10.3.5.0 Fri Apr 1 20:20:06 PDT 2011 1398638 ]


The completed example can be downloaded as a zip file from GitHub Here
See the ReadMe.txt file contained in the zip for installation instructions.