Friday, May 6, 2011

Executing Groovy scripts using WSO2 ESB

Following post will discuss how to execute a Groovy script using the WSO2 ESB's script mediator [1].

1) Download a distribution of the WSO2 ESB [2].

2) Extract the zip file. The directory created will be referred as ESB_HOME.

3) Go to the ESB_HOME/samples/axis2Server/src/SimpleStockQuoteService directory. Run "ant" to build the service. A service archive will be created at ESB_HOME/samples/axis2Server/repository/services. The generated service archive can be deployed at an Axis2 server.
eg. SimpleStockQuoteService.aar

4) Copy the groovy-all-1.1-rc-1.jar into ESB_HOME/repository/components/lib/.

5) Go to the ESB_HOME/bin and run the script which starts wso2server.
eg. wso2server.bat for windows environments
wso2server.sh for linux environments

6) Once the server stats, log into the Mangement Console using following credentials (following are the default username/password).
username: admin
password: admin

7) Add the following proxy to the Synapse configuration using the Source View tab.
<proxy xmlns="http://ws.apache.org/ns/synapse" name="groovyProxy" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<script language="groovy">println "The current time is: ${new Date()}"</script>
<send>
<endpoint name="endpoint_urn_uuid_4ECE7CA834EC574477533951">
<address uri="http://localhost:9000/services/SimpleStockQuoteService" />
</endpoint>
</send>
</inSequence>
</target>
</proxy>
8) Execute the client using the following command.
heshan@heshan-ThinkPad:~/Dev/wso2esb-4.0.0-SNAPSHOT/samples/axis2Client$ ant stockquote -Daddurl=http://localhost:8280/services/groovyProxy
9) Following message will be printed at ESB console.
The current time is: Fri May 06 14:00:40 IST 2011
References
[1] - http://wso2.org/project/esb/java/3.0.1/docs/mediators/script.html
[2] - http://wso2.org/downloads/esb

Sunday, February 27, 2011

Friendly Basketball Match

We (WSO2) played a friendly Basketball match against some of my friends at Colombo University. We played the match on 24th Thursday at British School's outdoor Basketball court. This was the second time that we met in a friendly match. Last year the Colombo University guys won the match and this time around we won the match.


When comparing our performance against our previous encounter, our team has improved a lot.

Since we had 2 games in 2 consecutive years, we are planning to take this ahead and have this friendly Basketball match as an annual event.

I should like to thank my junior match mates at Colombo University for coming there to play a match during a University vacation and the crowd for coming there to cheer us.

Saturday, February 19, 2011

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

Following post will discuss how to handle a http-get request from WSO2 ESB and call a external web service. Inorder to clarify example clearly I am using a simple usecase described below. The relevant configuration files, steps to run the sample and the messages flowing through the system is shown below. I have labeled the messages in the diagram, inorder to show the contents of the messages.

Usecase
1. Client makes a rest-like http-get: GET /.../company/<id>
eg. curl "http://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 spesific ws-method.
4. ESB service parses the ws-response and returns a plain xml result to the client.

Configuration Files
Following is the Synapse configuration which contains the 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="http://localhost:9000/services/SimpleStockQuoteService" format="soap11"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<property xmlns:ax21="http://services.samples/xsd" xmlns:ns="http://services.samples" name="response_symbol" expression="//ns:return/ax21:symbol/child::text()"/>
<property xmlns:ax21="http://services.samples/xsd" xmlns:ns="http://services.samples" name="response_high" expression="//ns:return/ax21:high/child::text()"/>
<property xmlns:ax21="http://services.samples/xsd" xmlns:ns="http://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="http://localhost:9000.*">
<send/>
</filter>
</in>
<out>
<send/>
</out>
</sequence>
</definitions>

Following is the xslt transformation (request_transform.xslt) which transforms the request at the ESB.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="symbol"/>
<xsl:template match="/">
<m0:getQuote xmlns:m0="http://services.samples">
<m0:request>
<m0:symbol><xsl:value-of select="$symbol"/></m0:symbol>
</m0:request>
</m0:getQuote>
</xsl:template>
</xsl:stylesheet>

Following is the xslt transformation (response_transform.xslt) which transforms the response at the ESB.
<xsl:stylesheet xmlns:xsl="http://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="http://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>

