In all BizTalk projects you come across the old problem of configuration and how to manage the environmental settings when taking your solution from development to other environments. The common scenario is, I work with my binding file and get my solution build and tested etc and then I take it to the testing environments or production and I need to have a new binding file or I need to manually change the settings for ports etc. Obviously any manual steps are usually error prone so this never fully works.
On our project it is not just the binding files we need to configure between environments. The following table summarises the files that need to be configured:
|BTSNTSVC.exe.config || |
This file contains a few simple settings which are not
held within SSO. These need to be configured by environment
|PolicyCache file used by BTSNTSVC.exe || |
The policy cache contains endpoints and SPN values which are different by environment.
These are configured
Web.config in any web services that
|Again there may be some values that need to be configured by environment|
PolicyCache for any published web
|The SPN will be different by environment so this typically needs to be configured|
|Binding Files || |
We configure the binding files so that any settings which change by environment are configured. These settings usually include:
- Hosts for the ports
- Adapter specific information
In solving this problem i wanted to address the following requirements:
- Needs to be available as an MsBuild task to integrate into the build process
- Xml will be used to hold the configuration data. This would make it easy to maintain and I could extend it by creating a tool to manage the configuration source if I wanted.
- Needs to be able to produce files for multiple environments based on a template file
- Needs to be able to deal with different file types such as those listed above
So the problem is defined above and I will explain how our solution works, and a small sample is available which demonstrates its use.
The solution I developed is not BizTalk specific it can be used to configure any file. The process that we use is as follows:
- Maintain an xml file which is the source of the configuration data. We refer to this file as the configuration dictionary. This file defines the tags that are to be looked for, and also the real value for each environment.
- For each file that is to be configured we would have a template copy of it which would contain tags where the real values are to be replaced.
- In our build script we would call the MsBuild task passing in the input file and dictionary file. We would indicate which is the desired environment and where to place the output file.
The following sections will explain how we manage each of the types of file.
BizTalk Binding Files
The bindings file is the most awkward to manage typically because it is the most complicated xml. In the solution I keep a template copy which is used in the build script. When the bindings need to be changed I do them manually in BizTalk and then export the bindings to an xml file. I then need to manually merge the changes into the template (this can be awkward) and replace the values that need to be configured with tags which correlate to the dictionary.
Whe the build script runs I configure the template for every environment I am working with and then copy them to a special folder. This includes the binding file for the development environment.
Later in the build script I use the development binding file which I created to import it to my BizTalk Application and setup my ports etc before I run my unit tests.
When I deploy on another environment I can include the various binding files with the msi when it is produced, or I can import them manually.
BTSNTSVC.exe.config & The Policy Cache
As mentioned above these files also need to be configured for our overall solution. We manage these files as a solution on their own. This solution is setup as a project in Cruise Control. Each time a build is produced configured versions of these files are produced for each environment.
The build process for each individual application basically copies the right files to the development machine and uses them for the individual application build.
When we are deploying to a given environment we can just grab the appropriate files from our Cruise Control server.
Published Web Services (web.config & policyCache.config)
Because we do a lot of web service publishing we need to configure the policy cache and web.config as certain details in there files can change by environment. We take a similar approach to the binding files where we keep templates for each as part of the solution. We then create all of the configured versions for each environment.
When we want to run tests we copy the development versions of web.config and policyCache to the right place and then run the tests.
When we come to deploy to other environments we deploy the web services via the msi, but then we simply copy the appropriate environments versions of these files to the right location.
Because we use Continuous Integration and the build process to create all of the files it allows us to produce versioned instances or all of the files that need to be configured as part of the output package from each build
As mentioned above I have setup a small example which goes over the core details of the solution, and I will discuss these in this section
There are 2 solutions in the sample:
- MsBuild.ConfigurationTask = The msbuild task and some tests for it
- MsBuild.ConfigurationTask.Example = A sample solution demonstrating its use in the build script
Im not really going to go into the detail of the MsBuild task as the sample contains a test which should demonstrate its use. Im going to focus on the example on how to implement it in your build. If you have any questions about the task however feel free to drop me an email.
In the example solution I have the sample input file which contains the following xml.
<?xml version="1.0" encoding="utf-8"?>
The input file will have the $(BindingFilesSettings-Parameter1) tag replaced with a value from the dictionary.
The key points about the dictionary file are as follows:
- It contains sections to group together similar config tags. This makes the file easier to manage
- Each tag contains a default value which is used when you choose an environment which does not have a specific setting
In the build script you will find the following task:
DictionaryFile = "Acme.ConfigurationDictionary.xml"
Environment = "SystemTest"
InputFile = "Acme.SampleBindingFile.xml"
OutputFile = "ConfiguredOutput\Acme.SystemTestBindings.xml"/>
This will call my custom task passing in the input and output files as required and will ensure a file is produced which is configured for the system test environment.
Hopefully you will find this solution can help you on your project, if so then feel free to download the sample from below and use or amend it as you wish. This solution has worked very well for us. If you have any feedback or questions please feel free to comment below