Tuesday, December 17, 2013

WSO2 ESB - sample REST to REST API configuration

<api xmlns=”http://ws.apache.org/ns/synapse” name=”TestApi” context=”/helloWorld”>
   <resource methods=”GET” url-mapping=”/hello”>
      <inSequence>
         <property name=”ContentType” value=”text/xml” scope=”axis2” type=”STRING”/>
         <switch source=”$axis2:HTTP_METHOD”>
            <case regex=”GET”>
               <property name=”HTTP_METHOD” value=”GET” scope=”axis2” type=”STRING”/>
            </case>
            <case regex=”POST”>
               <property name=”HTTP_METHOD” value=”POST” scope=”axis2” type=”STRING”/>
            </case>
            <default/>
         </switch>
         <log/>
         <send>
            <endpoint>
               <address uri=”http://localhost:8080/HelloRestFul” format=”pox”/>
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <log/>
         <send/>
      </outSequence>
   </resource>
</api>
                       

Thursday, December 5, 2013

WSO2 ESB exposing Web Service Proxy to a TCP client PART 2 : Sending batch responses from ESB to TCP server

In my last post regarding how to expose a web service for a TCP client we have discussed about retrieving a request in plain text format from a TCP client, convert it to SOAP message and send to the back end webservice.


In that post I have mentioned that according to our implementation we did not need to send the response back to the TCP client immediately due to that our responses are not synchronous.


So what we did to achieve this asynchronous status is converting the ESB it self to a TCP client and send the responses as batches to a TCP server.


So in this article I am going to explain how to use the WSO2 ESB as a TCP client where we needed to convert the XML responses to delimited string sequences before sending to TCP server.



To convert the XML file to delimited string sequence we have used the smooks mediator. (Refer the smooks configuration below)


In above example we are converting a xml file that has an entity called “Login”. Each login element has three child elements.


Freemarker tool has been used to convert the XML elements to text fields and delimit two values.


<smooks-resource-list xmlns=”http://www.milyn.org/xsd/smooks-1.1.xsd” xmlns:ftl=”http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd” xmlns:core=”http://www.milyn.org/xsd/smooks/smooks-core-1.3.xsd” xmlns:file=”http://www.milyn.org/xsd/smooks/file-routing-1.1.xsd”>
      <core:filterSettings type=”SAX” defaultSerialization=”false”/>
      <resource-config selector=”//batchTransfer/returnVal/login”>
         <resource>org.milyn.delivery.DomModelCreator</resource>
      </resource-config>
      <ftl:freemarker applyOnElement=”login”>
         <ftl:template>${.vars[“login”].id},${.vars[“login”].password},${.vars[“login”].userName}
           </ftl:template>
      </ftl:freemarker>
   </smooks-resource-list>


Save above smooks configuration as a Local XML entry.


Then to send a batch of responses to ESB from our back end, we have created a dummy web service proxy inside ESB. This dummy web service connect to the TCP server, thus the TCP server now acts as the back end. Also we have hand written a WSDL and expose that hand written WSDL through the ESB. This way we can configure what kind or SOAP structure accept by this dummy proxy web service and then convert the XML resides within that proxy and then send those converted text to the back end TCP server.


Below is the WSDL which we hand written for the above “Login batch response” example.


