Tuesday, May 26, 2015

Database interaction WSO2 ESB

Database interaction WSO2 ESB

Lets say we have a requirement of getting the data (eg: may be configuration information) from database and store the same in a cache. This should be a onetime activity where we don’t want to interact with the database for every request. The newly created cache should be accessed for any further request in order to get the configuration information instead of from the database.

In this post I'm trying to explain you what are the options available and how to achieve the above requirement.

There are 2 options available to cater this requirement
  1. Cache Mediator
  2. Custom Mediator

Cache Mediator

Refer : https://docs.wso2.com/display/ESB481/Cache+Mediator
You can retrieve the values from database using a DB Lookup Mediator and cache the result.
And when the next request comes, it should only execute the dblookup mediator when the cache is empty.
But please note that using a DB lookup mediator you can retrieve only one data row from the database.


Custom Mediator 

Refer : https://docs.wso2.com/display/ESB470/Sample+380%3A+Writing+your+own+Custom+Mediation+in+Java
You can write a custom mediator to implement this requirement. Here you do not need a DB lookup mediator. And what this custom mediator would do is, it should have a cache and when a requests comes, if the cache it empty it should retrieve the data from the database directly. else it should use the cached values and update the messageContext properties. please refer the sample.


//Please note that this is only a sample code for you to get a basic idea

package org.example.mediator;

import org.apache.synapse.MessageContext;
import org.apache.synapse.Mediator;
import org.apache.synapse.mediators.AbstractMediator;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.soap.SOAPBody;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.cache.Cache;

import javax.xml.namespace.QName;

public class MyMediator extends AbstractMediator {

    private static final Log log = LogFactory.getLog(MyMediator.class);

    public MyMediator(){}

    public boolean mediate(MessageContext mc) {
      if( getDBValueCache().get(“dbValueCache”) == null){
//retrieve values from db
//update cache
}
//set values as MessageContext properties
return true;
    }

    private Cache getDBValueCache() {
return Caching.getCacheManager(“dbValueCache".getCache(“dbValueCache”);
    );
}




If you need to further improve the code and to load the values when synapse initializes, you can implement the ManagedLifecycle interface in your class mediator and implement the init() method to load the required data.

import org.apache.synapse.ManagedLifecycle;
public class MyMediator implements Mediator, ManagedLifecycle {
public void init(SynapseEnvironment synapseEnvironment)
public void destroy() {
}
// mediation logic here
@Override
{ // perform initialization here }
@Override
}

If you are using this in multiple places, there will be multiple instances of the class mediator created for each declaration of the class mediator in synapse configurations. Hence there will be multiple copies of the cache as well. If you need to eliminate having multiple copies, you can make the cache/map static.


2 comments:

  1. can you please get me the example or any reference link

    ReplyDelete
    Replies
    1. Please refer these articles for more information regarding custom mediators:
      https://docs.wso2.com/display/ESB470/Sample+380%3A+Writing+your+own+Custom+Mediation+in+Java

      http://wso2.com/library/2898/

      You can also use the WSO2 Developer Studio to make this more easier.

      Delete