sexta-feira, janeiro 30, 2009

Automation of BizTalk Installation Package Build

BizTalk solutions include numerous interdependent components and managing those during build/un-deploy/deploy cycles can be very tedious and time consuming. Fortunately BizTalk 2006 greatly simplifies deployment tasks with the new Application concept and improved BTSTask tool which replaces BTSDeploy. You can further simplify life by scripting package building process. I'd like to demonstrate some features of BTSTask and show how it can be used for installation package build automation.

There are some assumptions in the example provided about how solution is structured and naming conventions. These are not anything new and based on best practices for .net solutions development as well as some common sense rules specific for BizTalk development. For instance, VS.NET projects are structured by BizTalk functions like: Schemas, Maps, Pipelines, Orchestrations, BRE Vocabularies and so on, and have common solution namespace: i.e. CompanyName.ApplicationName.Maps.

Typically, BizTalk package build would include following stages:

  • Build projects
  • Deploy assemblies to global assembly cache (may not be necessary if application is not intended to run on the build server)
  • Deploy artifacts to the BizTalk management database
  • Import application bindings
  • Export installation package (MSI)

Let's consider scripts. First, I have a master build script that calls all task specific scripts for the corresponding solution:

@REM ----------------------------------------------------------
@REM Master script. Builds solution and deploys all artifacts
@REM of BizTalk application and packages resources into the MSI.
@REM -----------------------------------------------------------

SET AppName=%1
SET BuildMode=%2


IF %BuildMode%==Debug (SET BtsBuildMode=Development) ELSE (SET BtsBuildMode=Deployment)

CALL %AppName%_set_build_environment.bat
CALL %AppName%_buid_projects.bat
CALL %AppName%_gac_assemblies.bat
CALL %AppName%_biztalk_deploy.bat
CALL %AppName%_start_orchestrations.bat

ECHO Exporting installation package...
btstask ExportApp /A:%AppName% /P:"%MsiFolder%/%AppName%.msi" /ResourceSpec:" :"%MsiFolder%/%AppName%.ResourceSpec.xml"



Note how it accepts command line argument defining which application to build. Every script is prefixed with the application name. This application name is assigned to the variable AppName and is used in other scripts. Entire process is broken down into task specific scripts so they can be run standalone (if I need to GAC only, for instance). The same reason is behind the fact that every script makes a call to the set_build_environment. Let's look at what's in this file:


@REM ------------------------------------------------------------

@REM Sets environment variables for building BizTalk application
@REM ------------------------------------------------------------



ECHO Setting build environment...

CALL "%VS80COMNTOOLS%vsvars32.bat"

SET AppDescription="My BizTalk Application"
SET SolutionNamespace=CompanyName.ProjectName
SET SolutionName=..\..\CompanyName.ProjectName.sln
SET AssemblyKeyFile=..\..\key.snk

SET MsiFolder=..\..\MSI

SET BindingFile="..\Bindings\%AppName%.BindingInfo.xml"
SET BindingFileDev="..\Bindings\%AppName%.BindingInfo.DEV.xml"
SET BindingFileTest="..\Bindings\%AppName%.BindingInfo.TEST.xml"
SET BindingFileProd="..\Bindings\%AppName%.BindingInfo.PROD.xml"

SET OrchestrationName="ProcessRequest"

SET SqlPortName=SaveRequest_SQL
SET ApprovalPortName=SendApprove_FILE
SET LogPortName=Log_FILE

SET WebPortName=WebPort_ReceivePort
SET WebPortReceiveLocationName=Services/ProcessRequest


ECHO Build environment has been set.



The script makes call to the vsvars32.bat and sets all required variables used in corresponding scripts.


Next step is to build Visual Studio projects and is pretty simple:


@REM ------------------------
@REM Builds solution projects
@REM ------------------------


CALL %AppName%_set_build_environment.bat

ECHO Building solution projects...

DevEnv /Build %BuildMode% /project %SolutionNamespace%.Common %SolutionName% /Out %AppName%_build.log

DevEnv /Build %BuildMode% /project %SolutionNamespace%.Schemas %SolutionName% /Out %AppName%_build.log


Next script installs compiled assemblies to the global assembly cache using GacUtil tool and I won't quote it here.


BizTalk application deployment step is probably the most interesting one as it shows how BTSTask can be used to add different kind of resources to the application.


@REM ------------------------------------------
@REM Deploys artifacts to the BizTalk database
@REM ------------------------------------------

CALL %AppName%_set_build_environment.bat

@ECHO Creating BizTalk application...

btstask AddApp /ApplicationName:%AppName% -Description:%AppDescription%

ECHO Deploying BizTalk assemblies to BizTalk database...

btstask AddResource /Type
:System.BizTalk:BizTalkAssembly /A:%AppName% /Source:..\..\%SolutionNamespace%.Schemas\bin\%BtsBuildMode%\%SolutionNamespace%.Schemas.dll /Overwrite /Op:GacOnInstall

ECHO Adding non-BizTalk assemblies...

btstask AddResource /Type
:System.BizTalk:Assembly /A:%AppName% /Source:..\..\%SolutionNamespace%.Common\bin\%BuildMode%\%SolutionNamespace%.Common.dll /Overwrite /Op:GacOnInstall

ECHO Importing default bindings...

btstask ImportBindings /Source:%BindingFile% /ApplicationName:%AppName%

ECHO Adding target environment specific bindings...

btstask AddResource /Type
:System.BizTalk:BizTalkBinding /A:%AppName% /Source:%BindingFileDev% /Property:TargetEnvironment=Development /Overwrite

ECHO Adding file resources...

btstask AddResource /A:%AppName% /Type
:System.BizTalk:File /Source:"..\..\%AppName%.config" /Destination:%%BTAD_InstallDir%%\%AppName%.config /Overwrite

ECHO Adding post-processing script file...

btstask AddResource /A:%AppName% /Type
:System.BizTalk:PostProcessingScript /Source:PostInstallScript.vbs
/Property:Args="HKLM\Software\CompanyName\%AppName%\ File_IO File_IO\In" /Overwrite


This script creates BizTalk application and then adds all kinds of resources to it. Notice use of BTAD_InstallDir variable when adding file resource (in my case it's app config file). Its value will be set by MSI install package when invoked and file will be copied into the application istallation directory provided at the install time. Also, look at how postprocessing script is added with option /Property. This option allows to pass arguments to the post/pre processing script when it runs and is not available from the BizTalk administration UI. In my case postprocessing script creates some registry entry, directory structure and will not be copied to the installation directory since /Destination option is omited.


The batch file that enables ports, enlists and starts orchestrations is needed only if you want to start the application on the build box. It calls generic WMI scripts that can be found in the BizTalk SDK.


The last important thing to call is ExportApp command of BTSTask (called from the master script) which creates MSI package and resource description file.



In Paul's Petrov Whiteboard