Wednesday, December 19, 2012

How to use WSO2 ESB VFS transport to transfer large files..


We can use VFS transport in WSO2 ESB as described in the sample [1]. Apart from that Supun which was a project manger of WSO2 ESB has written and article[2] on that. These articles and samples provides a great help on using VFS transport to transfer files.

But when using that configurations for transferring large files (Greater that 500 MB), i got an Out Of Memory exceptions[3] and some other errors[4].

When looking in to the problem more deeply, i could found the solution for the problem. The issue was with the message builder class that i have used and missing a property. We need to use the message builder "org.apache.axis2.format.BinaryBuilder" for this. Apart from that  we need to include the property "ClientApiNonBlocking" in the proxy configuration.

As a sample i have defined a custom content type "chs/binary".

Entries in axis2.xml


<messageFormatters>
        ...    
        <messageFormatter contentType="chs/binary"
        class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
        ...
</messageFormatters>
    <messageBuilders>
        ...
        <messageBuilder contentType="chs/binary"
        class="org.apache.axis2.format.BinaryBuilder"/>
        ...
   </messageBuilders>

Then we need to have a sample VFS proxy as :

 <proxy xmlns="http://ws.apache.org/ns/synapse"
       name="FileProxy"
       transports="vfs"
       startOnLoad="true"
       trace="disable">
    <description/>
    <target>
       <inSequence>
          <log level="custom">
             <property name="FileProxy" value="Processing file"/>
          </log>
          <property name="OUT_ONLY" value="true"/>
          <property name="ClientApiNonBlocking"
                   value="true"
                  scope="axis2"
                  action="remove"/>
          <send>
             <endpoint name="FileEpr">
                <address uri="vfs:file:////home/shammi/file-out"/>
             </endpoint>
          </send>
       </inSequence>
    </target>
    <parameter name="transport.vfs.Streaming">true </parameter>
    <parameter name="transport.PollInterval">15 </parameter>
    <parameter name="transport.vfs.ActionAfterProcess">MOVE </parameter>
    <parameter name="transport.vfs.FileURI">file:///home/shammi/file-in </parameter>
    <parameter name="transport.vfs.MoveAfterProcess">file:///home/shammi/file-original </parameter>
    <parameter name="transport.vfs.MoveAfterFailure">file:////home/shammi/file-failure </parameter>
    <parameter name="transport.vfs.Locking">enable </parameter>
    <parameter name="transport.vfs.FileNamePattern">.*.zip|.*.test </parameter>
    <parameter name="transport.vfs.ContentType">chs/binary </parameter>
    <parameter name="transport.vfs.ActionAfterFailure">MOVE </parameter>
 </proxy>

    

With this proxy , i could use VFS transport to transfer a file with the size 1 GB with out any issue. I have made the points bold which needs to pay more attention..

Cheers.. Thats it......





[1]http://docs.wso2.org/wiki/pages/viewpage.action?pageId=15471427
[2]http://wso2.org/library/articles/2011/01/wso2-esb-example-file-processing
[3]2012-12-19 11:49:04,797 [-] [Framework Event Dispatcher]  WARN PollTableEntry transport.vfs.FileURI parameter is missing in the proxy service configuration
2012-12-19 11:50:08,896 [-] [vfs-Worker-3] ERROR NativeWorkerPool Uncaught exception
java.lang.OutOfMemoryError: Java heap space
at org.apache.commons.io.output.ByteArrayOutputStream.needNewBuffer(ByteArrayOutputStream.java:124)
at org.apache.commons.io.output.ByteArrayOutputStream.write(ByteArrayOutputStream.java:155)
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1263)
at org.apache.commons.io.IOUtils.copy(IOUtils.java:1236)
at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:360)
at org.apache.axis2.format.BinaryBuilder.processDocument(BinaryBuilder.java:72)
at org.apache.synapse.transport.vfs.VFSTransportListener.processFile(VFSTransportListener.java:558)
at org.apache.synapse.transport.vfs.VFSTransportListener.scanFileOrDirectory(VFSTransportListener.java:312)
at org.apache.synapse.transport.vfs.VFSTransportListener.poll(VFSTransportListener.java:158)
at org.apache.synapse.transport.vfs.VFSTransportListener.poll(VFSTransportListener.java:107)
at org.apache.axis2.transport.base.AbstractPollingTransportListener$1$1.run(AbstractPollingTransportListener.java:67)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)


[4]