The 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="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:body>
<m0:getquote m0="http://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="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:body>
<ns:getquoteresponse ns="http://services.samples">
<ns:return ax21="http://services.samples/xsd" xsi="http://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="http://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 (ie. 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 to 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 "http://localhost:8280/services/ProxyA/company/IBM" -v

Then you will be getting 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="http://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] - http://wso2.org/downloads/esb
[2] - http://wso2.org/project/esb/java/3.0.1/docs/

Tuesday, January 11, 2011

Apache Synapse Enterprise Service Bus (ESB) - 2.0.0 Released

Overview
The Apache Synapse ESB is a robust, lightweight and highly scalable and distributed open source Enterprise Service Bus (ESB). It supports SOAP Web services as well as Legacy services over transports such as JMS, Apache VFS File systems, Mail etc, and SOAP, REST/POX, plain text and binary message payloads. (Please see http://synapse.apache.org for more details)

Installation Prerequisites
Apache Synapse requires a J2SE runtime of version 1.5.x or later. Running the samples also requires Apache Ant 1.7.x or later. Although Synapse would run with a JDK > 1.5.x, the Script mediator may not properly function on these JDKs. Building Synapse from source requires JDK 1.5.x or later, and Apache Maven 2.1.0 or later

Quick start
Please see the http://synapse.apache.org/Synapse_Quickstart.html guide

Building the Samples
Please see the documents http://synapse.apache.org/Synapse_Samples.html and http://synapse.apache.org/Synapse_Samples_Setup.html

Synapse configuration language
Please see the document http://synapse.apache.org/Synapse_Configuration_Language.html

Extending Synapse
Please see the document http://synapse.apache.orgs/Synapse_Extending.html

Known Issues and limitations
  • SYNAPSE-180 Does not support throttling by concurrency within a cluster
  • SYNAPSE-186 Does not support HTTP some of the REST operations (such as put/delete etc)
  • SYNAPSE-181 Does not yet support JTA transactions
  • SYNAPSE-330 Does not yet support load balancing with session affinity using SOAP sessions
  • SYNAPSE-280 Does not preserve CDATA sections within payloads
  • SYNAPSE-307 The XSLT mediator will not report errors encountered in a provided stylesheet
  • The Synapse JMS implementation supports JMS 1.0.2b, however due to licensing issues we includethe JMS 1.1 spec JAR from Apache Geronimo (geronimo-jms_1.1_spec-1.1.jar) instead. If you have any issues with JMS 1.0.x, please download the Sun JMS 1.0.2b JAR and replace supplied JAR from Geronimo.
Frequently asked questions
  • How can I change the default logging level of Synapse? Edit the lib/log4j.properties and set the line "log4j.category.org.apache.synapse=INFO" to "log4j.category.org.apache.synapse=DEBUG" and restart Synapse.
  • If you get an error related to WS-Security or when using it, check to ensure that your JDK uses the "Unlimited Strength Jurisdiction Policy Files". These could be downloaded from http://java.sun.com/javase/downloads/index_jdk5.jsp Refer to the associated documentation for instructions on how to install it to your JDK.
  • If you encounter issues with your JDK related to XML processing, try placing the Xerces jar files xercesImpl-2.8.0.jar and xml-apis-1.3.03.jar in your /jre/lib/endorsed/ directory.
Reporting Problems

New features in the Synapse 2.0.0 release
  • New, fine-grained configuration model
  • Hot deployment and hot update support for configuration artifacts
  • Priority based mediation support
  • Comprehensive eventing capabilities with WS-Eventing support
  • Secure vault for encrypting passwords in configuration files
  • File locking support in the VFS transport for concurrent polling
  • URLRewrite medaitor for fast and simple URL rewriting
  • Synapse configuration observer API
  • Multiple identity support in the HTTPS transport
  • Enhanced JMX monitoring support for the NHTTP transport
  • Dead letter channel implementation (experimental)
  • Synapse XAR Maven plugin for generating configuration artifacts

Wednesday, January 5, 2011

SFTP file transer with WSO2 ESB.

The VFS transport implementation is based on Apache Commons VFS implementation. VFS (Virtual File System) transport implementation is a module which belongs to the Apache Synapse project. It has a set of service level parameters that needs to be specified for each service.

VFS service level parameters and their descriptions can be found in [1] and the endpoint formats can be found in [2].

Following is a sftp sample for ESB 3.0.1. It copies a file from one sftp location to another sftp folder. SFTPVFSProxy is the proxy service which copies file from one sftp location to another.

If you need further information or need help troubleshooting this sample refer [5].

<proxy name="SFTPVFSProxy" transports="vfs" startOnLoad="true" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<log level="full"/>
<property name="File" expression="fn:concat('test-', get-property('transport', 'FILE_PATH'))" scope="default"/>
<property name="transport.vfs.ReplyFileName" expression="fn:concat(fn:substring-after(get-property('MessageID'), 'urn:uuid:'), '.xml')" scope="transport"/>
<property name="OUT_ONLY" value="true"/>
<send>
<endpoint name="endpoint_urn_uuid_A1546EFFD75FC9CCED785986339425964585275">
<address uri="vfs:sftp://heshan:password@10.101.1.112/home/heshan/out"/>
</endpoint>
</send>
</inSequence>
</target>
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.PollInterval">15</parameter>
<parameter name="transport.vfs.MoveAfterProcess">vfs:sftp://heshan:password@10.101.1.112/home/heshan/original</parameter>
<parameter name="transport.vfs.FileURI">vfs:sftp://heshan:password@10.101.1.112/home/heshan/in/test.xml</parameter>
<parameter name="transport.vfs.MoveAfterFailure">vfs:sftp://heshan:password@10.101.1.112/home/heshan/original</parameter>
<parameter name="transport.vfs.FileNamePattern">.*.xml</parameter>
<parameter name="transport.vfs.ContentType">application/xml</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
</proxy>
Following is the XML file (test.xml) that is being moved.

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Body>
<getQuote xmlns="http://services.samples">
<request>
<symbol>IBM</symbol>
</request>
</getQuote>
</soapenv:Body>
</soapenv:Envelope>

If you are interested in trying out more VFS samples, refer [3] and [4].

Tuesday, November 23, 2010

Debug Carbon server when it is started as a daemon

WSO2 Carbon Server can be run as a daemon on Unix/Linux systems. Say for instance that you need to remote debug the server when it is started as a daemon. This blogpost will be discussing $subject.

1) Open up the wrapper.conf file.

