Wednesday, November 25, 2009

WSO2 ESB Tips & Tricks 02: Content Based Routing

Content based routing (CBR) is one of the most fundamental and widely used features of an ESB. Most integration scenarios involve situations where we need to analyze the content of a message and route it to a predefined endpoint based on the results. Depending on the actual requirements the ESB will have to inspect the message headers, message body or both.
For an example take a situation where you have two servers, server-A and server-B, that host an order processing service. Assume that server-A takes an hour to process an order whereas server-B takes over two hours. You could use something like WSO2 ESB to do CBR and provide a better service to the clients who are placing order requests on the servers. You can configure the ESB to analyze the request content and somehow identify the high priority requests based on a certain criteria. Such requests can be forwarded to server-A and the other requests can be forwarded to server-B. This way you can assure a better service to the clients who are placing high priority orders.
So how exactly do we implement a CBR scenario with WSO2 ESB? WSO2 ESB provides mediators like the filter mediator and the switch mediator for this task. I will now explain how to employ the filter mediator and get a simple CBR scenario up and running with WSO2 ESB.
Start the server and login to the management console. Click on “Sequences” and select the “Edit” option for the “main” sequence. Start by deleting all the child mediators already present in the sequence. To delete a mediator simply click on it and select the delete option from the little popup thingy that appears.
Now add an “In” mediator and an “Out” mediator to the sequence. Then add a “Filter” mediator as the first child of the “In” mediator. “Filter” mediator will appear on the editor with two more child mediators – “Then” mediator and the “Else” mediator. Let’s leave them as they are for the moment and configure the “Filter” mediator as follows.
On the “Filter” mediator configuration form (just below the editor window) select the “Source and Regular Expression” option. If you cannot see this form on your browser just click on the “Filter” mediator icon on the editor and it will appear on the screen. Specify the following parameters for the source and regular expression fields.
  • Source: //m0:getQuote/m0:request/m0:symbol
  • Regex: IBM
Now click on the “Namespaces” link and define the following namespace.
  • Prefix: m0
  • URL: http://services.samples
Exit the namespace editor popup and click on the “Update” button to save the changes made to the “Filter” mediator configuration. Now click on “Then” mediator and select the “Add Child” option from the little popup menu. Add a “Send” mediator as the child of the “Then” mediator. Specify an anonymous endpoint for the send mediator. Provide the address http://localhost:9000/services/SimpleStockQuoteService for the anonymous endpoint.
Once you are done with that click on “Else” mediator. Again add a “Send” mediator as a child. Specify the address http://localhost:9001/services/SimpleStockQuoteService as an anonymous endpoint for the send mediator.
Finally add another “Send” mediator as a child of the “Out” mediator which we added earlier. Do not specify any endpoints for that.


Save and close the sequence editor. We are now ready to run the scenario.
If you prefer to work with the Synapse configuration language and want to implement this scenario by manually editing the configuration you can use the following XML sequence configuration. Simply click on the “Synapse” link under “Configure” in the management console and locate the configuration for the “main” sequence. Replace it with the following XML snippet.
<syn:sequence name="main">
<syn:in>
<syn:filter xmlns:m0="http://services.samples" source="//m0:getQuote/m0:request/m0:symbol" regex="IBM">
<syn:then>
<syn:send>
<syn:endpoint>
<syn:address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
</syn:endpoint>
</syn:send>
</syn:then>
<syn:else>
<syn:send>
<syn:endpoint>
<syn:address uri="http://localhost:9001/services/SimpleStockQuoteService"/>
</syn:endpoint>
</syn:send>
</syn:else>
</syn:filter>
</syn:in>
<syn:out>
<syn:send/>
</syn:out>
</syn:sequence>
Before we run this scenario let’s try to figure out what it is supposed to do. The “In” mediator will take all the incoming requests and hand them over to the “Filter” mediator which evaluates an XPath expression on the content (Yes – this is the XPath we specified as the 'Source' parameter earlier. It simply extracts a text value from the SOAP payload). We extract a value from the message payload and perform a regular expression match on it (Out regex is “IBM”). If the regular expression matches, the message will be handed to the “Then” mediator or else it will be given to the “Else” mediator. Both these mediators invoke the “Send” mediator but on two different endpoints, so that the incoming requests are sent to one of two endpoints depending on the result of the XPath evaluation and the regular expression match. The “Out” mediator grabs all the responses coming back from the endpoints and invokes the “Send” mediator. Since we haven’t specified a target endpoint for this “Send” mediator, responses will be sent back to the clients based on the addressing information available on the message.
That sounds simple enough. Let’s run this scenario. First go to the directory ESB_HOME/samples/axis2Server/src/SimpleStockQuoteService and deploy the sample service by running the command “ant” (you need to have Apache ANT installed). Then go to ESB_HOME/samples/axis2Server and run the following two commands on two different shells/command prompts. (Run the commands applicable to your platform)

