Popular Posts

Friday, June 20, 2008

WS-Reliable messaging with WSO2 WSAS -1

Web services are an essential component of distributed computing. Reliable communication between services and service consumers should be taken in to account when designing SOA based systems.
WS-Reliability is a SOAP-based specification that fulfills reliable messaging requirements critical to web service applications.
The objective of this post is not to discuss the features and architectural details of WS-Reliable Messaging (WS-RM). You can find the WS-RM specification from here and a lot of useful materials are available on the web. I'm going to demonstrate the simplest RM scenario, one-way single channel invocation using WSO2 mercury, which is an implementation of WS-RM using Apache Axis2.
WSO2 mercury is shipped as a module with WSO2 web services application server version 2.3 (WSO2 WSAS-2.3) as well as a separate piece of product. I'm going to describe the scenario using WSO2 WSAS, however you may also follow the given steps with Axis2-1.4 .

We are going to send a set of ping messages (one-way messages) to a web service in reliable manner. In other words, we send a set of requests to a service and block the channel at the middle of message transmission. Then we restart the transport channel. If WS-RM is not enabled, the message transmission will be lost when the transport channel goes down. You have to re-send messages. However, if our service and client are configured to use Wso2 mercury (WS-RM implementation), it will take care of guaranteed delivery of the rest of the messages when the transport channel is back again.

Lets see how reliable messaging can be used with WSO2 WSAS and Mercury.

Install WSO2 WSAS-2.3

Step 1 - Service configuration

Create a simple web service implementation class as follows.

package org.wso2.wsas.service;
public class MercuryService{

//Oneway messaging
public void Ping(String s){
System.out.println("*****Received the ping request*****");

Compile and save the class.

Next, create a service descriptor (services.xml) as given below and save it in a META-INF directory.

<service name="MercuryService">
Mercury test service
<messageReceiver mep="http://www.w3.org/2006/01/wsdl/in-only"
<messageReceiver mep="http://www.w3.org/2006/01/wsdl/in-out"
<module ref="Mercury" />
<parameter name="ServiceClass" locked="false">

Note that <module> element is used to engage the Mercury module, which provides reliable messaging at the server side.

Now, create a deployable Axis2 service archive (*.aar) using the above service implementation class and META-INF/services.xml file. (Please have a look at Axis2 user guide if you are not familiar with service archive structure)

Copy the created service archive (Lets say it is "MercuryService.aar") to WSAS_HOME/repository/services directory. It will be deployed on WSAS. Start WSO2 WSAS using wso2wsas.bat{sh} and login in to admin console (https://localhost:9443)

Go to the services and service group management page and you should see the "MercuryService" there. Click on the service name. You will be directed to MercuryService's service management page. Click on "Manage Module Engagements" link. You will notice that the mercury module is listed under "Modules engaged at service level".

That's all for configuring RM at the web service level. Let's take a look at the client side configuration.

Step 2 - Generate stubs

First, we need to generate client side stubs through WSO2 WSAS management console. In the MercuryService's service management page, select "Generate Client". "Stub Generation" page will be displayed. Click on "Generate" with the code gen options as specified in the following image.

Save the generated jar file in your file system.

Step 3 - Write Client

Now write the client to invoke service in reliable manner. Make sure to add jars in WSAS_HOME/lib and the generated client stub jar in the previous step to your class path in order to compile the client.

package org.wso2.wsas.client;

public class OnewayAnnonSOAP11Client{

public static void main(String args[])throws AxisFault{

ConfigurationContext cc = ConfigurationContextFactory.createConfigurationContextFromFileSystem

MercuryServiceStub stub = new MercuryServiceStub(cc, "http://localhost:9080/services/MercuryService");
MercuryServiceStub.Ping request = new MercuryServiceStub.Ping();


for (int i = 0; i < 100; i++) {
try {
} catch (RemoteException e) {
} try
{ Thread.sleep(1000);
} catch (InterruptedException e) {
// Setting the last message stub._getServiceClient().getOptions().setProperty("MercuryLastMessage", Constants.VALUE_TRUE);
try { stub.Ping(request);
} catch (RemoteException e) {
e.printStackTrace(); }
try { Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace(); } } }

In order to get the reliable messaging support at the client, we need to engage Mercury module with "stub._getServiceClient().engageModule("Mercury")". We need to have ConfigurationContext to define the client repository where the Mercury.mar and axis2 configuration file (axis2.xml) is placed. Create a directory, client-repo and copy WSAS_HOME/repository/modules/mercury.mar to client-repo/modules directory. Also, create a sub-directory conf under client-repo and copy an axis2.xml file ( I have used axis2.xml copied from Axis2-1.4) in to that folder. You can call ping method of your webservice inside a loop so that multiple requests will be submitted. stub.Ping(request); In reliable messaging, a Sequence is created using a CreateSequence interaction, and terminated when finished with a TerminateSequence interaction. Therefore, a CreateSequence message is generated by client as the first step. If the CreateSequenceResponse message is received, then the actual application message delivery is started. Each message in a sequence has a message number, which starts at one and increments by one for each message. These message numbers are used to acknowledge the messages. In order to complete the sequence, the last message should be stated explicitly with stub._getServiceClient().getOptions().setProperty("MercuryLastMessage", Constants.VALUE_TRUE); Lets try to understand this scenario by sending messages via tcpmon. Start tcpmon and configure listen port as 9080 and target port as 9762.

Step 4 - Run client and monitor with TCPmon

Now run the client and check the messages delivered through tcpmon. You will notice that the first message is "CreateSequence". You will see that <wsrm:MessageNumber>1</wsrm:MessageNumber> soap header element in the next message where the actual ping request payload is transmitted.

Finally, check whether the messages are delivered reliably when your transport medium is interrupted. While the request soap messages are being sent, stop the incoming transport channel through tcpmon. You may do so by just stopping the port 9080. Wait a few seconds. Restart port 9080. You should see that the message transmission is resumed.

Thats all for now! will post more on WSO2 WSAS/Axis2 and RM soon.


kothai said...
This comment has been removed by the author.
Tom Shearer said...

Hi Following the instructions in you blog, I'm getting an end point error from the service when I run it:

Error here... org.apache.axis2.AxisFault: The endpoint reference (EPR) for the Operation not found is /services/MercuryService and the WSA Action = null

at org.apache.axis2.engine.DispatchPhase.checkPostConditions(DispatchPhase.java:88)

at org.apache.axis2.engine.Phase.invoke(Phase.java:333)

at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:264)

at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:163)

at org.apache.axis2.transport.http.util.RESTUtil.invokeAxisEngine(RESTUtil.java:136)

at org.apache.axis2.transport.http.util.RESTUtil.processURLRequest(RESTUtil.java:130)

at org.apache.axis2.transport.http.AxisServlet$RestRequestProcessor.processURLRequest(AxisServlet.java:824)

at org.wso2.wsas.transport.WSASServlet.handleRestRequest(WSASServlet.java:149)

at org.wso2.wsas.transport.WSASServlet.doGet(WSASServlet.java:138)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)

at org.wso2.adminui.AdminUIServletFilter.doFilter(AdminUIServletFilter.java:142)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)

at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870)