2012-12-19 13:59:58,033 [-] [Axis2 Task] ERROR VFSTransportSender IO Error while creating response file : file:///home/shammi/wso2/foo/file-out/response.xml
org.apache.axis2.AxisFault: Error serializing binary content of element : {http://ws.apache.org/commons/ns/payload}binary
at org.apache.axis2.format.BinaryFormatter.writeTo(BinaryFormatter.java:66)
at org.apache.synapse.transport.vfs.VFSTransportSender.populateResponseFile(VFSTransportSender.java:235)
at org.apache.synapse.transport.vfs.VFSTransportSender.sendMessage(VFSTransportSender.java:173)
at org.apache.axis2.transport.base.AbstractTransportSender.invoke(AbstractTransportSender.java:112)
at org.apache.axis2.engine.AxisEngine$TransportNonBlockingInvocationWorker.run(AxisEngine.java:627)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.apache.commons.vfs2.FileNotFoundException: Could not read from "file:///home/shammi/wso2/foo/file-in/a.zip" because it is a not a file.
at org.apache.commons.vfs2.provider.AbstractFileObject.getInputStream(AbstractFileObject.java:1316)
at org.apache.commons.vfs2.provider.DefaultFileContent.getInputStream(DefaultFileContent.java:397)
at org.apache.synapse.transport.vfs.FileObjectDataSource.getInputStream(FileObjectDataSource.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.axis2.format.ManagedDataSourceFactory$DataSourceManager.invoke(ManagedDataSourceFactory.java:91)
at $Proxy15.getInputStream(Unknown Source)
at javax.activation.DataHandler.writeTo(DataHandler.java:290)
at org.apache.axis2.format.BinaryFormatter.writeTo(BinaryFormatter.java:64)
... 7 more
Caused by: java.io.FileNotFoundException: /home/shammi/wso2/foo/file-in/a.zip (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:120)
at org.apache.commons.vfs2.provider.local.LocalFile.doGetInputStream(LocalFile.java:210)
at org.apache.commons.vfs2.provider.AbstractFileObject.getInputStream(AbstractFileObject.java:1308)
... 17 more
2012-12-19 14:00:26,458 [-] [Timer-7]  WARN TimeoutHa

Friday, November 9, 2012

Exception during startup: org.wso2.andes.server.Broker$InitException: File null could not be found. Check the file exists and is readable.







Exception during startup: org.wso2.andes.server.Broker$InitException: File null could not be found. Check the file exists and is readable.
org.wso2.andes.server.Broker$InitException: File null could not be found. Check the file exists and is readable.
at org.wso2.andes.server.Broker.getConfigFile(Broker.java:323)
at org.wso2.andes.server.Broker.startupImpl(Broker.java:120)
at org.wso2.andes.server.Broker.startup(Broker.java:102)
at org.wso2.andes.server.Main.startBroker(Main.java:227)
at org.wso2.andes.server.Main.execute(Main.java:220)
at org.wso2.andes.server.Main.(Main.java:63)
at org.wso2.andes.server.Main.main(Main.java:53)
.....





You may get the pointed out exception when installed Message Broker features in WSO2 carbon or in any other wso2 products. The root cause for this problem is missing a system property in the start up
script. 

You can solve this by adding the system property to the wso2server.sh file or the wso2server.bat file of your server. The property is :

-DandesConfig=qpid-config.xml \

When you added this property to the wso2server.sh file , it should look like;

 $JAVACMD \
    -Xbootclasspath/a:"$CARBON_XBOOTCLASSPATH" \
    -Xms256m -Xmx1024m -XX:MaxPermSize=256m \
    -XX:+HeapDumpOnOutOfMemoryError \
    -XX:HeapDumpPath="$CARBON_HOME/repository/logs/heap-dump.hprof" \
    $JAVA_OPTS \
     -DandesConfig=qpid-config.xml \
    -Dcom.sun.management.jmxremote \
    -classpath "$CARBON_CLASSPATH" \
    -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" \
    -Djava.io.tmpdir="$CARBON_HOME/tmp" \




This issue will be fixed with the 2.0.2 release of the wso2 message broker.



Monday, July 9, 2012

Find and Replace Strings in Linux with Grep and Sed

It would be very useful if we can find a string in multiple files and replace it with a new string. It takes a single line of code to do that :

grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g'

matchString - the string you want to find
string1 - same string you want to find
string2 - new string that you want to replace with


eg :
I need to find the string "foo" and replace it with "bar"

grep -rl 'foo' ./ | xargs sed -i 's/foo/bar/g'  

 There is a nice post on describing more on this:
http://vasir.net/blog/ubuntu/replace_string_in_multiple_files/

Friday, June 1, 2012

WSO2 ESB Message Stores with WSO2 MB 2.0 -M2

When using JMS Message stores in WSO2 ESB, there is a small difference scenario need to be followed 

We need to place "andes-client-0.13.wso2v1.jar" , "slf4j.api_1.6.1.jar" and "slf4j.log4j12_1.6.1.jar" libraries in the root lib directory of wso2 ESB before starting the server. 

Note : Offset configuration is not working in the M2 release of MB 2.0. So  you need to change the offset value of ESB instead of MB and the connection String should be like:

connectionfactory.QueueConnectionFactory = amqp://admin:admin@clientID/carbon?brokerlist='tcp://localhost:5672'

WSO2 Message Broker 2.0 - M2 Released



WSO2 integration development team is pleased to announce that the feature freezed version of WSO2 Message Broker 2.0 is released. In this release we have added Clustering support for Message broker where it can act as a distributed Message broker.
You can find the documentation on different cluster scenarios,setup information in the deployment guide in the doc pack. 


You can find the current issues here



Wednesday, February 22, 2012

WSO2 MB - Samples : SQS SOAP Client Sample

Many users experiencing problems when testing this sample.



Here i am going to mention few simple steps to execute this sample.

1. Download WSO2MB 1.0.2 pack from http://wso2.org/downloads/message-broker

2. Extract and start the product.

3. Log in to the admin console of MB with credentials admin/admin



4. Navigate to the WSDL2Java tool which can be found in "Tools" left menu



5. Copy and paste the url of sqs wsdl to the provided test box in the "uri" option

6. Press generate button which can be found in the bottom of that page and it will give you the
zip file of generated source pack and save it.

7. Extract the source pack to your project folder. Once you extracted it, you can see a structure like :
.
|-- build.xml
|-- pom.xml
`-- src
`-- com
`-- amazonaws
`-- queue
`-- doc
`-- _2009_02_01
|-- MessageQueueCallbackHandler.java
|-- MessageQueueStub.java
|-- QueueServiceCallbackHandler.java
`-- QueueServiceStub.java


8. Go inside the project folder where you can find the above pom.xml file in the command line. Create the idea project by typing "mvn idea:idea".

9. Open the created project with IDEA

10. Add the SQSClient class to the project.

11. Change the "accessKey" and the "secretAccessKey" to the keys which can be found at "Home > Manage> Message Boxes(SQS)> Access Keys" of wso2mb server.


12.Build the project and execute the sqs client




NOTE:

Possible errors to be occurred when building the project

"cannot find symbol method createOMElement(org.apache.axiom.om.OMDataSource,javax.xml.namespace.QName)"

This is due to version mismatch of the axiom. Valid version of all axiom libraries is the version specified in the pom.xml

eg: 1.2.11.wso2v1

But where there are axiom libraries which is different from the above version, it gives above error.

You need to remove that version mismatching library from your class path .
Eg: axiom-api-1.2.7.jar

With this way you can get rid of this problem.

Thursday, February 16, 2012

Wednesday, February 15, 2012

ZooKeeper Increase maximum number of connections

When using zookeeper you may get the following exception:

org.apache.zookeeper.KeeperException$ConnectionLossException:
KeeperErrorCode = ConnectionLoss for /foo.XXXXXXXX
at org.apache.zookeeper.KeeperException.create(KeeperException.java

At the same time if you view the log of zookeeper you will see the the following warning :

WARN org.apache.zookeeper.server.NIOServerCnxn: Too many connections from /127.0.0.1 - max is 10

This is due to the default maximum number of connections configured in zookeeper.

You can overcome this by setting up the maximum number of connections in zoo keeper configuration file.(conf/zoo.cfg)

Add following entry to zoo.cfg file and restart zooKeeper. It will set maximum number of connections to 30.

"maxClientCnxns=30"

Killing multiple java processes at once

There are situations we need to kill multiple java processes at once. We can do it by killing all java processes. But there may be requirements to kill some filtered out java processes.

Lets say i have some processes which are running with details "OnceInOrderLoadTest.jar". I can kill all processes running with that details as bellow.


ps ax | grep OnceInOrderLoadTest.jar |grep -v grep | awk '{print $1}'| xargs kill -9

Wednesday, February 8, 2012

SQS Client for Stratos Live

It is a great advantage , if we can test message box feature of wso2 message broker in stratos live environment since it takes some time to set up product locally and test. Here i am going to describe how we can use a java client to invoke message box feature which acts as a message store of Wso2 Message broker in stratos live environment.

We can find the sample on creating "SQS SOAP Client" in here. This sample is specifically written for standalone product testing.

For stratos testing there are only few things need to be changed in this sample.

As described in the above sample as the first step you need to generate the code for the SQS wsdl.

For that you have multiple ways,
1. Use Axis2 wsdl2java tool for code generation
You can find samples on how to do that here.

2. Use wsdl2java feature of any of the wso2 products and generate the code from that.

Once you generate the code with using one of the above two methods, you can create a project using those source files.


If it is not automatically added the required libraries to the class path of your project, you need to add the libraries to the class path.

You can find all the required libraries for this source code in Message Broker product.
what you need to do is;

1. Extract wso2mb-1.0.2.zip
2. go to wso2mb-1.0.2/bin folder and run "ant" command
3. This will create a lib folder in "wso2mb-1.0.2/repository/" folder
4. You can add this lib folder to your class path

Once you have created the project successfully, you can use the same client for invoking Stratos Live Message Broker. How ever before invoking the client, you need to do some changes in that client code.

You need to change following constant of that client;
Eg: For the tenant foo.com , EPR will be

public static final String EPR = "http://messaging.stratoslive.wso2.com/services/a/foo.com/QueueService";

Apart from that you need to get the "accessKey" and the "secretAccessKey" after log in to the Message Broker service.

With changing those constants , you will be able to use the message box feature of Stratos Message Broker Service successfully.