Versioning and Re-Deploying BizTalk Server 2006 Applications

A couple posts ago I walked through the new packaging and deployment process in BizTalk Server 2006. In this post, I want to spend some time reviewing some real-life scenarios such as deploying new versions and only deploying certain new items.

One update from the last post. The Import process that is run on the MSI package only needs to be done once for the farm. While each machine must have the MSI bits installed, only one machine has to run the Import. That's because the Import process is what updates the central database(s) with configuration and assembly information. Thus, that doesn't need to be repeated on each machine.

The primary scenario that I'll walk through below focuses on updating a running BizTalk application with a new version, and what things to expect. So what I've done is first create a very simple orchestration + biz rule solution and deployed it. Works great. I then packaged it all up into a nice MSI file (using the steps in my previous post). As a side note, I also looked at my assembly in the Resources folder of the Admin Console, and changed the default destination location of the assembly which was the output directory of my .NET project. That's not really a real-life scenario.

After I packaged up the application, I undeployed the assembly from the application in the Admin Console. I went back to Visual Studio.NET and made changes to my orchestration so that I could easily see which version was firing. In this case, I have an Expression shape that writes a message to my Event Log. I then changed the assembly version in the project properties pane to mimic a real update scenario. After changing the version, I built and deployed this new assembly to my BizTalk Server. I then ran that application to make sure that the BizTalk components worked fine. After that, I again packaged up the application into an MSI and saved it out as version 2. Finally, I completed deleted the application thus removing any remnants of either version of my BizTalk process and started over with a clean machine.

Note: In my second MSI (version 2), when exporting the application to an MSI package, I chose to NOT include the Business Rules in the package. It's very easy to select which components you wish to include in the package via the wizard. Why did I exclude the rules? Because I didn't change them, and if I try to redeploy a ruleset on top of an existing (deployed) ruleset with the same version, your MSI will fail. Trust me, I tried! It's expected behavior and makes total sense, but just wanted to point that out.

My next step was to install and set up version 1 of the application. So, I ran the Import process from the Admin Console, chose which configuration to use, and on the last page, clicked the check box to actually kick off the MSI and install the bits on the machine. The application is stopped, so I went ahead and started it. Once that is done (and thus all bits like Business Rules are deployed), I dropped my files, BizTalk picked them and processed them through as expected using version 1 behavior.

Now what happens when I try to install version 2 on top of it without stopping the running application? Let's see. First, I Imported the new version 2 on top of my existing application. Walked through the wizard, no problems, and then chose to install the MSI bits (and thus new assembly version) onto the machine. Any expectation of what you'd see? Well, what you'll see is BOTH assemblies now in the Resources folder in the Admin Console, and, both versions of the orchestration listed in the Orchestrations folder, with the old one still running, and the new one unenlisted. If I dropped more files, the version 1 orchestration continues to process. I then enlisted and started the new version 2 orchestration to see what would occur. When I dropped two files, I actually got four messages as output! So both orchestrations processed the message. Again, it makes perfect sense since now I have two processes enlisted and thus subscribing on my inbound content. So, what will have to happen, is that we unenlist the old version 1 orchestration, and enlist the version 2 one. Odds are you would do that via script if you are doing a silent install with the MSI package. Let's run some tests to see what happens.

Test scenario 1: Only version 1 orchestration enlisted, suspend messages going through it (in a resumable fashion by undeploying the business rules), unenlist the version 1 orchestration (thus suspending any other in-process service instances) and enlist the new version 2 orchestration. So, we've got 2 suspended messages that were started with the version 1 orchestration, but now the version 2 orchestration is the one enlisted.

Result: I went back, redeployed the business rules (so, removing the orchestration blocker), and resumed the suspended instances. What happens? They finish with the version 1 orchestration even though it's not enlisted/started! Which again makes sense. The orchestration that starts the process with try and finish it using the still-available assembly. If I drop new files, they are processed by the newly enlisted version 2 orchestration. So moving forward, all new files use the new orchestration, but any in-process messages would try and resume with the original one.

Test scenario 2: Have only the version 1 orchestration enlisted, suspend messages, unenlist and try to undeploy the assembly containing the version 1 orchestration. Then enlist the version 2 orchestration to see if it'll try and pick up the messages started with version 1.

Result: When I tried to undeploy the version 1 assembly, I got the message below:

Makes sense. So you can't undeploy an assembly if there are instances still using it and relying on it to complete their process. Once all the orchestrations are done using it, you can safely undeploy it.

Ok, can't stop there. What happens if we drop 2 more files? Remember I still have the business rules undeployed and version 2 orchestration is the only one enlisted. Now I have 4 messages suspended. So you may be saying, "well sheesh, how can I find out when my freakin' assembly and orchestrations are doing being used so that I can kill it?" Fair question. The great new Hub view in the Admin Console lets me decide what data I want to see. So, I can create a simple query that shows me each service instance, and which assembly it uses! In the picture below, you can see that I have 4 messages suspended, 2 for each orchestration/assembly. If I go ahead and redeploy my business rule, and resume ALL instances, as expected, the first 2 complete with the original version 1 orchestration, and the second set of messages complete using the version 2 orchestration. All subsequent messages also use the version 2, and I can easily come back to my Query and make sure that my original assembly is no longer in use. Once that's the case, NOW I can go back and undeploy the assembly with no errors.

Well that was one freakin' large post. But, it covered what I think is an important topic: graceful redeployments of application versions. If you've got ideas on how to improve the process, feel free to leave a comment and share with us.