venerdì, gennaio 07, 2011

BizTalk Versioning Strategy (1/4)

Like said in the previous post BizTalk solution management can be a challenging task due to the complexity of the biztalk artifacts update process.

BizTalk does its best to avoid the possibility to leave the system in inconsistent state and this is a good thing, but doing that it throws the burden of an incredibly bureaucratic deployment workflow on the developer even when it is clearly unnecessary.

Let’s make the following not-so-hypothetical case:

I’ve an orchestration (contained in an assembly ProcessA.orchestrations.dll) which uses a map (contained in ProcessA.maps.dll) which uses some schemas (contained in System1.schemas.dll and System2.schemas.dll).

As you can see, I’ve followed the best practices of separating different BizTalk artifacts in different assemblies and enhanced it a bit (further separating artifacts for processes and systems) to easily detect impact of our future modifications on the project.

Let’s say we need to implement another process between the same systems.

What we need to do is to add a new schema to the System1.schemas.dll to represent new messages exchanged in the second process.

Well, to update the System1.schemas.dll we need to:

  1. Since you’re updating a schema dll, you must remove it.
    1. Since schema is used on maps you need to remove maps that are using it (ProcessA.maps.dll).
      1. Since maps are used in orchestration you need to remove also orchestrations (ProcessA.orchestrations.dll)
        1. To remove an orchestration assembly you need to unenlist every orchestration contained in it.
          1. To unenlist every orchestration you must terminate every service instance existing referencing them.
          2. If orchestration is bound to a physical port you need to stop & unenlist every related port.
      2. If maps are used in a port you’ll need to manually remove maps from every port where it is used.
  2. Finally you can deploy the schema.
    1. But after you need to redeploy also maps you removed (ProcessA.maps.dll)
      1. But after you need to redeploy also orchestrations you removed (ProcessA.orchestrations.dll)
        1. You must remember to enlist again orchestration.
        2. You must remember to enlist/start receive/send ports
      2. You need to re set maps on receive/send ports that were removed.

A damned long sequence of steps especially considering that I was forced to completely redeploy ProcessA when I know that it's not necessary because the only modification I did to schema assembly was to add a new schema leaving untouched the old one… in other words my changes were backward compatible but by default biztalk assumes they’re not and this causes the problem.

A bit unfair.

I know, above I voluntarily omitted a couple of things that would have made life easier and I’m going to remediate here adding also the reasons why I don’t consider them a solution at all.

Using “Modify”

If you select a resource from the BizTalk Administration Console and press the right mouse key you’ll notice a “Modify…” voice in the popup menu.

image

This option bring us to a dialog window nearly identical to the “Add –> New BizTalk Assembly…”

image

But with a difference: if we decide to “Refresh” the assembly with a new one, BizTalk became smarter and will let us deploy the new one without removing the old one. Therefore, in the upper scenario, every list of step I reported could be avoided simply using Modify instead of the classical “Add –> New BizTalk Assembly –> Overwrite

Why BizTalk team decided to implement such a different behavior for these two nearly identical options (Add with overwrite and Modify) is a mystery to me but as long as i know that the difference is there it’s ok for me.

So problem solved?

No, definitely not and for two (IMHO good) reasons:

  1. Modify option has no command line equivalent, BTSTask.exe in fact has just the AddResource /Overwrite alternative, leaving us unable of using this feature for install/update scripts or automatic deploy msi.
  2. Modify works great if there are no inter-application dependencies but fails miserably (with the same problem of AddResource with Overwrite) if there is some application reference.

The second reason needs a better explanation: Let’s say for above project I defined different applications such as Common (containing all common components such as schemas, helper functions and so on) ProcessA (containing orchestrations, ports and maps pertaining to ProcessA) and so on.

Obviously ProcessA Application will reference Common Application and when we try to modify the schema.dll in Common (exactly as we did before when all processes where in the same application) we obtain a failure as depicted below.

image

Increasing Assembly Version.

Another solution could be simply to increase the assembly version of the modified schemas dll (let’s say from 1.0.0.0 to 1.0.0.1).

BizTalk allows side-by-side deployment of assemblies (more on this later) and so this could be the solution we were searching for:

ProcessA will continue to use 1.0.0.0 version of schemas while the new ProcessB will use the new 1.0.0.1 version (therefore containing the new schema)

This may seems to work but sooner or later (if you use orchestrations) you’ll face a similar exception

'Inner exception: Received unexpected message type MySchema, Schemas, Version=1.0.0.1,
Culture=neutral, PublicKeyToken=e1a7e3de4e628631' does not match expected type MySchema, Schemas,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=e1a7e3de4e628631'.

To understand why (and when) this exception will be raised and how we can solve the problem once for all we need to examine BizTalk resolution mechanism in depth.

Nessun commento: