Yossi Dahan [BizTalk]

Google
 

Sunday, October 05, 2008

Wish list: Transforming unknown message

The other day I ended up developing a process that would take one of two message types (using XmlDocument as the underlying message type), something I don't usually advocate, but I agree of course that occasionally it is the right way to go.

Naturally the first thing I wanted to do is to convert the message from either format to a single message type.

I normally write my own xsl (as opposed to using the mapper) and so I knew that the template-based xsl scripts are geared towards this type of work through the use of apply templates matching logic;

In theory I should be able to create a map that takes a message of type XmlDocument and spit out a single format; the xsl script under the covers would use apply templates to match the possible root nodes and execute the correct template to map to the target format correctly.

This is only theoretical though as the compiler does not let you build a project with a btm file that has System.Xml.XmlDocument as the input type; a schema (type) must be selected.

Further more - the orchestration designer does not let you select a message as an input or output of it is not strongly typed (although that's just a designer issue, if you edit the ODX directly the compiler is happy enough, not that I suggest anyone do that)

This leaves the following alternatives -

You could write your own code to run xsl scripts, and call that from your process passing in the XmlDocument.

You could, of course, have multiple maps - each with a different input message type- all using the same xsl underneath the hood.

You could decide to hack a little bit and create your btm with any schema as the input type (selecting one of the alternatives for the input might be a good idea, or a specially created schema to indicate the scenario at hand); you could then use the transform function in an expression shape to run that map passing in the XmlDocument message as the input message;
You could do that because the transform function does not actually validate the input (or the output) against the schema at runtime, only the out-of-the-box transform shape does that, so as long as you avoid it you're ok.
Of course it has the implication of having a btm file that does not correctly represent the reality (in terms of input message), but I guess for some its easier to live with that than for others...

Labels: , ,

Tuesday, November 06, 2007

Subscriptions and multi-part messages

As we all know at the heart of BizTalk there's the publish subscribe mechanism that determines what process gets a copy of a message to work on (and where); we also know that most typically a message is assigned a message-type when it enters BizTalk, which is typically composed of the root node and xml namespace, and that most often it is the message type that drives those subscriptions.

It is also often said that BizTalk is a strongly typed system, although, I suspect, this refers mostly to the orchestration environment and less to the messaging environment as almost anything in an orchestration, as it is in programming languages such as the C# or VB.net, has a type (class) and an instance.

For example - when you want to declare a port - you are really first declaring a port type, and then a port of that type; when you create a correlation set you first define a correlation type, and then a correlation set of this type, etc.

Unfortunately, when it comes to messages, quite possibly the most fundamental item in an orchestration, the picture gets a little bit more confusing -

In an orchestration you can create a message out of four "things" -

  • A .net class - in which case the class is the type behind the message

  • A schema - in which case the xsd is the type behind the message

  • A multi-part message type - in which case you are required to declare the type first in the types section of the orchestration view pane.

  • A web part - in which case a multi-part message type has been created for you when you've added a web reference.


  • While all four options follow on the type-instance approach, which keeps the statement that an orchestration is a strongly typed environment correct, it can be somewhat confusing to understand to those beginning with BizTalk Server.

    However - what's furthermore confusing is that there seem to be a gap between what a message type means in the orchestration environment and what it means in the messaging environment, and there's a potential for confusion where the two meet -

    As discussed earlier, in the messaging world a message type is typically the root node and xml namespace when dealing with Xml, when dealing with .net types the same applies if you consider the xml that is a result of a serialisation of the class as what determines the message-type (and not the class itself) it is the serialisation attributes that will determine the namespace and root node used and as such the message type used.

    The question is - what is the story with multi-part messages in the messaging layer?

    Well - the basic answer is quite short - in the messaging layer - the namespace and root node of the body part of a multi-part message is used as the message type.

    This, however, can cause some problems with subscriptions and developers must be aware of this difference of approach between the two layers -

    Lets see if I can demonstrate this with an abstract scenario -

    I create a solution with two orchestrations - ProcA and ProcB
    I also add to my solution two schemas A.xsd and B.xsd

    In ProcA I take in a message of type A.xsd in an activating receive
    In ProcB I take in a message of type B.xsd in an activating receive.

    I've effectively created two subscriptions for these messages, pretty basic.

    Now, imagine I have a third process, ProcC, and that this process has a multi-part message with two parts - first part uses a different schema - C.xsd and second part uses A.xsd.
    Effectively, I've created a new type in my orchestration which has a name and is composed of C.xsd and A.xd (lets call the type C*)

    What would happen if ProcC published such a message to the message box? We'll get a routing failure as we don't have any process subscribing to that message.

    What I think can be confusing is what "that message" means in that context-

    While in the orchestration a multi-part message with two parts is a completely different message from any of the other ones defined in the process, in the messaging layer, it's the body part that counts, so that the reason my multi-part message had no subscribers is not down to the fact that there was no orchestration subscribing to C* (the multi-part message) but that there was no orchestration subscribing to a message of type C.xsd (the type of the first part in the multi-part message)

    And indeed - if I created a new multi-part message where the first (body) part was of type A.xsd and the second part was of schema C.xsd (call it A*) and published it to the message box, contrary to what one might expect (which would be another routing faliure, as there's no process subscribing to A*) ProcA will get triggered.

    Although in the orchestration world a message of type A.xsd and a multi-part message A* are two completely different types (even if one of the parts in A* is, indeed, defined using A.xsd) in the messaging world, it is only the type of the body part that counts so that the two are the same.

    Hope this makes sense

    Labels: , ,