<wsdl:definitions xmlns:wsdl=”http://schemas.xmlsoap.org/wsdl/” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:soap=”http://schemas.xmlsoap.org/wsdl/soap/” xmlns:tns=”com.mobitel.test” name=”test” targetNamespace=”com.mobitel.test”>
      <wsdl:types>
         <xsd:schema targetNamespace=”com.mobitel.test”>
            <xsd:element name=”batchTransfer” type=”tns:batchTransfer”/>
            <xsd:element name=”batchTransferResponse” type=”tns:batchTransferResponse”/>
            <xsd:complexType name=”batchTransfer”>
               <xsd:sequence>
                  <xsd:element name=”returnVal” type=”tns:logins”/>
               </xsd:sequence>
            </xsd:complexType>
            <xsd:complexType name=”logins”>
               <xsd:sequence>
                  <xsd:element name=”login” type=”tns:login” nillable=”true” minOccurs=”0” maxOccurs=”unbounded”/>
               </xsd:sequence>
            </xsd:complexType>
            <xsd:complexType name=”login”>
               <xsd:sequence>
                  <xsd:element name=”id” type=”xsd:int”/>
                  <xsd:element name=”password” type=”xsd:string”/>
                  <xsd:element name=”userName” type=”xsd:string”/>
               </xsd:sequence>
            </xsd:complexType>
            <xsd:complexType name=”batchTransferResponse”/>
         </xsd:schema>
      </wsdl:types>
      <wsdl:message name=”batchTransferRequest”>
         <wsdl:part element=”tns:batchTransfer” name=”parameters”/>
      </wsdl:message>
      <wsdl:message name=”batchTransferResponse”>
         <wsdl:part element=”tns:batchTransferResponse” name=”parameters”/>
      </wsdl:message>
      <wsdl:portType name=”test”>
         <wsdl:operation name=”batchTransfer”>
            <wsdl:input message=”tns:batchTransferRequest”/>
            <wsdl:output message=”tns:batchTransferResponse”/>
         </wsdl:operation>
      </wsdl:portType>
      <wsdl:binding name=”testSOAP” type=”tns:test”>
         <soap:binding style=”document” transport=”http://schemas.xmlsoap.org/soap/http”/>
         <wsdl:operation name=”batchTransfer”>
            <soap:operation soapAction=”com.mobitel.test/NewOperation”/>
            <wsdl:input>
               <soap:body use=”literal”/>
            </wsdl:input>
            <wsdl:output>
               <soap:body use=”literal”/>
            </wsdl:output>
         </wsdl:operation>
      </wsdl:binding>
      <wsdl:service name=”test”>
         <wsdl:port binding=”tns:testSOAP” name=”testSOAP”>
            <soap:address location=”http://localhost:8282/services/TcpOutput”/>
         </wsdl:port>
      </wsdl:service>
   </wsdl:definitions>


This way the user of this dummy web service can create a web service client by using the above WSDl expose from WSO2 ESB’s dummy proxy service. Also the details such as back end is TCP can be hidden from the user.


Below is the dummy proxy for the “Login batch response” example.


<?xml version=”1.0” encoding=”UTF-8”?>
<proxy xmlns=”http://ws.apache.org/ns/synapse”
       name=”TcpOutput”
       transports=”https,http,tcp”
       statistics=”disable”
       trace=”disable”
       startOnLoad=”true”>
   <target>
      <inSequence>
         <log level=”full”/>
         <smooks config-key=”smooksXMLToText”>
            <input type=”xml”/>
            <output type=”text”/>
         </smooks>
         <log level=”full”/>
         <property name=”CONTENT_TYPE”
                   value=”text/plain”
                   scope=”axis2”
                   type=”STRING”/>
         <property name=”OUT_ONLY” value=”true” scope=”default” type=”STRING”/>
         <send>
            <endpoint>
               <address uri=”tcp://localhost:9448”/>
            </endpoint>
         </send>
         <property name=”FORCE_SC_ACCEPTED”
                   value=”true”
                   scope=”axis2”
                   type=”STRING”/>
      </inSequence>
      <outSequence>
         <send>
            <endpoint>
               <default/>
            </endpoint>
         </send>
      </outSequence>
   </target>
   <publishWSDL key=”testOutPutWsdl”/>
   <description/>
</proxy>
                               


Here we have used 3 properties ( please refer the proxy xml above)


1. <property name=”CONTENT_TYPE” value=”text/plain”               scope=”axis2” type=”STRING”/>   


This will tell ESB that the output to back end will be “text/plain”. We needed this because our TCP server accept only text formate.


