domenica, gennaio 09, 2011

BizTalk Versioning Strategy (2/4)

This is the second part in the versioning discussion, the first part here.

Messages and Objects: Two Sides of the same coin

BizTalk has a strange dualism when it came to message processing:

On one side BizTalk is a .NET application, and therefore a message is identified by its .NET Type, the assembly containing it and its Strong Name.

On the other side BizTalk is an XML Oriented processing middleware and therefore a message (if it’s an xml) is also identified by its XSD characteristics (what is called in BizTalk terminology its “MessageType” which is identified by root node name and namespace)

In the below example I double clicked to a deployed schema in the biztalk administration console, just to discover that the schema is identified by the following couple of properties:

MessageType: http:/MySchema1#Root

Type: BizTalk_Server_Project1.Schema1, BizTalk Server Project1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a76ffbe6c9882f67

image_thumb[2]

The same dualism can be read in a message instance inspected through the admin console: as you can notice from MessageType and SchemaStrongName context properties.

image_thumb[3]

Why is this distinction important?

This distinction is extremely important because help us to understand some strange biztalk behaviors and anticipate versioning problems:

If you try to deploy two different schemas but with the same root node name and namespace in two different assemblies BizTalk will blow up as soon as a message matching the schema will enter the messagebox with the following exception

Cannot locate document specification because multiple schemas matched the
message type "http:/MySchema1#Root"

(The nasty thing of this problem is that it obviously affects every message matching the schema, not only messages of the offending deploy, this means that one day a process works correctly, the day after someone decide to deploy another schema for another project without noticing the messagetype mismatch and booom even the process that was working correctly is not working anymore. This experience taught me to put schemas in assemblies separated for systems instead of processes: it reduce the possibility to put the same messagetype in different assembly because usually system name is also contained in message xml namespace)

Knowing the dualism depicted above the problem is now clear:

BizTalk receive an XML Message from the external, the first thing it does is to lookup in its database to find the .NET type related to that XML Message (using MessageType as key).

If it has two matches it is unable to decide which type to use for message deserialization and it throws the exception.

But, if you deploy the same messagetype in another version of the same assembly then no exception will be raised.

This is due to the fact that (as depicted here) biztalk engine has an exception to the no multiple match rule: If the multiple match came from different versions of the same assembly then the schema coming from the latest (highest version) is used.

Equipped with all these new knowledge let’s see how every biztalk artifacts will react to a schema update (i.e. old schema version = 1.0.0.0 while the new schema is deployed side by side with version = 1.0.0.1).

Pipelines

XmlDisassembler component is responsible to identify and promote the MessageType and SchemaStrongName of the message.

Therefore, applying what seen till now, the xmldisassembler will assign the MessageType without problems (after all it’s simply concatenating Root name and namespace) and will resolve SchemaStrongName to version 1.0.0.1.

If, for some reason, you want to override the “default to higher version” rule you can indicating explicitely the SchemaStrongName in the “Document schemas” property of the pipeline component

Maps

Maps are simply XLST transforms therefore they’re usually not at all interested in SchemaStrongNames or .NET Types but they only look at the MessageType.

Actually, when placing several maps on a port, a message is directed towards one or another map just examining its messagetype and nothing else.

But, at compile time, maps are compiled against biztalk schemas (source and destination schemas) and therefore, at the end of the transformation maps simply “append” the expected destination MessageType and SchemaStrongName to the outbound message.

In other words, If you’ve compiled your map against 1.0.0.0 version of your schema, the map will continue to work seamless if you send a 1.0.0.1 version of your message inside but it will produce a 1.0.0.0 version of the outcome.

Orchestrations

Orchestrations are different: they’re statically compiled block of code and therefore they’re not at all aware of XML Messages but they only understand .NET types.

Therefore, if you send to an orchestration (compiled against 1.0.0.0 version) messages with version 1.0.0.1, even if they’re identical (from an xml point of view) to 1.0.0.0 message orchestration will raise an exception (“Received unexpected message type” seen in the previous part).

Doing a quick recap therefore we can say that side by side schema deployment with its “default to higher version” rule is good when you’ve just maps and pipelines (so it’s perfect in a messaging-only scenario) but it will fail miserably if you’ve orchestrations in your solution.

In the next part we will try to find a solution to this problem.

1 commento:

Mitch Vanhelden ha detto...

Great post.
The explanation is very clear.