Month: October 2012

Normalizer Message Transformation Pattern With WSO2 ESB

Introduction

The Normalizer is used in scenario where ESB has to mediate different types of message formats and get the service of a certain endpoint service which support only a single format of messages. In a business-to-business (B2B) integration scenario it is quite common for an enterprise to receive messages from different business partners. These message may have the same meaning, but follow different formats, depending on the partners’ internal systems and preferences. For example, we built a solution for a pay-per-view provider that has to accept and process viewership information from over 1700 (!) affiliates, most of which did not conform to a standard format.

Therefore ESB needs to identify those formats and send the responses back in the same format. In such case client application and back-end service do not have to worry about message type because Message Builders and Message Formatters in WSO2 ESB do that on behalf of them.

Implementation Using the WSO2 ESB

Prerequisites
  • Start the WSO2 ESB with the following configuration
  • Start the Axis2 server and deploy the SimpleStockQuoteService if not already deployed.
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">

<!-- The proxy service to receive all kinds of messages -->
<proxy name="ServiceProxy" transports="https http" startOnLoad="true" trace="disable">
<target>
<inSequence>
<log level="full"/>

<!-- Filters incoming JSON messages -->
<filter xmlns:m0="http://services.samples" xpath="//m0:getQuote/m0:request/m0:symbol">
<then>
<sequence key="sendSeq"/>
</then>
<else>
<sequence key="jsonInTransformSeq"/>
</else>
</filter>

</inSequence>

<outSequence>

<!-- Filters outgoing JSON messages -->
<filter source="get-property('TRANSFORMATION')" regex="JSONtoSOAP">
<then>
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
</then>
</filter>

<log level="full"/>
<send/>

</outSequence>

</target>
</proxy>

<localEntry key="in_transform">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
xmlns:m0="http://services.samples"
version="2.0"
exclude-result-prefixes="m0 fn">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="http://services.samples">
<xsl:copy-of select="attribute::*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
</localEntry>

<!-- Transform a JSON message -->
<sequence name="jsonInTransformSeq">
<xslt key="in_transform"/>
<property name="TRANSFORMATION" value="JSONtoSOAP" scope="default" type="STRING"/>
<sequence key="sendSeq"/>
</sequence>

<!-- Normal flow of messages -->
<sequence name="sendSeq">
<send>
<endpoint>
<address uri="http://localhost:9000/services/SimpleStockQuoteService" format="soap11"/>
</endpoint>
</send>
</sequence>

<sequence name="fault">
<log level="full">
<property name="MESSAGE" value="Executing default 'fault' sequence"/>
<property xmlns:ns="http://org.apache.synapse/xsd" name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
<property xmlns:ns="http://org.apache.synapse/xsd" name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
</log>
<drop/>
</sequence>

<sequence name="main">
<log/>
<drop/>
</sequence>

</definitions>

In the above synapse configuration first filter-out JSON messages to do necessary transformation and then add to the normal message flow since back-end service only know SOAP. In out sequence also it filters the JSON messages separately in-order to do necessary transformation. Major part of these transformation is done at code level. You can test this configuration for JSON, SOAP, POX messages by using sample axis2client shipped with WSO2ESB.

For SOAP

ant stockquote -Dtrpurl=http://localhost:8280/services/ServiceProxy

For POX – In here the XML message contains exactly the format that the service wants. Else you need to use Payload Factory Mediator to create required message from incoming message.

ant stockquote -Dtrpurl=http://localhost:8280/services/ServiceProxy

For JSON

ant jsonclient -Daddurl=http://localhost:8280/services/ServiceProxy

References

[1] WSO2 ESB – http://wso2.com/products/enterprise-service-bus/

[2] ESB Samples – http://docs.wso2.org/wiki/display/ESB450/Samples

[3] Normalizer EAI pattern – http://www.eaipatterns.com/Normalizer.html

Advertisements

Connect WSO2 ESB with WSO2 MB

Introduction

WSO2 Enterprise Service Bus (WSO2 ESB) and WSO2 Message Broker (WSO2 MB) plays very important role in opensource Enterprise Application Integration. With WSO2 ESB, WSO2 MB can be used for 2 different tasks.

1. JMS Endpoint

2. Message Store

In here I’m talkng about connecting WSO2 ESB with WSO2 MB 1.0.2 as a JMS endpoint. It will also shows how WSO2 ESB exhibits Message Broker EAI pattern. Basically it does is decoupling messages from sender and receiver. Senders message is put into a Message Broker and any receiver who interested in those messages can consume. In following example you can see how WSO2 ESB  works with WSO2 Message Broker (WSO2 MB version 1.0.2) Queue to do that. If you want to add more receivers you can use Topics provided in WSO2 MB in a similar way.

Prerequisites

Setting up WSO2 MB

