Message Content Filtering with WSO2 ESB
Every integration architect or developer should be familiair with Enterprise Integration Patterns (EIP) as described by Gregor Hohpe and Bobby Woolf. One of the patterns is the ‘Content Message Filter’ (not to be confused with the Message Filter pattern).
There are multiple ways to achieve this in WSO2 with different Mediator. One way is using the XSLT Mediator where you can simply use an XSLT to do the filtering. The other one (not so obvious based on the name of it) is the Enrich Mediator.
Here is an example how to use the Enrich Mediator for this. Imagine the original the message is:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tmp="http://www.pascalalma.net/order"> <soapenv:Header/> <soapenv:Body> <tmp:message> <tmp:document> <tmp:order> <tmp:id>123</tmp:id> </tmp:order> </tmp:document> </tmp:message> </soapenv:Body> </soapenv:Envelope>
What we actually want is a Soap message with just the ‘order’ element as payload. We can accomplish that with the Enrich mediator with the following configuration:
<enrich xmlns:tmp="http://www.pascalalma.net/order"> <source clone="false" type="custom" xpath="//tmp:document/*" /> <target action="replace" type="body" /> </enrich>
So with this configuration we tell the mediator it should take content of the ‘document’ element as the source and to put this content in the body of the incoming SOAP message.
When you choose to use the XSLT Mediator instead here is an example XSLT that can be used to remove certain elements from a XML document. You can use it on the following XML message:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tmp="http://www.pascalalma.net/order"> <soapenv:Header/> <soapenv:Body> <tmp:message> <tmp:document> <tmp:order> <tmp:id>123</tmp:id> <tmp:type>backorder</tmp:type> <tmp:status>open</tmp:status> <tmp:description>open</tmp:description> </tmp:order> </tmp:document> </tmp:message> </soapenv:Body> </soapenv:Envelope>
If we want this same XML document but then without the elements ‘tmp:type’ and ‘tmp:description’ we can define the XSLT Mediator like this:
<xslt key="xslt/remove-elements-v1.xslt" description="remove unwanted elements"> <property name="removeElementsNamed" value="type,description" /> </xslt>
The XSLT code that makes this work (I found it on the stackoverflow site):
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="no" indent="yes" encoding="UTF-8"/> <xsl:strip-space elements="*"/> <xsl:param name="removeElementsNamed" /> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="*[local-name()=tokenize($removeElementsNamed,'[\|, \t]')]"/> </xsl:stylesheet>
Please note that this XSLT doesn’t take namespaces into account and simply removes all elements whose local-name matches the supplied names!
Reference: | Message Content Filtering with WSO2 ESB from our JCG partner Pascal Alma at the The Pragmatic Integrator blog. |