at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)

at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)

at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)

at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)

at java.lang.Thread.run(Thread.java:595)

Any pointers are appreciated.


Charitha said...

Hi Tom,
Can you please make sure you have following line of code in your client? Make sure to use the correct url. Check spaces etc..
MercuryServiceStub stub = new MercuryServiceStub(cc, "http://localhost:9080/services/MercuryService");

Normally, this error occurs if the client cannot find the service endpoint.
If you encounter more issues please let me know.

Tom said...


Thanks for the help, I've got that sorted, but now I have a new error, this one is thankfully much shorter...

Exception in thread "main" org.apache.axis2.AxisFault: Unable to engage module : Mercury
at org.apache.axis2.client.ServiceClient.engageModule(ServiceClient.java:357)
at org.wso2.wsas.client.OnewayAnnonSOAP11Client.main(OnewayAnnonSOAP11Client.java:20)

Charitha said...

your client could not find mercury.mar in your repository hence it threw this error. Therefore please make sure you have mercury.mar in the client repository.
As I explained in the post, you must create a directory, client-repo and copy WSAS_HOME/repository/modules/mercury.mar to client-repo/modules directory. (Make sure mercury.mar is placed in a directory called "modules" inside client-repo)
So your client repository will be as follows.
- modules

Then use this as an argument in ConfigurationContextFactory.createConfigurationConttextFromFileSystem("C:\\RM\\client-repo", "\\..\\");

Tom said...


Thanks for your help getting this to work

crystal said...

Perfect!!You are a outstanding person!Have you ever wore chaussures puma,Here are the most popular puma CAT,Puma shoes store gives some preview of puma speed cat,and casual but no sweat puma basket.

crystal said...

Thank you so much!!polo shirt men'ssweate,Burberry Polo Shirts lacoste sweater, ralph lauren Columbia Jackets,ski clothing. Free Shipping, PayPal Payment. Enjoy your shopping experience on mensclothingus.com.You can find the father who desire fashionable, intellectual mens clothing simultaneously.

crystal said...

God bless you!I really agree with your opinions.Also,there are some new fashion things here,gillette razor blades.gillette mach3 razor bladesfor men.As for ladies,gillette venus razor blades must the best gift for you in summer,gillette fusion blades are all the best choice for you.

crystal said...

Do not mean bad.Thank you so much!I just want to show some fashion things to all of you.I like puma speed, puma femmes and other puma shoes. These puma sport items are at store recently and available for anyone.

crystal said...

Fantastic!God bless you!Meanwhile,you can visit my China Wholesale,we have the highest quality but the lowest price fashion products wholesale from China.Here are the most popular China Wholesale productsfor all of you.You can visit http://chinaclothes.net.Also the polo clothing is a great choice for you.

crystal said...

Awesome!!!Best wishes for you !!cheap polo shirts is the father of the summer should be prepared to most commonly used item, it has both style and shape of Ralph Lauren Polo, and vest with a random function polo ralph lauren, so that in the short-sleeved apply to both on many occasions, the pink and black color men's polo shirts brought into effect, lightweight cotton, linen texture to demonstrate masculine temperament and sense of fashion exhaustively.

swimingfidh said...


swimingfidh said...

There are ed hardy shirts
,pretty ed hardy shirt for men,

ed hardy womens in the ed hardy online store

designed by ed hardy ,
many cheap ed hardy shirt ,glasses,caps,trouers ed hardy shirts on sale ,

You can go to edhardyshirts.com to have a look ,you may find one of ed hardy clothing fit for you
Top qualitymen's jacket,
These cheap jacket are on sale now,you can find
north face jackets inmage on our web
Ralph Lauren Polo Shirtsbuberry polo shirts

Do you wannaghd hair straighteners for you own , we have many
cheap ghd hair straightenersin style and great,you can choose one from these
hair straighteners
Authentic chaussure puma
chaussure sport
And chaussure nike shoes

swimingfidh said...

Come here to have a look of our Wholesale Jeans
Many fashionMens Jeans ,eye-catching
Womens Jeans ,and special out standing
Blue Jeans ,you can spend less money on our
Discount Jeans but gain really fine jeans, absolutely a great bargain.
China Wholesale
wholesale from china
buy products wholesale
China Wholesalers