Unix/Linux:
./axis2server.sh –http 9000 –https 9005
./axis2server.sh –http 9001 –https 9006

Windows:
axis2server.bat –http 9000 –https 9005
axis2server.bat –http 9001 –https 9006

These two commands will start two Axis2 instances, one running on port 9000 and the other running on port 9001. To invoke the sample client go to ESB_HOME/samples/axis2Client and execute the following command.
ant stockquote –Daddurl=http://localhost:8280 –Dsymbol=IBM
This will send a message to the ESB with the string “IBM” in the payload. This will match the regular expression and hence will be forwarded to the server running on port 9000. Check out the console where you started that server instance for confirmation. You should see something like this.
Wed Nov 25 18:48:57 IST 2009 samples.services.SimpleStockQuoteService :: Generating quote for : IBM
Now again invoke the client as follows.
ant stockquote –Daddurl=http://localhost:8280 –Dsymbol=MSFT
This will send a message to the ESB with the string “MSFT” in the payload and voila! The regular expression match will fail causing the message to be forwarded to port 9001. Check the Axis2 log for confirmation.
Wed Nov 25 18:48:49 IST 2009 samples.services.SimpleStockQuoteService :: Generating quote for : MSFT
So there you go – CBR made easy by WSO2 ESB. The filter mediator brings if-else like semantics into the mediation logic. The ESB also has a switch mediator. Just guess what semantics that can bring into the mediation. And then of course we have the router mediator to implement complex CBR scenarios. If you are interested in learning more about CBR support available in WSO2 ESB then you can have a look at the following samples. These 2 samples are shipped with WSO2 ESB so you can try them out all by yourself.

2 comments:

Marta y Miguel said...

Hi,

I´m interested in WSO2 solution as a flow control "proxy" (maybe some content control), means configuring and monitoring communication between systems (through webservices), in order to prevent congestion fails.

Right now i´m trying WSO2, starting with examples comes with binary distribution, but I don´t have clear is if it allows me to configure, for example, how many messages is each system able to receive in a minute.

You also can send me any advice at this email address: quieresqueso@gmail.com

Regards!

Hiranya Jayathilaka said...

Hi Marta,

WSO2 ESB provides throttling capabilities through its throttle mediator. Throttling rules are specified as a WS-Policy document. You can have a look at the following samples to get an idea:

http://wso2.org/project/esb/java/2.1.2/docs/samples/advanced_mediation_samples.html#Sample370
http://wso2.org/project/esb/java/2.1.2/docs/samples/advanced_mediation_samples.html#Sample371
http://wso2.org/project/esb/java/2.1.2/docs/samples/advanced_mediation_samples.html#Sample372

Sample 370 shows how to restrict the number of concurrent requests through the ESB using the throttle mediator.

Please feel free to contact the team through our mailing lists and free forums if you need more info.

Thanks,
Hiranya