Sunday, August 31, 2014

[WSO2 ESB] Enrich Mediator Patterns

WSO2 ESB Enrich Mediator can process a message based on a given source configuration and then perform the specified action on the message by using the target configuration. The following post specifies some of the source/target patterns that can be used with Enrich mediator. The flow is explained in 'description' element of each mediator entry to make it easily understandable.

1. Adding a property value into message body as a sibling

<property name="failureResultProperty" scope="default" description="FailureResultProperty">
        <result xmlns="">failure</result> 

</property>
<enrich>
        <source xpath="$ctx:failureResultProperty"/>
        <target type="body" action="sibling"/> 

</enrich>   
   
2. Append new elements into a property using two enrichs

<property name="testMessages" scope="default" description="Test Messages Property">
        <
testMessages/> 
</property>
          
<property name="testMsg" expression="//testMessage" scope="default" type="OM"/>

<enrich description="Get testMessages into current msg body">
            <source type="property" property="testMessages"/>
            <target type="body"/> 

</enrich>
<enrich description="Append testMsg into testMessages property">
            <source xpath="$ctx:testMsg"/>
            <target type="body" action="child"/> 

</enrich>

<property name="testMessages" description="Set testMessages property back"  expression="//testMessages" scope="default" type="OM"/>
       
       
The final output for 'testMessages' property after enriching will be like this.

 




 
3 . Append direct to a property using single Enrich.
   
<property name="testMessages" scope="default" description="Test Messages Property">
        <
testMessages/> 
</property>
<enrich>
            <source xpath="//testMessage"/>
            <target action="child" xpath="$ctx:testMessages"/>
 </enrich>

    

[WSO2 ESB] How to Read Local Entries and Registry Entries

This post is rather a quick note to my self. In WSO2 ESB we can have external reference to a file using either a local entry or a registry entry. 

Local-entry :

An entry stored in the local registry. The local registry acts as a memory registry where you can store text strings, XML strings, and URLs. These entries can be retrieved from a mediator.

Registry-entry :
WSO2 ESB makes use of a registry to store various configurations and artifacts such as sequences and endpoints. A registry is a content store and a metadata repository. Various SOA artifacts such as services, WSDLs, and configuration files can be stored in a registry and referred to by a key, which is a path similar to a UNIX file path.

1. This is how we can read some value stores in a local-entry. Let's say i have a value stored in local-entry file 'testEntry'.

<localEntry xmlns="http://ws.apache.org/ns/synapse" key="testEntry">12345</localEntry>

 This is how we can read this value into a mediator.

<property name="testProp" expression="get-property('testEntry')" scope="default" type="STRING"/>

2. If this 'testEntry' file is stored in the registry we have to use 'registry' scope with get-property() XPath extension function and read entry as below.

<property name="testProp" expression="get-property('registry', 'conf://custom/testEntry')" scope="default" type="STRING"/>

[WSO2 ESB] Property mediator : Performing XPath Expressions with and without Namespaces

Assume that we have an XML payload where there are several namespaces defined and we need to retrieve values of some elements from the payload into Properties using XPath. There are several ways to do this. We can either define the namespace in the property mediator and then refer to XML element via XPath with adding the namespace itself into the Xpath operation. let's get started with this.

Below is our payload.

<abc  xmlns="http://abc.xyz.com" >
         <A>YES</A>
         <B>{"abc":"Y","d":"N","e":"N"}</B>
</abc>

For e.g i need to read the value 'A' into a property.  Following are the two ways for this However the 2nd option is more cleaner approach since we can get rid of adding namespace references every where. In addition to Property mediator, this can be used with other mediators in WSO2 ESB whether XPath operations are supported.

1. Use name space entries with property mediator

<property  xmlns:ns="http://abc.xyz.com" name="aValue" expression="//ns:abc/ns:A" scope="default" type="STRING"/>

2. Use local-name() option in XPath in order to avoid name spaces and get the same element value with property mediator.

<property name="aValueWithoutNS" expression="//*[local-name()='A']" scope="default" type="STRING"/>


 

[WSO2 ESB] XSLT mediator : Writing a simple style sheet

The XSLT Mediator of WSO2 ESB applies a specified XSLT transformation to a selected element of the current message payload. In this post i am going to write a simple XSLT style sheet which will read values from the current XML payload inside ESB using XPath and populate them into style sheet to create a new or different payload.

Below is our original XML payload.



We will be passing this payload into XSLT mediator with specifying a certain drink name as a parameter to the style sheet. For e.g i am passing drink name as 'Coffee'. At the style sheet it will traverse through incoming payload and find the <lunch> elements which contains 'Coffee' as drink name. If matches found we add the prices of those elements under a new <Payment> element. So when we come out of XSLT mediator the payload will be now changed to the <Payment> entry where it contains drinkPrices of matching elements.

The style sheet 'discountPayment.xsl' is like this.

<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:param name="drink_name"/>
        <xsl:template match="/">
            <Payment>
                <xsl:for-each select="//Order/lunch[contains(drinkName, $drink_name)]">
                    <discount>
                        <xsl:value-of select="drinkPrice"/>
                    </discount>
                </xsl:for-each>
            </Payment>
        </xsl:template>
</xsl:stylesheet>

Add this style sheet into local-entries of ESB and it can be referred from XSLT mediator as this.

After coming out from XSLT mediator now our current message payload is changed to below.


[WSO2 ESB] Using [resource] attribute for [xsd:import] elements in a scheme file with Validate Mediator

The Validate Mediator in WSO2 ESB is used for schema validation of messages. Then this message is validated against the schema specified.

When we use validate mediator against a schema that schema file itself can contain some other schema references under <xsd:import> elements like below.


If our schema file is like this, in this scenario validate mediator tries to map and find the internal schemas which are defined in <xsd:import> elements. If these cannot be found, ESB will log an error saying that "The resource "{resource_file_name} can not be located"

Therefore in order to use these schema files with validate mediator follow the steps given below.

1. First add all the xsd files as local entries to ESB. These is no relative paths or nested folders supported so the xsd files has to be in local-entries folder itself. However if you put the schemas into registry nested folders are supported.

2. In the validate mediator there is an attribute called <resource>. Use this option to tell the validate mediator on where to find the files to import as below. Make sure ‘location’ and ‘schemaLocation’ entries has the same file name in order to map those correctly. Then the 'key' attribute is used to specify the current location of this schema file as shown in the given exmaple.


If you have added the schema files as registry entries, and when there are relative paths mentioned in parent schema, validate mediator can be used in  the following manner.