WS-Addressing and routing is a pain in the ass
So here we have our nice soap 1.2 messaging standard. All works fine with encryption, signing, policies, end-points, validation, schema's. Microsoft created most drafts for the WS-* specs I think and in time they were slowly change to requests from the market and WSE (wizzy) is a nice product of their effort. I know that we'll get WCF in the future but that also has to work with the WS-* standards and doesn't solve the problem I am currently having.
We start our adventure with a contract first design. We create a nice interface with mostly fat messages in a fire and forget fashion if possible and then start to implement the damn service. But then multiple systems start implementing the same service. Not a problem of course because the loosely coupled design of the contract first method is exactly the reason why we choose this.
Our client knows the interface and asks some kind of service locator for an end-point that knows this contract and voila we seem to have multiple implementations. This isn't an issue when you are within one enterprise. You just configure to use just one implementation for your client. But now imagine that we want to connect multiple enterprises that all publish at least one service with this contract.
The question the client is having is "I want to communicate with enterprise X with contract Y and I want an end-point for that enterprise". Not a problem if system X is allowed to directly communicate with another system. The soap specs has the WS-Addressing for this. We have a Destination element that contains a uri for the service identifier (Address) and the end-point that knows how to process this message (Via). All is working fine if you can communicate directly through any transport mechanism. Doesn't matter if it's http, msmq, smtp, tcp, udp or in-process it just works.
But now we have this issue that says that all messages between systems pass a message broker. The sender knows where the message must be going (enterprise X) and know through which system the message must be routed being the message broker. I could those between the following implementations:
A - The client knows the exact end-point uri but sends it to the message broker and supplies it with meta-information to route the message (the soap service end-point that processes the message).
B - The client only knows the contract and no end-point and sends it to the message broker with meta-information about the destination enterprise (domain name for example)
1. In the first scenario (A) I would imagine that the client sends a the soap message to the message broker that just picks it up and sends it to the listener within enterprise X. It does this for example with meta-information in a custom soap-header within the soap envelope. The message structure stays the same and only the soap header gets slightly modified by the message broker.
2. Another option is that the client wraps up the message within another message. The inner message contains the actual message to be delivered to enterprise X. The outer message contains information where to route/send the inner message to. The message broker unwraps the outer message and sends the inner message to end-point for enterprise X that knows this contract.
3. In the second scenario (B) the client is unaware of end-point for enterprise X. It only knows that the message is for enterprise X. Here we can do the same two techniques as I just described.
I always try to reflect these kind of situations to everyday stuff. So this seems like the normal snail mail system we have. We write a message for a department, stuff the paper in an envelope and write the address of the organisation that should receive it on the envelope. We only know that mailbox in our street and only god knows how that envelope can get shipped that fast to the other side of the world. The envelope was never opened or repackaged but it did travel by car, fan, plane or bicycle (the different transports). What did happen is that the envelope got wrapped in a container. This container could be the actual car, fan or plane. So you could say it got wrapped by the enveloper that is needed for that kind of transport.
This makes me quite confused to be honest....
But then I thought "those soap dudes that thought about the design of WS-Addressing must have thought about it's usage thoroughly". After googling for hours searching for examples and browsing the w3c documents I can just come up with one conclusion. WS-Addressing does not fix my problem.
I have found the most interesting posts about routing problems with WS-Addressing at Steve Main
- [Adventures in Next-Hop Routing (part 1 of n)
- [Adventures in next-hop routing part 2: the return address rabbit-hole
- [Subsuming WS-Referral with WS-Addressing
These are posted about 2 years ago but the best I could find.
With this information I come to the conclusion that the soap messages should not be wrapped within a new soap envelope. The existing soap envelope should be extended with end-point information and routing hints. But it seems that there isn't a standard for this. I also found an msdn article [Moving from WS-Routing to WS-Addressing Using WSE 2.0
] where they have the following example:
<wsa:ServiceName wsa:PortName="ChatPort" xmlns:c="urn:chat">c:WseChat</wsa:ServiceName>
But the sample is wrong especially with the contract first approach in mind. The To
references a real end-point without service information. The rather strange thing is that the ReplyTo
mentions a ServiceName
. So.. shouldn't this be there too in the To
? And why do we have a Address
and a To
in the header?
I just want to have the following information in my envelope:
- Service identifier ( urn:MyCoolContractFirstService )
- A logical endpoint reference ( urn:CoolServiceProcessor@receiverdomain.nl )
- A physical endpoint reference that routes my message ( msmq://soaprouter.senderdomain.nl/private$/soaprouterincoming or like tcp://localhost:12345/soaprouter)
To be continued....