My current project will go live this weekend with the first phase and we're looking to go live with a next phase within days/weeks after that.
But our solution relies heavily on long-running transactions (long being about a month), with thousands of concurrent transactions. So, we can't just undeploy an existing version and deploy a new one.
The good news is: BizTalk has build-in support for versioning which relies heavily on .NET assembly versioning (which is good).
The bad news is: The documentation about it is vage and incomplete. Things didn't work like I first understood from the documentation. Later I found out that the documentation might be right, but isn't very clear about action to take.
So I went off to see how versioning really works. I started easy. I tested two scenario's on a simple solution.
The solution I used for testing
My solution consists of two project. One with 2 schemas and a map and one with 1 orchestration that receives a message, maps it and send it out. I deployed both assemblies with version number 1.0.0.0 and then increased the version number of the schema assembly to 1.1.0.0 and started changing it.
Scenario 1
The idea: I fixed some bugs in my maps, the assemblies interface is exactly identical and I just want to replace the existing version without any impact.
I decided that the easiest way to do this is to NOT deploy the assembly to BizTalk. Instead, just deploy it to the GAC using gacutil and let .NET's versioning make sure the right assembly is used. The way to do this in .NET, is to add assemblybinding information to the application configuration file. For BizTalk this is the BTSNTSvc.exe.config file which can be found in the root of the BizTalk installation folder. You can create the binding directly in that file or create a seperate configuration file and reference it from BTSNTSvc.exe.config. This does require you to create a seperate appdomain for your assemblies, which might not always be what you want.
I added the following info to BTSNTSvc.exe.config, just below the opening configuration tag.
<configSections>
<section name="xlangs" type="Microsoft.XLANGs.BizTalk.CrossProcess.XmlSerializationConfigurationSectionHandler, Microsoft.XLANGs.BizTalk.CrossProcess" />
</configSections>
<xlangs>
<Configuration>
<AppDomains AssembliesPerDomain="10">
<AppDomainSpecs>
<AppDomainSpec Name="MyAppDomain" SecondsIdleBeforeShutdown="-1" SecondsEmptyBeforeShutdown="12000">
<BaseSetup>
<ConfigurationFile>c:\myAppBase\myConfig.config</ConfigurationFile>
</BaseSetup>
</AppDomainSpec>
</AppDomainSpecs>
<PatternAssignmentRules>
<PatternAssignmentRule AssemblyNamePattern="myAssembly*" AppDomainName="MyAppDomain" />
</PatternAssignmentRules>
</AppDomains>
</Configuration>
</xlangs>
My configuration file contained the following
<?
xml version="1.0" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly>
<assemblyIdentity name="myAssembly" publicKeyToken="32ab4ba45e0a69a1" culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="1.1.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
NOTE: Above code is not tested, so it might contain some issues, just tell me and I will update it
After restarting BiztalkServerApplication the new version was used perfectly.
Scenario 2
The idea: I extended the assembly with new schemas and maps, which will be used by new assembly. My existing orchestration assembly remains unchanged.
Now I am required to deploy the assembly to BizTalk. The issue that arises after you deploy the assembly is the existance of two definitions of all the existing schemas and maps. This will especially cause errors when receive and sending messages using the default pipelines. The solution to this issue is pretty simple. You have to tell BizTalk which version of the schema you want to use.
I extended my version 1.1.0.0 with two pipelines, one for sending and one for receive my messages. I added the XML (dis)assembler to the (dis)assembler stage and added the schemas to the document definition. Since the pipelines reside in the same assembly as the schema, it will always reference the latest version. I used these pipelines in the send and receive port and it worked perfectly.
If you need to reference the version 1.0.0.0 of schemas in your pipeline (which might be needed if you change schema definitions along the way), you have to put the pipeline in a seperate assembly that is build against the version 1.0.0.0 of the assembly. Here's where it started to become complex and I haven't gone through this root (yet ;-)
I guess I justed scratched the surface and didn't cover all the things that can go wrong in scenario 2, but this looks pretty promising.
I would recommend though that if you expect versioning of your assembly that you quickly start using your own pipelines. This eases the stuff.
My next question is how to version orchestrations. The documentation mentions two scenario that might apply to my situation, side-by-side execution and major application upgrade. So, to be continued I guess.