tag:blogger.com,1999:blog-6003063374827736283.post-23212305781435208022007-05-22T01:15:00.000-07:002007-05-22T02:14:54.234-07:00Getting started with WSRM and Axis2This is a short HOWTO on getting your first WS-ReliableMessaging interaction going with <a href="http://ws.apache.org/axis2">Axis2</a> and <a href="http://ws.apache.org/sandesha2">Sandesha2</a>. [Sandesha2 is an Open Source implementation of both the WSRM 1.0 and WSRM 1.1 specifications].<br /><br />First, download the prereqs.<br /><br />I'm proposing you do this with Axis2 1.2 - the latest release at the time of writing (May 2007).<br /><br />Here is the <a href="http://ws.apache.org/axis2/download/1_2/download.cgi">download</a>. You can use the standalone ZIP or the WAR file. I'm assuming you've already used Axis2 enough to know deploying services and creating clients.<br /><br />The Sandesha2 1.2 release isn't yet available, so I'm posting a <a href="ftp://fremantle.org/axis2_sandesha/sandesha2-SNAPSHOT.mar">snapshot</a> that you can use. As soon as it becomes available I'll point to the real thing.<br /><br /><span style="font-weight: bold;">Make the Version service Reliable</span><br />1) Take the version.aar file from the Axis2 distribution and edit the services.xml<br /><br />Underneath the <service><span style="font-weight: bold;"> <services></span> tag add<br /><span style="font-family:courier new;"><module ref="sandesha2"><br /></span></service><br /><br />You can either do it by hand, and update the AAR file (which is just a JAR file) or by go edit the build in <axis2_home>\samples\version.<br /><br />I use <a href="http://www.7-zip.org/">7-Zip</a> file manager, which updates MAR and AAR files with any edits I make in-place which is great. I can just browse the AAR file, edit the XML, save it, and 7-Zip updates the AAR with my edits.<br /><br />If you are too lazy to do either of those, I've posted the version.aar file with the updates <a href="ftp://fremantle.org/axis2_sandesha/version.aar">here</a>.<br /><br /><span style="font-weight: bold;">Add the right phases to Axis2</span><br />2) Edit your <axis2_home><span style="font-weight: bold;">/conf/axis2.xml</span> to add<br /></axis2_home><pre><phase name="RMPhase"></phase></pre> <phase name="RMPhase"/><br /><br /><br />Just between OperationIn/Out/InFault/OutFaultPhases and SoapMonitorPhase (4 places in all):<div style="direction: ltr;"><br />e.g.<br /> <phase name="OperationInFaultPhase"/><br /> <phase name="RMPhase"/><br /> <phase name="soapmonitorPhase"/><br /><br /><phase name="OperationInFaultPhase"> <phase name="RMPhase"><phase name="soapmonitorPhase"><span style="font-weight: bold;">Deploy Sandesha2</span><br />3) Deploy sandesha2.mar into <AXIS2_HOME><axis2_home>/repository/modules<br /><br /><span style="font-weight: bold;">Check if its working</span><br />4) Start Axis2 and verify that the RM operations are listed when you<br />look at the version service via the browser<br /><a onclick="return top.js.OpenExtLink(window,event,this)" href="http://localhost:8080/axis2/services/" target="_blank">http://localhost:8080/axis2<wbr>/services/</a><br /><br />You should see extra operations listed under Version such as<br /></axis2_home></phase></phase></phase><ul><li>Sandesha2OperationInOut</li><li>Sandesha2OperationOutIn</li><li>getVersion</li><li>Sandesha2OperationOutOnly</li><li>Sandesha2OperationInOnly</li><li>Sandesha2OperationDuplicate</li></ul><br /><span style="font-weight: bold;">Create a client</span><br />5) Build a client for the service using WSDL2Java:<br /><axis2_home>\bin\wsdl2java.bat -uw -uri <a onclick="return top.js.OpenExtLink(window,event,this)" href="http://localhost:8080/axis2/services/Version?wsdl" target="_blank">http://localhost:8080/axis2<wbr>/services/Version?wsdl</a> -o client<br /><br />This will put the client code in .\client\ directory from where you ran the command.<br /><br />WSDL2Java automatically creates an <a href="http://ant.apache.org/">Ant</a> build script, so you can test the build works using:<br /><span style="font-weight: bold;">> </span><span style="font-family:courier new;">ant<br /><br /></span>If you use Eclipse you can create a new project for this based on the Ant build.xml and you will get all the right libraries, etc. Just select File->New->Project, Java Project From Existing Ant Buildfile<br /><br />6) Now go to .\client\src and add this Java class <a href="ftp://fremantle.org/axis2_sandesha/TestRM.java">TestRM.java</a><br /><br /><span style=";font-family:courier new;font-size:85%;" >import org.apache.axis2.context</span><wbr style="font-family:courier new;"><span style=";font-family:courier new;font-size:85%;" >.ConfigurationContext;</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >import org.apache.axis2.context</span><wbr style="font-family:courier new;"><span style=";font-family:courier new;font-size:85%;" >.ConfigurationContextFactory;</span><span style="font-size:85%;"><br /></span><script><!-- D(["mb","import org.apache.axis2.transport\u003cwbr /\>.http.HTTPConstants;\u003cbr /\>import org.apache.axis2.transport\u003cwbr /\>.http.HttpTransportProperties\u003cwbr /\>.ProxyProperties;\u003cbr /\>\u003cbr /\>import sample.axisversion.VersionVers\u003cwbr /\>ionSOAP12Port_httpStub;\u003cbr /\>\u003cbr /\>public class TestRM {\u003cbr /\> public static void main(String[] args) throws Exception {\u003cbr /\>\u003cbr /\> // use a config context to ensure I have the right Axis2.xml and\u003cbr /\>Sandesha2 module\u003cbr /\> ConfigurationContext cc \u003d\u003cbr /\>ConfigurationContextFactory\u003cwbr /\>.createConfigurationContextFro\u003cwbr /\>mFileSystem("c:/axis2-1.2/repository","c:/axis2-1.2/conf/axis2.xml");\u003cbr /\>\u003cbr /\> // Use the generated Stub with the config Context\u003cbr /\> VersionVersionSOAP12Port\u003cwbr /\>_httpStub stub \u003d new\u003cbr /\>VersionVersionSOAP12Port\u003cwbr /\>_httpStub(cc,\u003cbr /\>"\u003ca onclick\u003d\"return top.js.OpenExtLink(window,event,this)\" href\u003d\"http://localhost:8080/axis2/services/Version\" target\u003d_blank\>http://localhost:8080/axis2\u003cwbr /\>/services/Version\u003c/a\>");\u003cbr /\>\u003cbr /\> // WSRM prereqs Addressing\u003cbr /\> stub._getServiceClient()\u003cwbr /\>.engageModule("addressing");\u003cbr /\>\u003cbr /\> // Sandesha2 provides WSRM support\u003cbr /\> stub._getServiceClient()\u003cwbr /\>.engageModule("sandesha2");\u003cbr /\>\u003cbr /\> // go through a proxy so I can see what is happening\u003cbr /\> // dont forget to startup TCPMON\u003cbr /\> ProxyProperties pp \u003d new ProxyProperties();\u003cbr /\> pp.setProxyName("localhost"); pp.setProxyPort(8001);\u003cbr /\>",1] ); //--></script><span style=";font-family:courier new;font-size:85%;" >import org.apache.axis2.transport</span><wbr style="font-family:courier new;"><span style=";font-family:courier new;font-size:85%;" >.http.HTTPConstants;</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >import org.apache.axis2.transport</span><wbr style="font-family:courier new;"><span style=";font-family:courier new;font-size:85%;" >.http.HttpTransportPropertie</span><span style=";font-family:courier new;font-size:85%;" >.ProxyProperties;</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" >import sample.axisversion.VersionVers</span><wbr style="font-family:courier new;"><span style=";font-family:courier new;font-size:85%;" >ionSOAP12Port_httpStub;</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" >public class TestRM {</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > public static void main(String[] args) throws Exception {</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" > // use a config context to ensure I have<br />// the right Axis2.xml and </span><span style=";font-family:courier new;font-size:85%;" >Sandesha2 module<br />// Change the paths to fit your filesystem of course<br /></span><span style="font-weight: bold;font-family:courier new;font-size:85%;" > ConfigurationContext cc = </span><span style="font-weight: bold;font-family:courier new;font-size:85%;" >ConfigurationContextFactory</span><span style="font-weight: bold;font-family:courier new;font-size:85%;" >.createConfigurationContextFr</span><span style="font-weight: bold;font-family:courier new;font-size:85%;" >mFileSystem("c:/axis2-1.2/repository","c:/axis2-1.2/conf/axis2.xml");</span><span style="font-weight: bold;font-size:85%;" ><br /></span><span style=";font-family:courier new;font-size:85%;" > // Use the generated Stub with the config Context</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > VersionVersionSOAP12Port</span><wbr style="font-family:courier new;"><span style=";font-family:courier new;font-size:85%;" >_httpStub stub = new </span><span style=";font-family:courier new;font-size:85%;" >VersionVersionSOAP12Port</span><span style=";font-family:courier new;font-size:85%;" >_httpStub(cc,</span><span style=";font-family:courier new;font-size:85%;" >"</span><span style="font-size:85%;"><a style="font-family: courier new;" onclick="return top.js.OpenExtLink(window,event,this)" href="http://localhost:8080/axis2/services/Version" target="_blank">http://localhost:8080/axis2<wbr>/services/Version</a></span><span style=";font-family:courier new;font-size:85%;" >");</span><span style="font-size:85%;"><br /><br /></span><span style="font-weight: bold;font-family:courier new;font-size:85%;" > // WSRM prereqs Addressing</span><span style="font-weight: bold;font-size:85%;" ><br /></span><span style="font-weight: bold;font-family:courier new;font-size:85%;" > stub._getServiceClient()</span><wbr style="font-weight: bold;font-family:courier new;"><span style="font-weight: bold;font-family:courier new;font-size:85%;" >.engageModule("addressing");</span><span style="font-size:85%;"><br /><br /></span><span style="font-weight: bold;font-family:courier new;font-size:85%;" > // Sandesha2 provides WSRM support</span><span style="font-weight: bold;font-size:85%;" ><br /></span><span style="font-weight: bold;font-family:courier new;font-size:85%;" > stub._getServiceClient()</span><wbr style="font-weight: bold;font-family:courier new;"><span style="font-weight: bold;font-family:courier new;font-size:85%;" >.engageModule("sandesha2");</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" > // go through a proxy so I can see what is happening</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > // dont forget to startup TCPMON - tcpmon 8001</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > ProxyProperties pp = new ProxyProperties();</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > pp.setProxyName("localhost"); pp.setProxyPort(8001);</span><span style="font-size:85%;"><br /></span><script><!-- D(["mb"," stub._getServiceClient()\u003cwbr /\>.getOptions().setProperty(HTTPConstants.PROXY, pp);\u003cbr /\>\u003cbr /\> // This is the first message, so it will automatically kick off a\u003cbr /\>CreateSequence\u003cbr /\> System.out.println(stub.getVersion());\u003cbr /\>\u003cbr /\> // now mark the second message as the last\u003cbr /\> stub._getServiceClient()\u003cwbr /\>.getOptions().setProperty(\u003cwbr /\>"Sandesha2LastMessage",\u003cbr /\>"true");\u003cbr /\>\u003cbr /\> // after the last message is sent, we should send a Terminate\u003cbr /\>Sequence automatically\u003cbr /\> System.out.println(stub.getVersion());\u003cbr /\>\u003cbr /\> // give enough time for it to work\u003cbr /\> Thread.sleep(1000);\u003cbr /\>\u003cbr /\> // System exit because there will be Sandesha threads otherwise running\u003cbr /\> System.exit(0);\u003cbr /\> }\u003cbr /\>}\u003cbr /\>\u003cbr /\>7) Build everything (ant in client\\ should work). I use Eclipse and I\u003cbr /\>started out with the build file\u003cbr /\>\u003cbr /\>8) Remember to start TCPMON up. It needs to be running in PROXY mode\u003cbr /\>on port 8001.\u003cbr /\>You can do this by typing\u003cbr /\>tcpmon 8001\u003cbr /\>\u003cbr /\>9) If you used Ant to build the file then you can call the class like this:\u003cbr /\>java -Djava.ext.dirs\u003d\\axis2-1.2\\lib;\\code\\client\\build\\lib\\ TestRM\u003cbr /\>\u003cbr /\>Obviously this only works if your axis2 is in \\axis2-1.2 and you built\u003cbr /\>the client in the \\code directory, but you get the idea and can switch\u003cbr /\>it to work.\u003cbr /\>\u003cbr /\>10) You should see something like:\u003cbr /\>",1] ); //--></script><span style=";font-family:courier new;font-size:85%;" > stub._getServiceClient()</span><span style=";font-family:courier new;font-size:85%;" >.getOptions().setProperty(HTTPConstants.PROXY,pp);</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" > // This is the first message, so it will automatically kick off a </span><span style=";font-family:courier new;font-size:85%;" >CreateSequence</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > System.out.println(stub.getVersion());</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" > // now mark the second message as the last</span><span style="font-size:85%;"><br /></span><span style="font-weight: bold;font-family:courier new;font-size:85%;" > stub._getServiceClient()</span><wbr style="font-weight: bold;font-family:courier new;"><span style="font-weight: bold;font-family:courier new;font-size:85%;" >.getOptions().setProperty(</span><span style="font-weight: bold;font-family:courier new;font-size:85%;" >"Sandesha2LastMessage",</span><span style="font-weight: bold;font-family:courier new;font-size:85%;" >"true");</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" > // after the last message is sent, we should send a Terminate </span><span style=";font-family:courier new;font-size:85%;" >Sequence automatically</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > System.out.println(stub.getVersion());</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" > // give enough time for it to work</span><span style="font-size:85%;"><br /></span><span style="font-weight: bold;font-family:courier new;font-size:85%;" > Thread.sleep(1000);</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" > // System exit because there will be Sandesha threads otherwise running</span><span style="font-size:85%;"><br /></span><span style="font-weight: bold;font-family:courier new;font-size:85%;" > System.exit(0);</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > }</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >}</span><span style="font-size:85%;"><br /></span><br /><span style="font-weight: bold;">Let's just look at this code</span><br />Firstly, what is the overall flow? Simple! New up a stub, call stub.getVersion() twice and then exit. I've bolded the changes we make to be reliable.<br />So what have we added to make it work with RM?<br /></axis2_home><ul><li>Instead of using the default config, we explicitly want Axis2 to read the modified axis2.xml and also to use the repository containing Sandesha2.mar. So we use a custom ConfigurationContext.</li><li>Secondly, we want to see RM happening, so we set up a Proxy. For this we are going to use <a href="http://ws.apache.org/commons/tcpmon/">TCPMON</a>.</li><li>Thirdly, we need to engage Addressing and Sandesha to ensure the modules do their thing.<br /></li><li>We need to let Sandesha know when we are complete. There are a couple of ways to do this, but the very simplest is to mark the LastMessage. (This is based on WSRM1.0), so just before the second call to getVersion() we do this.</li><li>Finally, Apache Sandesha spawns threads, so we do a Thread sleep and then a System.exit(0) which ensures that the code exits.<br /></li></ul><axis2_home>7) Build everything (Running <span style="font-family:courier new;">ant</span> in client\ should work).<br /><br />8) Remember to start TCPMON up. It needs to be running in PROXY mode on port 8001.<br />You can do this by typing<br />> <span style="font-family:courier new;">tcpmon 8001</span><br /><br />9) If you used Ant to build the file then you can call the class like this:<br /><span style="font-family:courier new;">> java -Djava.ext.dirs=\axis2-1.2\lib;\code\client\build\lib\ TestRM</span><br /><br />Obviously this only works if your Axis2 is in <span style="font-weight: bold;">\axis2-1.2 </span>and you built the client in the <span style="font-weight: bold;">\code</span> directory, but you get the idea and can switch it to work.<br /><br />10) You should see something like:<br /><script><!-- D(["mb","May 21, 2007 5:45:21 PM org.apache.axis2.deployment\u003cwbr /\>.ModuleDeployer deploy\u003cbr /\>INFO: Deploying module: addressing-1.2\u003cbr /\>May 21, 2007 5:45:22 PM org.apache.axis2.deployment\u003cwbr /\>.ModuleDeployer deploy\u003cbr /\>INFO: Deploying module: sandesha2\u003cbr /\>May 21, 2007 5:45:22 PM org.apache.axis2.deployment\u003cwbr /\>.ModuleDeployer deploy\u003cbr /\>INFO: Deploying module: soapmonitor-1.2\u003cbr /\>May 21, 2007 5:45:22 PM org.apache.sandesha2.SandeshaM\u003cwbr /\>odule init\u003cbr /\>WARNING: Could not load module policies. Using default values.\u003cbr /\>May 21, 2007 5:45:22 PM org.apache.axis2.deployment\u003cwbr /\>.ServiceDeployer deploy\u003cbr /\>INFO: Deploying Web service: version.aar\u003cbr /\>Hello I am Axis2 version service , My version is 1.2\u003cbr /\>Hello I am Axis2 version service , My version is 1.2\u003cbr /\>\u003cbr /\>11) If you look at the TCPMON Trace you should see 4 message interactions:\u003cbr /\>CreateSequence/CSR\u003cbr /\>Request 1\u003cbr /\>Request 2/LastMessage\u003cbr /\>TerminateSequence.\u003cbr /\>\u003c/div\>",1] ); D(["mb","\u003cdiv style\u003d\"direction:ltr\"\>\u003cspan class\u003dsg\>\u003cbr /\>Paul\u003cbr /\>\u003c/span\>\u003c/div\>",1] ); //--></script><span style="font-family:courier new;">May 21, 2007 5:45:21 PM org.apache.axis2.deployment</span><wbr style="font-family:courier new;"><span style="font-family:courier new;">.ModuleDeployer deploy</span><br /><span style="font-family:courier new;">INFO: Deploying module: addressing-1.2</span><br /><span style="font-family:courier new;">May 21, 2007 5:45:22 PM org.apache.axis2.deployment</span><wbr style="font-family:courier new;"><span style="font-family:courier new;">.ModuleDeployer deploy</span><br /><span style="font-family:courier new;">INFO: Deploying module: sandesha2</span><br /><span style="font-family:courier new;">May 21, 2007 5:45:22 PM org.apache.axis2.deployment</span><wbr style="font-family:courier new;"><span style="font-family:courier new;">.ModuleDeployer deploy</span><br /><span style="font-family:courier new;">INFO: Deploying module: soapmonitor-1.2</span><br /><span style="font-family:courier new;">May 21, 2007 5:45:22 PM org.apache.sandesha2.SandeshaM</span><wbr style="font-family:courier new;"><span style="font-family:courier new;">odule init</span><br /><span style="font-family:courier new;">WARNING: Could not load module policies. Using default values.</span><br /><span style="font-family:courier new;">May 21, 2007 5:45:22 PM org.apache.axis2.deployment</span><wbr style="font-family:courier new;"><span style="font-family:courier new;">.ServiceDeployer deploy</span><br /><span style="font-family:courier new;">INFO: Deploying Web service: version.aar</span><br /><span style="font-family:courier new;">Hello I am Axis2 version service , My version is 1.2</span><br /><span style="font-family:courier new;">Hello I am Axis2 version service , My version is 1.2</span><br /><br />11) If you look at the TCPMON Trace you should see 4 message interactions:<br />1. CreateSequence/CSR<br />2. Request 1<br />3. Request 2/LastMessage<br />4. TerminateSequence.<br /></axis2_home></div><span class="sg"><br /></span><br />Congratulations - you have just got RM working (I hope!!!).<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6003063374827736283-2321230578143520802?l=pzf.fremantle.org'/></div>Paul Fremantlehttp://www.blogger.com/profile/15326219720808613358noreply@blogger.com11