Alternative Bindings

Topics: Bindings File, Settings Management and SSO, Tips and Tricks
Sep 7, 2010 at 12:29 PM
Edited Sep 7, 2010 at 12:44 PM

On developer and TFS build machines, it is often necessary to isolate dependencies on external systems. For example, on my previous project, developers would not install the Dynamics AIF adapter. Instead we used the alternative bindings technique to mimic Dynamics AX using an alternative adapter (MSMQ).

How can I achieve this alternative bindings approach using the BTDF?

Requirements:

  • I do not want to store long xml strings of receive locations and send ports in the Environment Settings spread sheet. This would require the teams deploying to test and production servers to edit these long strings.
  • I want a way to flag a machine as a development machine and so use the alternative generated bindings.

I was thinking that using some feature of the xml pre-processor syntax in the Master Bindings file would help.  Does anyone have any advise on how to achieve this?

Coordinator
Sep 7, 2010 at 7:34 PM

Can you assume that the Local Development environment in the SettingsFileGenerator.xml Excel spreadsheet would always use the alternative bindings?  (Possibly also the Shared Development environment.)  You can add a new row in the settings spreadsheet called (for example) UseAlternativeBindings, and in each environment column you can enter the word True or False or just put some value in the True columns and leave the False columns blank.

I'd suggest taking a look through the documentation linked on the home page of XmlPreprocess (http://xmlpreprocess.codeplex.com/).  XmlPreprocess is the tool that pre-processes the XML files, and it has quite a bit of flexibility, most of which you can use in your PortBindingsMaster.xml.  See if you can find a pattern supported by the tool that will do what you want, and let me know what you find.  You'll be able to reference the UseAlternativeBindings variable in your PortBindingsMaster.xml to vary the pre-processing.

Thanks,
Tom

Sep 7, 2010 at 11:08 PM

Thanks for the quick response.  I have given this a try.  However, I am unable to get any of the #if expressions nor the Embedded C# Scripts Property Expressions working with the BTDF.  For example, the following simple expression does not work. 

<!-- #if defined("UseAlternativeBinding") -->
     <hello />
<!-- #endif -->
I get the following error:

EXEC : error XMLPP100: Metadata file 'XmlPreprocess.exe' could not be found

C:\Program Files\MSBuild\DeploymentFrameworkForBizTalk\5.0\BizTalkDeploymentFramework.targets(1044,5): error MSB3073: The command ""C:\Program Files\Deployment Framework for BizTalk\5.0\Framework\DeployTools\xmlpreprocess.exe"
/f /v /c /i:"C:\Workspaces\<mynamespace>\Deployment\PortBindingsMaster.xml" /o:"C:\Workspaces\<mynamespace>\Deployment\PortBindings.xml" /d:CurDir="C:\Workspaces\<mynamespace>\Source"
/s:"C:\Workspaces\<mynamespace>\Deployment\EnvironmentSettings\local_settings.xml"" exited with code 1.

I also tried wrapping the above in a <!-- #ifdef _xml_preprocess -->. This did not help.
Is there anything else I need to do? Has anyone got "#if expressions" and\or "Embeded C# scripts" working with the BTDF? If so, can you share some sample code? 
Coordinator
Sep 8, 2010 at 5:48 AM

The current version of XmlPreprocess, 2.0.13, will be included in the next BTDF release.  You might want to grab 2.0.13 and overwrite the version installed by the BTDF and see if that helps.  Also, I'd grab the command line listed in the output above and use it to run XmlPreprocess directly from Command Prompt to speed your testing, vs. through the BTDF tools.  You can see exactly which command line parameters the BTDF uses.  You might want to post on the XmlPreprocess Discussions area if you're still stuck.

The error that you're showing there is quite odd: Metadata file 'XmlPreprocess.exe' could not be found... which seems to be output BY XmlPreprocess.exe.  Does that happen even if you don't have any conditionals defined in PortBindingsMaster.xml?  Maybe you could verify normal XmlPreprocess operation by checking that the BasicMasterBindings BTDF sample app deploys properly.

Thanks,
Tom

Sep 8, 2010 at 12:32 PM

Many thanks for the advice.  I have now got it working using version 2.0.13 of the XmlPreprocess (I did re-try the following with version 2.0.11 and it did not work).

Here is some simplified code in my PortBindingsMaster.xml to prove the concept:

<!-- #if GetProperty("UseAlternativeBindings")=="True" -->
<AlternativeReceiveLocation>${MySetting1}</AlternativeReceiveLocation>
<!-- #endif -->
<!-- #if GetProperty("UseAlternativeBindings")=="False" -->
<StandardReceiveLocation>${MySetting2}</StandardReceiveLocation>
<!-- #endif -->

