2011/03/16
16 Mar, 2011

Handling a http-get request and invoking an external Web service with WSO2 ESB

  • Heshan Suriyaarachchi
  • Software Engineer - WSO2

The following KB discusses how to handle a http-get request from WSO2 ESB and call an external web service. In order to clarify this subject, we use the simple usecase described below. The relevant configuration files, steps to run the sample and the messages flowing through the system is also shown below. The messages in the diagram are labeled in order to show the contents of the messages.

 

Usecase

1. Client makes a rest-like http-get: GET /.../company/<id>
eg. curl "https://localhost:8280/services/ProxyA/company/IBM" -v
2. ESB service proxy picks the company ID from the URL
eg. IBM
3. ESB service makes a web service call to a external WS-service (SimpleStockQuoteService) and a specific WS-method.
4. ESB service parses the WS-response and returns a plain XML result to the client.

Configuration Files

The following is the Synapse configuration which contains a sample proxy which handles the request:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
<registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">
    <parameter name="cachableDuration">15000</parameter>
</registry>
<proxy name="ProxyA" transports="https http" startOnLoad="true" trace="disable">
    <target>
        <inSequence>
            <enrich>
                <source type="inline">
                    <a xmlns=""/>
                </source>
                <target type="body" action="child"/>
            </enrich>
            <log level="full"/>
            <property name="company" expression="substring-after(get-property('To'),'company/')"/>
            <xslt key="xslt-transform-request">
                <property name="symbol" expression="get-property('company')"/>
            </xslt>
            <header name="Action" value="urn:getQuote"/>
            <log level="full"/>
            <send>
                <endpoint name="ep1">
                    <address uri="https://localhost:9000/services/SimpleStockQuoteService" format="soap11"/>
                </endpoint>
            </send>
        </inSequence>
        <outSequence>
            <property xmlns:ax21="https://services.samples/xsd" xmlns:ns="https://services.samples" name="response_symbol" expression="//ns:return/ax21:symbol/child::text()"/>
            <property xmlns:ax21="https://services.samples/xsd" xmlns:ns="https://services.samples" name="response_high" expression="//ns:return/ax21:high/child::text()"/>
            <property xmlns:ax21="https://services.samples/xsd" xmlns:ns="https://services.samples" name="response_low" expression="//ns:return/ax21:low/child::text()"/>
            <log level="custom">
                <property name="response symbol:" expression="get-property('response_symbol')"/>
                <property name="response high  :" expression="get-property('response_high')"/>
                <property name="response low   :" expression="get-property('response_low')"/>
            </log>
            <xslt key="xslt-transform-response">
                <property name="symbol" expression="get-property('response_symbol')"/>
                <property name="high" expression="get-property('response_high')"/>
                <property name="low" expression="get-property('response_low')"/>
            </xslt>
            <send/>
        </outSequence>
    </target>
</proxy>
<localEntry key="xslt-transform-request" src="file:repository/samples/resources/transform/request_transform.xslt"/>
<localEntry key="xslt-transform-response" src="file:repository/samples/resources/transform/response_transform.xslt"/>
<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">
    <in>
        <log level="full"/>
        <filter source="get-property('To')" regex="https://localhost:9000.*">
            <send/>
        </filter>
    </in>
    <out>
        <send/>
    </out>
</sequence>
</definitions>

The following is the XSLT transformation (request_transform.xslt) which transforms the request in the ESB:

<xsl:stylesheet xmlns:xsl="https://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="symbol"/>
<xsl:template match="/">
    <m0:getQuote xmlns:m0="https://services.samples">
        <m0:request>
            <m0:symbol><xsl:value-of select="$symbol"/></m0:symbol>
        </m0:request>
    </m0:getQuote>
</xsl:template>
</xsl:stylesheet>

The following is the XSLT transformation (response_transform.xslt) which transforms the response in the ESB:

<xsl:stylesheet xmlns:xsl="https://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="symbol"/>
<xsl:param name="high"/>
<xsl:param name="low"/>
<xsl:template match="/">
    <m0:getQuote xmlns:m0="https://services.samples">
        <m0:response>
            <m0:company><xsl:value-of select="$symbol"/></m0:company>
    <m0:high><xsl:value-of select="$high"/></m0:high>
    <m0:low><xsl:value-of select="$low"/></m0:low>
        </m0:response>
    </m0:getQuote>
</xsl:template>
</xsl:stylesheet>

Contents of the messages flowing through the ESB

Request-A

