Wednesday, November 4, 2015

How to use Cache Mediator in WSO2 ESB

Cache mediator in WSO2 ESB used when we see same type of message again and again and also process with same output. In this scenario if we want to optimize our ESB performance, we can use cache mediator. Cache mediator checks if the same type of message has been processed before, it cashes the message and on the same request mediator gets the message from the cache and reply back.


Cache mediator uses the hashes for checking the equivalence the message. In cache mediator you can define the cache response time and message size in bytes.

Test Case:

In our test case, we will use same service I have created in my last blog. Basically it is a data service and we have created a pass through proxy of this DSS service in ESB. This service gives the employee details based on the Employee Id.

We will try to cache the DSS response in ESB so that on same request of ESB does not hit the DSS server and reply the cached response to the client.

To understand whether cache is working fine or not, I will change the employee details in Database but change should not reflect in our response till message is cached. We are assuming that ESB cache Mediator will not hit the DSS and it will give response from the cached message.

Below is the DSS service I have created in my last blog.


Below is the ESB service, pass through proxy of DSS.


Service gives the details of employee based on the Employee Id. Below is the SOAP UI request and response of ESB pass through proxy.


 To use the caching mediator I am going to sequences and updating the IN Sequence of this service.


You can add Cache mediator in Advance group.


Below are the fields you need to fill to use Cache mediator.


  • Cache Id: This is the cache id for the configuration.
  • Cache Scope: It is important when you are using cluster.
    • Per Host: It Cache the message for the current host of the cluster.
    • Per-Mediator: It Cache the message once for the whole cluster.
  • Cache Type: It is used to check the message is coming from the request or we need to cache the response for outgoing message.
    • Finder: When message needs to be cached from incoming path, it hash the each incoming message.
    • Collector: It indicates the message needs to be collected from cached message. It is used for outgoing path.
  • Hash Generator: It is by default selected to org.wso2.caching.digest.DOMHASHGenerator and it has the hash logic to check each incoming message.
  • Cache Timeout:  We need to specify the timeout in seconds that how much we want to cache the message.
  • Maximum Message Size: The limit of cache message in bytes.
Cache Implementation Details
  • Implementation Type: Default to set “In-Memory” and this is the only available.
  • Maximum Size: 1000 is default selected.
On Cache Hit: It basically tells that which sequence needs to be followed from registry.

Now edit the out sequence as defined below.


Specify the Cache id, cache Scope and Cache Type. In out sequence we are using “Collector” Cache type because we need to get the response from cache in out going message.


Now we check that what is there in our database. You can see that for Employee Id 1, we have Employee Name as ‘Shri’ and address is ‘Delhi’ as highlighted in Yellow.


Let see what we are getting in SOAP UI response.


Same thing we are getting in response and in one hit the response is cached.
Now I am going to change the address from “Delhi” to “Noida” as below.


Now if you try within 20 second, this is what we have mentioned in our cache response. We should be getting same response.


And Yes, as above we are getting the same response because response is cached we it is not coming from DSS server. If we hit just after 20 second we can see the address is now updated from “Delhi” to “Noida”.


Now this response will be cached till net 20 second in each hit.

You can see that from the IN sequence we are getting the response.



ESB Synapse Code:

<proxy name="DSS_EmployeeDetailDataServiceProxy" transports="http" startOnLoad="true" trace="disable" statistics="enable">
  <target inSequence="DSS_EmployeeDetailDataService_IN" outSequence="CommonSequence_OUT" faultSequence="DSS_EmployeeDetailDataService_Fault"/>
        <publishWSDL key="DSS_EmployeeDetailDataService_wsdl"/>
    </proxy>
<localEntry key="DSS_EmployeeDetailDataService_wsdl" src="file:repository/conf/employee/EmployeeDetailDataService.wsdl"/>
   
    <sequence name="DSS_EmployeeDetailDataService_Fault">
        <log level="full"/>
        <payloadFactory>
            <format>
                <shr:employees xmlns:shr="http://shriwithjava.blogspot.co.nz/">
                    <shr:employee>
                        <shr:id>Exception has been caught</shr:id>
                        <shr:name>Exception has been caught</shr:name>
                        <shr:address>Exception has been caught</shr:address>
                    </shr:employee>
                </shr:employees>
            </format>
        </payloadFactory>
        <property name="RESPONSE" value="true"/>
        <header name="To" action="remove"/>
        <send/>
        <drop/>
    </sequence>
    <sequence name="DSS_EmployeeDetailDataService_IN">
        <log level="full"/>
        <cache id="GetEmpDetailCache" scope="per-host" collector="false" hashGenerator="org.wso2.caching.digest.DOMHASHGenerator" timeout="20" maxMessageSize="500">
            <implementation type="memory" maxSize="1000"/>
        </cache>
        <send>
            <endpoint key="DSS_EmployeeDetailDataService_EPR"/>
        </send>
    </sequence>
    <sequence name="CommonSequence_OUT">
        <log level="full"/>
           <cache id="GetEmpDetailCache" scope="per-host" collector="true"/>
           <send/>
    </sequence>
   <endpoint name="DSS_EmployeeDetailDataService_EPR">
        <address uri="http://10.251.162.192:9763/services/EmployeeDataService">
            <timeout>
                <duration>10000</duration>
                <responseAction>fault</responseAction>
            </timeout>
            <suspendOnFailure>
                <errorCodes>101500,101501,101506,101507,101508</errorCodes>
                <initialDuration>3000</initialDuration>
                <progressionFactor>1.0</progressionFactor>
            </suspendOnFailure>
            <markForSuspension>
                <errorCodes>101504,101505</errorCodes>
                <retriesBeforeSuspension>3</retriesBeforeSuspension>
                <retryDelay>1</retryDelay>
            </markForSuspension>
        </address>
    </endpoint>