Buddhike's Weblog

SOAP Routing – What has it gotta do with “To” header ???

During the past few days I came across some SOAP routing intermediary implementations (of course running on WCF ;)) and each of them were trying to route the WCF messages by changing the “To” WS-Addressing header in the message. In some cases this even required completely reconstructing the message by reading its body contents. This actually made me think about the basics once again. What actually happens in the real routers? For example, does Windows TDI driver for TCP/IP change the destination IP to your router’s IP after looking at the routing table? No! Instead, the transport transmits the traffic to the appropriate IP as specified in the routing table. Then the router reads the destination IP in the incoming TCP segments and forwards the traffic to the next network hop according to the routing table in the router itself. So essentially, the router is a device that simply forwards messages without tweaking them. Likewise this should be the theory behind the SOAP routers as well (of course SOAP works at a much higher level and you can divert this approach to meet your custom needs. But I’m talking about the routing in general).

So how exactly you can do this in WCF? The answer is hidden in an attribute that you might not pay too much attention in your everyday WCF adventures ;). When you configure an endpoint you can actually, specify the service address as well as the actual listening address as follows.

[ServiceEndpoint]

<endpoint address="http://localhost:8000/service/dummyendpoint.svc"
  listenUri="http://localhost:8000/service/actualendpoint.svc"
  contract="…"
  binding="…"
  bindingConfiguration="…" />

When you start your service the underlying transport actually uses the address specified in the listenUri to listen to the incoming traffic (if this is not specified, it uses the endpoint address by default). The service address on the other hand is the one which goes in the WS-Addressing “TO” header. This address is validated by service model layer to make sure that the messages that arrive at the endpoint are truly intended for this service (otherwise you’ll get the address filter mismatch error… remember that? ;)). So with these two attributes in our hands we can successfully model the aforementioned routing in the SOAP level as well. You can do it by having your router service actually listening on the endpoint address specified in the service (see below).

[Router endpoint]

<endpoint address="http://localhost:8000/service/dummyendpoint.svc"
  contract="…"
  binding="…"
  bindingConfiguration="…" />

Then you can simply forward the messages to the actual service endpoints according your routing rules. For example, you can determine a message to the above service endpoint by looking at the action header of the incoming message and forward it to the service by making a channel to http://localhost:8000/service/actualendpoint.svc endpoint (which is the actual endpoint of our service). Also note that this way, no matter how many intermediaries the message passes through the WS-Addressing “TO” header remains consistent.

When I started writing this post I intended to provide a very rough sample that I created couple of months ago (in fact I gave up re-inventing the wheel after seeing Shy Cohen’s wonderful lossy router ;)). But then I realized that the SDK routing sample perfectly demonstrates this. So take a look at it to get a better picture on it.

Have fun!

Posted: May 25 2007, 12:30 AM by Buddhike | with no comments
Filed under:

Comments

No Comments