Note: I could not get this to work using #else syntax.  It would not substitute the ${MySetting2} tag.  Instead, I have used two #if statements. 

Apr 4, 2011 at 5:13 PM

Hi

When i tried this I had to set:

<RequireXmlPreprocessDirectives>True</RequireXmlPreprocessDirectives>

in the btdfproj file for the If statements to work.

This then resulted in the tokens not being set from the xml/excel file in the bindings before and after.

In order to get the settings to work i had to do the following:

<!-- #ifdef _xml_preprocess -->

<BindingInfo etc.

<!-- #endif -->

<!-- #if GetProperty("UseAlternativeBindings")=="True" -->
<AlternativeReceiveLocation>${MySetting1}</AlternativeReceiveLocation>
<!-- #endif -->
<!-- #if GetProperty("UseAlternativeBindings")=="False" -->
<StandardReceiveLocation>${MySetting2}</StandardReceiveLocation>
<!-- #endif -->

<!-- #ifdef _xml_preprocess -->

rest of file

<!-- #endif -->


Aug 24, 2011 at 10:04 AM

 Hi Tom,

Any chance supporting specifying an entirely different binding using the settingsmanager?

 

For my build process i would like to specify an entirely different binding file since i do not have minor adjustments (such as URI etc) but just want to use FILE instead of MSMQ etc. The approach above

means a lot of hassle in the portbindings file so i decided to look for other options, i ended up with choosing the 'change targets' approach since it is (clean? and) easy. I was wondering how this could be made

configurable using the settingsmanager. I don't mind to dive into the code, however i tried to look and had no idea how to overrule the target configuration...

 

Approaches:

1) Use BTDF to specify another file
Not supported

2) Use includes in Portbindings for additional ports
Possible, overly complex (leads to separate files)

3) Change IF DEF so that it removes/includes the entire block
Change the IFDEF XmlPreprocessor code, complex and timeconsuming

4) Change targets with alterend binding name
Change the TARGETS file to use a different binding file on the build server

 

Thanks and keep up the good work!


 

 

Coordinator
Aug 24, 2011 at 3:32 PM

Thanks for the positive comments!

1) This is supported.  PortBindings and PortBindingsMaster are both MSBuild properties that contain the bindings file name and the master bindings file name, respectively.  You could certainly override one or both of those properties (depending on whether you're using a master bindings file or not) in your .btdfproj (or pass in from the command-line during your build).  If you put them into the .btdfproj, you can put them into a PropertyGroup with a Condition attribute that would apply them in the correct situation (for example, '$(OnBuildServer)' == 'true' if you define OnBuildServer through the command-line during your build).

2 and 3) Be sure to take a close look over the XmlPreprocess documentation (see horizontal link bar), because you can use any of its functionality with your binding files.  It's pretty easy to make entire blocks of XML conditional on a property in your environment settings spreadsheet (i.e. #3 is supported today).  What you're describing wouldn't require any change to XmlPreprocess itself.

Hopefully that helps!
Tom

Aug 25, 2011 at 4:03 PM

Hi Tom,

Thanks for the in depth response, that really helped me out, i got it working the way i wanted! I was under the impression that being able to override the settings would be to good to be true....it is even better. Hereby my solution in case it helps somebody out;
 
MSBuild command line parameters (in MSBuild configuration):

/property:OnBuildServer=True

In my BTDF file i have the following configuration;

   <PropertyGroup Condition="'$(OnbuildServer)' == 'True' And '$(Configuration)' == 'Debug'">
    <OutputPath>C:\BizTalk\Releases\$([System.DateTime]::Now.ToString('yyyyMMdd'))\</OutputPath>
    <DeployPDBsToGac>false</DeployPDBsToGac>
    <PortBindingsMaster>BUILDSERVERPortBindingsMaster.xml</PortBindingsMaster>



I added a target in the .targets file so that i can run BizTalkDocumenter as well after deployment, my buildserver it becoming a it's starting to look like a real BuildServer

 

Note: In case you follow the MSBuild setup using the blog post ('Build Biztalk Deployment Framework Projects using TFS2010'), make sure you use the following to be able to maintain the MSBuild parameters:

String

 

.Format("/p:SkipInvalidConfigurations=true /t:Installer {0}"

, MSBuildArguments)

Coordinator
Aug 26, 2011 at 4:40 AM

Great news, thanks!

Tom