Wednesday, February 17, 2016

[WSO2 ESB]Invoke Contentful API

Lets say we want to invoke Contentful API which contains the response with Content-Type:application/vnd.contentful.delivery.v2+json

1. First we tried setting the Accept header before send the message. But that didn't change the Content-Type of the  server response.
<header name="Accept" scope="transport" value="application/json"/>
2. The second attempt was to set the BinaryRelayBuilder and ExpandingMessageFormatter in the axis2.xml file under <messageBuilders> and <messageFormatters> sections.
<messageBuilder class="org.wso2.carbon.relay.BinaryRelayBuilder" contentType="application/vnd.contentful.delivery.v2+json"/>
<messageFormatter class="org.wso2.carbon.relay.ExpandingMessageFormatter" contentType="application/vnd.contentful.delivery.v2+json"/>
Now the message building error solved. But the response contains in binary format.
Eg:
<ns:binary xmlns:ns="http://ws.apache.org/commons/ns/payload">-------CAgIH0KICAgICAgICBdCiAgICAg--------</ns:binary>
3. Finally we used the default json builder and formatter with our contentful media type(application/vnd.contentful.delivery.v2+json) to resolve the issue. (make sure to remove the configuration added in above 1 and 2 steps)
Eg:
<messageBuilder class="org.apache.synapse.commons.json.JsonStreamBuilder" contentType="application/vnd.contentful.delivery.v2+json"/>
<messageFormatter class="org.apache.synapse.commons.json.JsonStreamFormatter" contentType="application/vnd.contentful.delivery.v2+json"/>

Thursday, February 11, 2016

[WSO2 ESB] How to remove default namespace at message enrich.

1.Lets say we need to add new element (eg: foo) to the message body using enrich mediator.

<enrich>
 <source type="inline" clone="true">
 <foo>test</foo>
</source>
<target type="body" action="child"/>
</enrich>
2. After enriched, the  message will be as bellow.
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
    <soapenv:Body>
        <foo xmlns="http://ws.apache.org/ns/synapse">test</foo>
    </soapenv:Body>
</soapenv:Envelope>
3. You can see foo element contains with default synapse namespace.
4. You can avoid this adding empty namespace (xmlns="") to foo element in enrich mediator configuration.
<enrich>
 <source type="inline" clone="true">
 <foo xmlns="">test</foo>
</source>
<target type="body" action="child"/>
</enrich>

Friday, February 5, 2016

[WSO2 ESB] How to remove jsonObject root element from message body

Eg: Sample SOAP message

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soap:Header/>
    <soap:Body>
        <jsonObject>
            <foo>
                <aaa>Ajith</aaa>
                <bbb>Vitharana</bbb>
            </foo>
        </jsonObject>
    </soap:Body>
</soap:Envelope>

Eg: Sample ESB configuration.

<enrich>
        <source clone="true" xpath="$body/jsonObject/foo"/>
        <target type="body"/>
</enrich>

source : https://docs.wso2.com/display/ESB480/JSON+Support#JSONSupport-XMLrepresentationofJSONpayloads

Friday, January 22, 2016

[WSO2 ESB] Iterate and Aggregate mediators

Lets assume we have two services.

First : This returns list of market details
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <marketDetails xmlns="http://market.test.com">
            <marketDetail>
                <market>
                    <id>100</id>
                    <openTime>10.00AM</openTime>
                    <closeTime>4.00PM</closeTime>
                    <name>New York</name>
                </market>
                <market>
                    <id>200</id>
                    <openTime>9.00AM</openTime>
                    <closeTime>5.PM</closeTime>
                    <name>London</name>
                </market>
            </marketDetail>
        </marketDetails>
    </soapenv:Body>
</soapenv:Envelope>
Second: This returns the symbols of each market.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <symbols xmlns="http://market.test.com">
            <symbol>
                <id>20</id>
                <name>Google</name>
                <qty>2000</qty>
                <unitPrice>6</unitPrice>
            </symbol>
            <symbol>
                <id>30</id>
                <name>IBM</name>
                <qty>1000</qty>
                <unitPrice>5</unitPrice>
            </symbol>
            <symbol>
                <id>30</id>
                <name>WSO2</name>
                <qty>1000</qty>
                <unitPriceice>5.5</unitPriceice>
            </symbol>
        </symbols>
    </soapenv:Body>
</soapenv:Envelope>
So we need to build a new service which returns all the symbols of all markets.

1. We need to iterate through the first response to get the market id and invoke the second service.
<property xmlns:m0="http://market.test.com" name="MARKET_COUNT"
          expression="count(//m0:marketDetails/m0:marketDetail/m0:market)"/>
<iterate xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://org.apache.synapse/xsd"
         preservePayload="true"
         attachPath="//m0:marketDetails/m0:marketDetail/m0:market"
         expression="//m0:marketDetails/m0:marketDetail/m0:market/m0:id"
         id="MARKET_ITERATOR">
<target>
    <sequence>
        <payloadFactory media-type="xml">
            <format>
                <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                    <soap:Body>
                        <getMarketSymbols xmlns="http://market.test.com">
                            <marketId>$1</marketId>
                        </getMarketSymbols>
                    </soap:Body>
                </soap:Envelope>
            </format>
            <args>
                <arg xmlns:m0="http://market.test.com" 
expression="//m0:marketDetails/m0:marketDetail/m0:market/m0:id" evaluator="xml"/>
            </args>
        </payloadFactory>
        <property name="messageType" value="application/soap+xml" scope="axis2"/>
        <call>
            <endpoint xmlns="http://ws.apache.org/ns/synapse" name="SymbolEndpoint">
                <address uri="https://test.com/services/market">
                    <timeout>
                        <duration>30000</duration>
                        <responseAction>fault</responseAction>
                    </timeout>
                    <suspendOnFailure>
                        <errorCodes>-1</errorCodes>
                        <initialDuration>0</initialDuration>
                        <progressionFactor>1.0</progressionFactor>
                        <maximumDuration>0</maximumDuration>
                    </suspendOnFailure>
                    <markForSuspension>
                        <errorCodes>-1</errorCodes>
                    </markForSuspension>
                </address>
            </endpoint>
        </call>
       <loopback/>
    </sequence>
</target>
</iterate>
2. Use the aggregate mediator to collect all the symbols.
<property name="ECNCLOSING_ELEMENT" scope="default">
    <wrapper xmlns=""/>
</property>

<aggregate id="MARKET_ITERATOR">
<completeCondition>
    <messageCount min="{get-property('MARKET_COUNT')}" max="-1"/>
</completeCondition>
<onComplete xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:ns="http://org.apache.synapse/xsd"
            xmlns:m0="http://market.test.com"
            expression="//m0:symbols/m0:symbol"
            enclosingElementProperty="ECNCLOSING_ELEMENT">
</onComplete>
</aggregate>
</iterate>

Monday, January 18, 2016

[WSO2 ESB]Add new element to message body.


Sometime we need to add static content to the message response. Eg: privacy statement. So we can store the note in the registry and include to message body using the enrich mediator.

<property  expression="get-property('registry','gov:/note/PrivacyStatement_v1.0.0.xml')"
name="PrivacyStatement" scope="default" type="OM"/>

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