GET /services/ProxyA/company/IBM HTTP/1.1
User-Agent: curl/7.21.0 (x86_64-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.18
Host: 127.0.0.1:8281
Accept: */*

Request-B

POST /services/SimpleStockQuoteService HTTP/1.1
Content-Type: text/xml; charset=UTF-8
Accept: */*
SOAPAction: "urn:getQuote"
Transfer-Encoding: chunked
Host: 127.0.0.1:9001
Connection: Keep-Alive
User-Agent: Synapse-HttpComponents-NIO

113
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:envelope soapenv="https://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:body>
     <m0:getquote m0="https://services.samples">
        <m0:request>
           <m0:symbol>IBM</m0:symbol>
        </m0:request>
     </m0:getQuote>
  </soapenv:Body>
</soapenv:Envelope>0

Response-C

HTTP/1.1 200 OK
Content-Type: text/xml; charset=UTF-8
Date: Sat, 19 Feb 2011 08:50:01 GMT
Transfer-Encoding: chunked
Connection: Keep-Alive

40a
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:envelope soapenv="https://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:body>
     <ns:getquoteresponse ns="https://services.samples">
        <ns:return ax21="https://services.samples/xsd" xsi="https://www.w3.org/2001/XMLSchema-instance" type="ax21:GetQuoteResponse">
           <ax21:change>-2.7502820955517455</ax21:change>
           <ax21:earnings>13.682776182003703</ax21:earnings>
           <ax21:high>159.3075652956029</ax21:high>
           <ax21:last>154.1201005301602</ax21:last>
           <ax21:lasttradetimestamp>Sat Feb 19 14:20:01 IST 2011</ax21:lastTradeTimestamp>
           <ax21:low>158.77156450332262</ax21:low>
           <ax21:marketcap>-4211789.232304155</ax21:marketCap>
           <ax21:name>IBM Company</ax21:name>
           <ax21:open>161.05685744490376</ax21:open>
           <ax21:peratio>24.219012038564948</ax21:peRatio>
           <ax21:percentagechange>1.913224112346585</ax21:percentageChange>
           <ax21:prevclose>-143.75117257844414</ax21:prevClose>
           <ax21:symbol>IBM</ax21:symbol>
           <ax21:volume>6450</ax21:volume>
        </ns:return>
     </ns:getQuoteResponse>
  </soapenv:Body>
</soapenv:Envelope>0

Response-D

HTTP/1.1 200 OK
Content-Type: application/xml; charset=UTF-8
Date: Sat, 19 Feb 2011 08:50:01 GMT
Transfer-Encoding: chunked

bc
<m0:getquote m0="https://services.samples">
<m0:response>
  <m0:company>IBM</m0:company>
  <m0:high>159.3075652956029</m0:high>
  <m0:low>158.77156450332262</m0:low>
</m0:response></m0:getQuote>0

Steps to run the sample

1) Download WSO2 ESB [1].

2) Start wso2esb using the startup scripts.
eg: ./wso2server.sh

3) Login to the WSO2 Management Console.

4) Copy the attached XSLT files (i.e. request_transform.xslt, response_transform.xslt) to wso2esb-3.0.1/repository/samples/resources/transform directory.

5) Go to Source View and paste the Synapse configuration into it and hit update.

6) Start the Axis2 server and deploy the SimpleStockQuoteService if not already done.
i) Run the ant script to build the SimpleStockQuoteService. It is residing in wso2esb-3.0.1/samples/axis2Server/src/SimpleStockQuoteService directory.
ii) Then run the simple axis2Server shipped in with the wso2esb. This can be done by the running the axis2Server startup script inside wso2esb-3.0.1/samples/axis2Server/ directory.
eg: ./axis2server.sh

7) Execute the following curl command.
eg: curl "https://localhost:8280/services/ProxyA/company/IBM" -v

Then you will gett the following response:
eg:

* About to connect() to localhost port 8280 (#0)
*   Trying ::1... connected
* Connected to localhost (::1) port 8280 (#0)
> GET /services/ProxyA/company/IBM HTTP/1.1
> User-Agent: curl/7.21.0 (x86_64-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.18
> Host: localhost:8280
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/xml; charset=UTF-8
< Date: Thu, 10 Feb 2011 07:54:46 GMT
< Transfer-Encoding: chunked
<
* Connection #0 to host localhost left intact
* Closing connection #0
<m0:getQuote xmlns:m0="https://services.samples"><m0:response><m0:company>IBM</m0:company><m0:high>-81.16785748190335</m0:high><m0:low>85.09674577550493</m0:low></m0:response></m0:getQuote>

References

[1] - https://wso2.org/downloads/esb
[2] - https://wso2.org/project/esb/java/3.0.1/docs/

Author:
Heshan Suriyaarachchi
Software Engineer; WSO2, Inc.
[email protected]

 

About Author

  • Heshan Suriyaarachchi
  • Software Engineer
  • WSO2 Inc.