Saturday, 12 July 2008

How to debug async responses in Axis2

In a dual-channel web services scenario (using WS-Addressing), its often hard to debug the responses, because the client opens a random URL and tells the server to send messages there. So even if you are sending the requests via a TCP monitor, such as TCPMON, the responses end up going direct.

Charitha has posted a blog entry on how to debug the responses. Here is another approach.

The problem is quite hard to describe without a diagram, and since its still Saturday morning I'm not up to graphics. Here is my attempt to describe without a diagram.

In a normal HTTP flow, its fairly easy to capture the messages. There are two options:
  1. Set up a (forward) HTTP proxy, and configure your client to use that proxy. This means that any request the client sends will go via the HTTP proxy, and the request will contain the real full address of the target HTTP endpoint.
    So instead of the HTTP normal request:
    POST /axis2/services/blah HTTP/1.1

    you get:
    POST http://server.com/axis2/services/blah HTTP/1.1

    The result is that the proxy looks at the request and uses the full URL to pass the message on.
  2. Set up a Reverse HTTP Proxy, and redirect the request to this address. In this model the reverse proxy listens on one port and sends everything to another host/port. So for example, anything that comes into port 8081 is sent to localhost:8080.
The TCPMON utility supports both models, but for some reason the second (reverse proxy) model is more popular. This is the approach that Charitha has documented. I prefer the forward proxy approach, and I have two reasons.

Firstly, the reverse proxy doesn't work with .NET. In the reverse proxy model, you are fooling the client into thinking the service is really hosted at port 8081. With WS-Addressing the address is not just used at the HTTP transport level, but also encoded into the WS-A headers. Now Axis2 is a little bit looser about checking WS-A headers, and ignores the host/port. But .NET validates the complete URL and will reject messages with the wrong host or port.

Secondly, the proxy option I propose can be used with any client, because you simply tell the server to send all asynchronous responses through the proxy.

Ok, enough blather, what do you need to do?

How to debug the return half of an async interaction.
1. Basically you need to setup a proxy to capture the responses.
2. Choose a port you aren’t already using (e.g. 999) and start tcpmon in Proxy mode
on that port
a. You can do this with the command line: tcpmon 999
b. Or through the TCPMON admin screen
3. Now edit the SERVER’s axis2.xml
4. You can read about this here: http://ws.apache.org/axis2/1_4/http-transport.html
5. Edit the Axis2.xml config to add the PROXY parameter:
<!-- ======================================= -->
<!-- Parameters -->
<!-- ======================================= -->
<parameter name="Proxy">
<Configuration>
<proxyhost>localhost</proxyhost>
<proxyport>999</proxyport>
</configuration>
</parameter>

6. Now all the responses (which are initiated by the server) will go through the
proxy

I suggest you try both my approach and Charitha's. I think there are going to be situations where each are more useful. I also want to thank Charitha for prompting me to blog my approach.

5 comments:

Charitha said...

Hi Paul,
Very helpful post! thanks!
The XML elements of axis2.xml (Step 5)are not shown in the post. You may need to use HTML tags for < and > to show them in the post.
Thanks
Charitha

Glen Daniels said...

Your approach, Paul, assumes that the server is a) Axis2, and b) under your control. In many cases, one or the other isn't true, so I have to say I tend to prefer Charitha's technique - rewriting the wsa:ReplyTo address works regardless of the server.

Paul Fremantle said...

Glen

Good point. I think you can say that if the server is in your control, then my approach works, and if the client is in your control Charitha's approach works. So that way you have both options covered.

However, in either case its worth noting that the "reverse proxy" model will never work with .NET (except with extra configuration), so if you have the client in your control and talking to a .NET server, you want to make sure outgoing requests go through a forward proxy.

Glen Daniels said...

Good point backatcha, Paul! :)

If you own the server but not the client, then you can use your technique to set the outgoing proxy, and if you want the incoming requests you'll need to move your server to a new port and put a TCPMON on the old one. If you own the client, then you can use Charitha's technique to rewrite the ReplyTo, and optionally use an outgoing proxy TCPMON to catch the requests too.

One last quick note - this stuff can also be accomplished with Synapse / ESB, by sitting the mediator in front of the service and having it rewrite the ReplyTos to go back to itself.

season said...

Your article is very good.I like it very much.
Once upon a time, there was a mouse father.He wanted to marry his daughter to the greatest person in the world.But, who was the greatest person in the world?Oh!
puma ferrari shoes
cheap nike shoesThe sun! He must be the greatest person in the world.The mouse father went to talk to the sun."Hello! Mr. Sun.
puma shoes
ferrari shoes
I know you are the greatest person in the world.Would you marry my daughter?""What? I'm not the greatest person in the world. The greatest person is the cloud.If he comes out, I’ll be covered."
nike shox nz
Ugg Boots
The mouse father went to talk to the cloud. “Hello! Mr. Cloud. I know you are the greatest person in the world. Would you marry my daughter?”
nike 360 air max
nike shox shoes
“What? I’m not the greatest person in the world. The greatest person is the wind.If he comes out, I’ll be blown away.”
cheap puma shoes
puma drift cat
The mouse father went to talk to the wind. “Hello! Mr. Wind. I know you are the greatest person in the world.Would you marry my daughter?” “What? I’m not the greatest person in the world. The greatest person is the wall. If he comes out, I’ll be stopped.”
cheap nike shox
nike air max 360
The mouse father went to talk to the wall. “Hello! Mr. Wall. I know you are the greatest person in the world. Would you marry my daughter?” “What? I’m not the greatest person in the world. The greatest person is YOU, the mouse.” “The greatest person in the world is … mouse?” “Yes, the greatest person in the world is mouse. See? If mouse comes out, I’ll be bit!”
nike air max
pumas shoes
The mouse father was very happy. He finally knew mouse was the greatest person in the world. He would marry his daughter to the handsome mouse next door.
puma mens shoes
nike shoxs
Chaussures puma
nike womens shoes
mens puma shoes
nike air max