Pages

Thursday, January 17, 2008

anyType xml message routing in ESB

For a customer I had to route the several different xml messages of a message handling system to the right backoffice database. I want to do this with the esb soa suite, so I need xml schema's of these message to map the data. I can use for every xml message type a different queue so I can use this specific message schema and maps this with xsl to the right db adapter. Or I can make one big schema where all messages types are included, but this is not so right because with every change in one of schema's I have to test the whole system.
Let's use xs:anyType for the xml messages. Now I don't know in the esb the structure of the xml messages. The solution is to make a main router where we use the filters and a specific xsl to extract anytype and map this to the right xsd in the next router, This router maps the data with a xsl to the db adapter.
The example main schema looks like this.

Here are two xml messages examples.

<ns1:Message xsi:schemaLocation="http://ordina.nl/esb message.xsd" xmlns:ns1="http://ordina.nl/esb" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:RunID>100</ns1:RunID>
<ns1:MessageType>A</ns1:MessageType>
<ns1:Data>
<MessageA>
<Text>this message A</Text>
</MessageA>
</ns1:Data>
</ns1:Message>


<ns1:Message xsi:schemaLocation="http://ordina.nl/esb message.xsd" xmlns:ns1="http://ordina.nl/esb" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:RunID>200</ns1:RunID>
<ns1:MessageType>B</ns1:MessageType>
<ns1:Data>
<MessageB>
<Text>this message B</Text>
<SubMessageB>
<Text>this message B</Text>
</SubMessageB>
</MessageB>
</ns1:Data>
</ns1:Message>

Let's do this in the 10.1.3 esb. I use for this example file adapters. Make a esb project and start by dragging the file adapter to the esb file. The file adapters reads the xml's in a directory and this file adapter is based on the anytype message schema.

Now we need to make a xsl where we extract the anytype to a new xml. This is how the xsl looks.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:n="http://ordina.nl/esb" xmlns="http://ordina.nl/esb">
<xsl:template match="/n:Message">
<xsl:for-each select="n:Data">
<xsl:copy>
<xsl:attribute name="RunID"><xsl:value-of select="//n:RunID"/></xsl:attribute>
<xsl:attribute name="MessageType"><xsl:value-of select="//n:MessageType"/></xsl:attribute>
<xsl:copy-of select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Let's apply this xsl to the two mail handling messages and generate ( I use Altova xmlspy) two new schema's on the new xml's, we need these schema for the specific routers. Now we can make the outgoing message A file adapter, use the new schema message A and make a messageA Router too. Use for this router also the new schema message A. Make a routing rule between the message A router and the message A file adapter.

We can do the same for the xml message B.

Now we have to make the routing rules on the main router. First we set the filters. We test the ns1:MessageType element if it equals A or B.
Then we make a xsl where we add the namespaces of the above xsl and replace the standard xsl:template with the xsl:template of the above xsl. See picture below for the xsl. This xsl can we use by all the main router rules.

The esb diagram looks like this, you can deploy it to the esb server and put xml message A or message B in the In folder. The esb puts now the messages in the right Out folder.

Here you can download the esb example project

No comments:

Post a Comment