I’ve spent the last few days working on a proof of concept for a generic (web-service) message bus application based on BizTalk 2006. The message bus is an orchestration exposed as a web service and accepts any message, consumes a remote web service and sends the results back to the calling web-service.
The Big Idea
As messages enter the message bus, they are updated with routing information identifying their sender and written to the Message Box. Following the traditional pub/sub architecture, it is then up to subscribing Send Ports to grab the messages they want, map them into the relevant format and consume the designated web service; the response is written to the Message Box and is correlated to the message bus orchestration for final delivery to the originating caller.
The problem came when trying to map the outbound message on the Send Port, as each web service we want to consume is likely to have a different signature. The port subscribed to the routing information as expected, the map worked as expected (when testing in Visual Studio), but when run on the port nothing happened.
My first thought was that because the port was subscribing to untyped messages, it just wouldn’t work (it was expecting a typed message that corresponded to the source schema of the map – duh). After a little more thinking, head-banging and reading this post on Google Groups, it all became it little clearer:
Understanding What its Doing Under the Hood
From what I can gather* maps on send ports don’t do anything particularly clever – they simply look at the MessageType in the context property and check whether the source schema matches (i.e. namespace#root-node-name). Maps work on Send Ports with typed messages because the MessageType property is promoted into the message context by the XLANG/S engine which ‘knows’ the type of the message (you’ve told it which schema the message corresponds to in the orchestration designer). With untyped messages, the XLANG/S engine doesn’t know the type (well, it knows its of type System.Xml.XmlDocument but that doesn’t really help) and therefore can’t promote the MessageType property into the context. As a result, the map doesn’t work because it doesn’t know what the message is (and doesn’t report an error either – helpful).
The fix is really simply – promote the MessageType into the context of the untyped message using a correlation set (as described here) and – hey-presto – everything works! Swindon, we have maps….
* Please feel free to shoot me down on this one…