heshan@heshan-ThinkPad:~/Dev/customer/wso2esb-3.0.1/bin$ vim ../repository/conf/wrapper.conf

2) Add following entries to the wrapper.conf.

wrapper.java.additional.20=-Xdebug
wrapper.java.additional.21=-Xnoagent
wrapper.java.additional.22=-Djava.compiler=NONE
wrapper.java.additional.23=-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005

3) Start the ESB as a daemon.

heshan@heshan-ThinkPad:~/Dev/customer/wso2esb-3.0.1/bin$ ./wso2server.sh start
Starting WSO2 ESB v3.0.1...

4) Start the debugger.

5) Monitor the log.

heshan@heshan-ThinkPad:~/Dev/customer/wso2esb-3.0.1/bin$ tail -f ../repository/logs/wrapper.log
INFO | jvm 1 | 2010/11/24 11:35:09 | object space 84224K, 76% used [0x00007fbfcff20000,0x00007fbfd3e0dff0,0x00007fbfd5160000)
STATUS | wrapper | 2010/11/24 11:35:09 | <-- Wrapper Stopped STATUS | wrapper | 2010/11/24 11:45:46 | --> Wrapper Started as Daemon
WARN | wrapper | 2010/11/24 11:45:46 | ------------------------------------------------------------------------
WARN | wrapper | 2010/11/24 11:45:46 | The JVM is being launched with a debugger enabled and could possibly be
WARN | wrapper | 2010/11/24 11:45:46 | suspended. To avoid unwanted shutdowns, timeouts will be disabled,
WARN | wrapper | 2010/11/24 11:45:46 | removing the ability to detect and restart frozen JVMs.
WARN | wrapper | 2010/11/24 11:45:46 | ------------------------------------------------------------------------
STATUS | wrapper | 2010/11/24 11:45:46 | Launching a JVM...
INFO | jvm 1 | 2010/11/24 11:45:46 | Listening for transport dt_socket at address: 5005
INFO | jvm 1 | 2010/11/24 11:45:56 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
INFO | jvm 1 | 2010/11/24 11:45:56 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
INFO | jvm 1 | 2010/11/24 11:45:56 |
INFO | jvm 1 | 2010/11/24 11:45:56 | [2010-11-24 11:45:56,845] INFO - Main Initializing system...

Now you have successfully debugged the Carbon Server, when it is started as a daemon.