Friday, January 4, 2013

Writing a Custom Mediator for WSO2 ESB - Part 2

Let's continue from the previous post, Part 1. As there were several changes and fixes happened to BAM mediator, there we are taking the example of two latest components,
  1. org.wso2.carbon.mediator.bam version 4.0.5 - backend component
  2. org.wso2.carbon.mediator.bam.ui version 4.0.5 - UI component
As you can see, there is no services.xml file exists in the backend component. There are two files namely org.apache.synapse.config.xml.MediatorFactory and org.apache.synapse.config.xml.MediatorSerializer containing the class names (with package name) of Mediator Factory and Mediator Serializer. Let's discuss the usage of these 2 classes.

Mediator Factory

In WSO2 ESB, each mediator is created using the Factory design pattern. When the ESB starts each mediator is created using a Mediator Factory. The programmer is given the opportunity to write the Mediator Factory as a single class. In this example, the factory class is org.wso2.carbon.mediator.bam.xml.BamMediatorFactory that contains all the instantiating code relevant to the mediator. Factory class is the code that generates the mediator based on the mediator XML (XML specification of the mediator in the ESB sequence). In this factory the configuration information should be extracted from the XML and should create a mediator based on that configuration.

public Mediator createSpecificMediator(OMElement omElement, Properties properties) {


This method should be implemented which takes the XML as an OMElement and returns the Mediator to be produced. Here it is an instance of the BamMediator class we have defined in the parent package.
And also in this method it can access the secondary storage (e.g.: Registry) as the method is not performance critical. (This method will run only at the creation stage of a mediator.)

public QName getTagQName() {


This method should also be implemented to return the QName of the XML of the specific mediator. In BAM mediator it has the name "bam".

Mediator Serializer

Mediator Serializer does the reverse of the Mediator Factory. It creates the XML, related to the mediator, back from the Mediator class. (Here it is from BamMediator)

public OMElement serializeSpecificMediator(Mediator mediator) {


This method should implement which does the above said conversion. (serialization) It takes the Mediator and returns the generated XML, related to the mediator.

public String getMediatorClassName() {


And also this should be implemented to return the Mediator's class name.

Now let's start discuss about the most important class, the Mediator class, here the BamMediator class.

Mediator Class

This is the class used while the ESB is running for the purpose of mediation. As this class is executed in run time it should be designed with care avoiding unnecessary performance degrading actions. And also because this class is executed in parallel threads, should be careful on concurrency issues and make them thread safe.
Mediator class should always extend the AbstractMediator class.

public boolean isContentAware() {
    return true;

The above method must be included in the Mediator class if the mediator is intended to interact with the MessageContext.
mediate is the most important method that should be implemented.

public boolean mediate(MessageContext messageContext) {


mediate method is given the MessageContext of the message, which is unique to an each request passing through the mediation sequence. The return boolean value should be true if the mediator was successfully executed and false if not.

Note that global variables in the Mediator class may cause race condition as different threads of the mediation sequence may access the same global variable. It can be prevented by one of the following techniques.
  1. Using local variables inside the method
  2. Storing variables in the MessageContext as Properties
  3. Using thread local variables
Best way to handle this issue is possible with first technique if the mediator is not that complex. And the third technique should be used with care if want to use due to the risk of memory leaks.

Let's discuss about the UI package in the next part (Part 3).

No comments:

Post a Comment