<Ports>
<Offset>1</Offset>
...
  • Change default virtual host to “carbon” inside wso2mb-1.0.2/repository/conf/advancedqpid-virtualhosts.xml file.
<virtualhosts>
 <default>carbon</default>
...
  • Start WSO2 MB by executing wso2server.sh (or wso2server.bat in Windows) file in wso2mb-1.0.2/bin

Setting up WSO2 ESB

  • Copy geronimo-jms_1.1_spec-1.1.0.wso2v1.jar and qpid-client-0.11.0.wso2v2.jar from wso2mb-1.0.2/client-lib to wso2esb-4.5.1/repository/components/lib
  • Enable jms transport Receivers and Senders by uncomment related sections as given below in file wso2esb-4.5.1/repository/conf/axis2/axis2.xml
<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
 <!--Only Enabled settings related to Queue since the sample here only uses a queue-->
 <parameter name="myQueueConnectionFactory" locked="false">
 <parameter name="java.naming.factory.initial" locked="false">org.apache.qpid.jndi.PropertiesFileInitialContextFactory</parameter>
 <parameter name="java.naming.provider.url" locked="false">repository/conf/jndi.properties</parameter>
 <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
 <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
 </parameter>
 <parameter name="default" locked="false">
 <parameter name="java.naming.factory.initial" locked="false">org.apache.qpid.jndi.PropertiesFileInitialContextFactory</parameter>
 <parameter name="java.naming.provider.url" locked="false">repository/conf/jndi.properties</parameter>
 <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
 <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
 </parameter>
</transportReceiver>
.........
<transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender"/>
  • Set wso2esb-4.5.1/repository/conf/jndi.properties file as follows.
.....
#Need change QueueConnection factory as follows
connectionfactory.QueueConnectionFactory = amqp://admin:admin@clientID/carbon?brokerlist='tcp://localhost:5673'

# register some queues in JNDI using the form
# queue.[jndiName] = [physicalName]
destination.myqueue=destinationMyQueue; {create:always}

# register some topics in JNDI using the form - Commented since this sample is not going to use Topics
# topic.[jndiName] = [physicalName]
#topic.MyTopic = example.MyTopic
  • Now start WSO2 ESB by executing wso2server.sh (wso2server.bat in Windows) inside wso2esb-4.5.1/bin
  • Change the configuration of ESB to the following.
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
 <proxy name="StockQuoteProxy"
 transports="http"
 startOnLoad="true"
 trace="disable">
 <description/>
 <target>
 <!-- Send message to WSO2 MB -->
 <endpoint>
 <address uri="jms:/myqueue?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&amp;java.naming.factory.initial=org.apache.qpid.jndi.PropertiesFileInitialContextFactory&amp;java.naming.provider.url=repository/conf/jndi.properties&amp;transport.jms.DestinationType=queue"/>
 </endpoint>
 <inSequence>
 <property name="OUT_ONLY" value="true"/>
 <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
 <property name="transport.jms.ContentTypeProperty"
 value="Content-Type"
 scope="axis2"/>
 </inSequence>
 <outSequence>
 <property name="TRANSPORT_HEADERS" scope="axis2" action="remove"/>
 <send/>
 </outSequence>
 </target>
 </proxy>
 <sequence name="fault">
 <log level="full">
 <property name="MESSAGE" value="Executing default "fault" sequence"/>
 <property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
 <property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
 </log>
 <drop/>
 </sequence>
 <sequence name="main">
 <log/>
 <drop/>
 </sequence>
</definitions>

The JMS URL is made up of:

jms:/myqueue

Look for a JNDI entry “myqueue”(see jndi properties above)

?   Separator indicating extra attributes

transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory

Look up ConnectionFactory in JNDI with name QueueConnectionFactory

&            Separator (this will convert to ‘&’)

java.naming.factory.initial=org.apache.qpid.jndi.PropertiesFileInitialContextFactory

Use the Qpid properties-based JNDI

&             Another separator

java.naming.provider.url=repository/conf/jndi.properties

Look in repository/conf/jndi.properties for the JNDI properties file

Now you  can send messages from sample/axis2Clint as follows to the ESB proxy and they will get stored in WSO2 MB.

ant stockquote -Dtrpurl=http://localhost:8280/services/StockQuoteProxy -Dsymbol=WSO2

The stored message can be consumed by any consumer who is keen on destinationMyQueue of WSO2 MB.

References

[1] WSO2 ESB – http://wso2.com/products/enterprise-service-bus/

[2] WSO2 MB – http://wso2.com/products/message-broker/

[3] Introduction to Message Broker – http://pzf.fremantle.org/2011/04/introduction-to-wso2-message-broker_05.html

[4] Pub/Sub in SOA – http://wso2.org/library/articles/2011/12/wso2-esb-example-pubsub-soa