2. <property name=”OUT_ONLY” value=”true” scope=”default” type=”STRING”/>


This will tell ESB that this proxy does not send a response or simply do not need a out sequence. Though we defined empty outsequance tag we does not expect web service client to wait for a response from back end TCP server.


3. <property name=”FORCE_SC_ACCEPTED” value=”true”                 scope=”axis2” type=”STRING”/>


Add this property just after the SEND mediator. We use this property to send a HTTP 202 ( no content ) response to the web service client to avoid it wait for response.


Also please note that in our dummy proxy web service we have enabled all the http,https,tcp transport types because in our proxy we retrieve the “batch response” request via HTTP or HTTPS and we use TCP to transport that “batch response” request to TCP server.



(Special thanks goes to Lalaji Sureshika from WSO2)



Tuesday, December 3, 2013

WSO2 ESB exposing Web Service Proxy to a TCP client. ( A.K.A TCP proxy)

In this article I am going to explain how to create a proxy to a back end web service which accept TCP messages.


In our case our TCP client was sending a delimited string to the ESB and we need ESB to convert the delimited string into a SOAP/XML file and call the web service.


In our case we does not intend to send the response immediately back to the client rather than sending response as batches of several requests. Since I will explain how the batch response in another article.


To accept the TCP requests you need to change your axis2.xml file inside <ESB_LOCATION>/repository/conf/axis2.xml file and add below two transport handler.


1. Configure TCPTransportListener to listen to in coming TCP requests.


<transportReceiver name=”tcp” class=”org.apache.axis2.transport.tcp.TCPTransportListener”>
      <parameter name=”transport.tcp.port”>6060</parameter>
    </transportReceiver>


2. Configure TCPTransportSender to send responses over TCP (this handler will not want for this article but this will be used in next article for batch response sending )


<transportSender name=”tcp” class=”org.apache.axis2.transport.tcp.TCPTransportSender”/>


Then we use inbuilt smooks handler to transform the delimited values into a XML entries.


To do this we first need to add smooks configuration which act as a template to smooks handler. We need to add the smooks configuration as a local XML entry to ESB. To do this go to Main - > Service Bus -> Local Entries. And add a in-lined XML entry.


(This is an example of smooks configuration which use to trans form delimited text to XML)


<smooks-resource-list xmlns=”http://www.milyn.org/xsd/smooks-1.1.xsd” xmlns:csv=”http://www.milyn.org/xsd/smooks/csv-1.2.xsd”>
      <resource-config selector=”org.xml.sax.driver”>
         <resource>org.milyn.csv.CSVReader</resource>
         <param name=”fields”>id,password,userName</param>
         <param name=”rootElementName”>addLogin</param>
         <param name=”recordElementName”>login</param>
      </resource-config>
   </smooks-resource-list>
                                   


Then add a new proxy which use the smooks mediator in “Advance -> smooks”, with TCP transport type allowed, and finally with port and content type properties as below.


Below is a sample


<?xml version=”1.0” encoding=”UTF-8”?>
<proxy xmlns=”http://ws.apache.org/ns/synapse”
       name=”LoginProxy”
       transports=”tcp”
       statistics=”disable”
       trace=”disable”
       startOnLoad=”true”>
   <target>
      <inSequence>
         <smooks config-key=”LoginDetails”>
            <input type=”text”/>
            <output type=”xml”/>
         </smooks>
         <send>
            <endpoint>
               <wsdl service=”HelloServiceImplService”
                     port=”HelloServiceImpl”
                     uri=”http://localhost:8080//HelloWebService/services/HelloServiceImpl?wsdl”/>
            </endpoint>
         </send>
         <log level=”full”/>
      </inSequence>
      <outSequence>
         <log/>
      </outSequence>
   </target>
   <parameter name=”transport.tcp.port”>9446</parameter>
   <parameter name=”transport.tcp.contentType”>text/plain</parameter>
   <description/>
</proxy>