Handling dependencies between applications

Jan 23, 2009 at 12:03 PM
I am fairly new to BizTalk 2006 and am just starting to utilize this fantastic framework that you have provided.  We currently have a "Common" Application contaning logging, email, error handling, etc. that all other Applications depend on.  This application rarely changes but when it does we need to uninstall all dependent applications in order to apply the new changes.  This has to happen even if the changes are internal to the common application such as adding new schemas that do not break the defined "Common Interfaces".  For deployments I have created a batch file using BTSTask which does the following:

1.  Extract all of the MSI's and Bindings of the Applications that are dependent on the Common Application
2.  Uninstall and Remove the Applications that are dependent on the Common Application
3.  Install the new Common Application
4.  Re-Install all of the Applications that are dependent on the Common Application using the MSI's and Bindings from Step 1.

Is there anything already built within the Deployment Framework that I can utilize that will handle Dependencies among Applications? If not, do you have any suggestions from previous experiences on how to handle the dependencies?

Thanks in advance!!
Coordinator
Jan 23, 2009 at 6:30 PM

Thanks for the positive feedback!  Since you are fairly new to BizTalk, you may not know that .NET components, orchestrations, maps/transforms and pipeline components assemblies (assuming that you are breaking things up that way) can be updated in-place without going through a whole undeploy/redeploy cycle -- as long as you don't modify the assembly version numbers.  They just need to be re-GAC'd and host instances restarted, which is how the Deployment Framework does its "quick" update.  Since you mentioned changing schemas, though, you are indeed stuck with the painful sequence of events that you described.

We do not have anything built in that specifically analyzes and handles the kind of BizTalk app dependencies that you described.  However, if you were using the Deployment Framework for all of those projects, you could call the Framework's Undeploy and Deploy targets from a batch file.  For a server deploy you also need to set the environment variables that the wizard GUI (SetEnvUI.exe) would normally handle -- those defined in InstallWizard.xml and UnInstallWizard.xml.

For example, using the BizTalkSample (note: I have not run this script, so it may have typos):

cd C:\Program Files\<project>\1.0\Deployment
REM Export settings from the spreadsheet
Framework\DeployTools\EnvironmentSettingsExporter.exe EnvironmentSettings\SettingsFileGenerator.xml EnvironmentSettings

REM Set Environment Variables that would normally be set in the wizard - defined in InstallWizard.xml and UnInstallWizard.xml
set VDIR_UserName=<username>
set VDIR_UserPass=<password>
set BTSACCOUNT=<biztalkusername>
set ENV_SETTINGS="EnvironmentSettings\PROD_settings.xml"
set BT_DEPLOY_MGMT_DB=<true for last server in the group on deploy and first server in the group on undeploy, otherwise false>

REM Call the Deployment Framework to undeploy and deploy
C:\Windows\Microsoft.NET\Framework\v2.0.50727\msbuild.exe <projectname>.btdfproj /t:Undeploy /p:Configuration=Server
C:\Windows\Microsoft.NET\Framework\v2.0.50727\msbuild.exe <projectname>.btdfproj /t:Deploy /p:Configuration=Server

Cross-app dependencies are definitely painful.  I also deal with the same problem that you described.  The best route is to use the GAC-and-restart method whenever possible (no schema changes) and script the entire sequence of events otherwise.  Remember to check for any suspended messages before you start the process, or you can always add a VBScript that kills everything that is suspended.

Thanks, and if you have any revelations around handling cross-app dependencies with the Deployment Framework, please do let me know!

Tom

Jan 23, 2009 at 7:47 PM
Tom,

Thanks for the quick response and suggestions!!  I will go ahead and try to incorporate your ideas into the deploy process.  I am hoping that I can also leverage information in the BizTalk Management database to determine the dependencies between the Applications so that I can dynamically figure out which Applications will need to be Undeployed/Redeployed.  I will post back if I come up with anything helpful.

Thanks again!!!



Coordinator
Jan 23, 2009 at 8:20 PM
The last time I had to deal with this issue - where we had a "Common" application - we did the re-gac trick as often as we could, as Tom suggests.

When that wasn't possible, we had our "customDeployTarget" for the Common application set up to undeploy the dependent applications.  This wasn't ideal, because then we had to inject knowledge of those applications in the deployment script for Common, but it was workable.  You can, of course, derive that information from the object model instead.

   <target name="customDeployTarget">

      <call target="TerminateAppsDependentOnCore"/>
.....
</target>


   <target name="TerminateAppsDependentOnCore">

      <if test="${property::exists('terminateInstances') and terminateInstances}" if="${deployBizTalkMgmtDB}">

         <!-- Core shouldn't have any service instances, but if it does, then
              core should be added here.
              Any application that depends on core should be added here. -->
         <property name="appsToTerminate" value="SomeApp1,SomeApp2,SomeApp3" />

         <foreach item="String" in="${appsToTerminate}" delim="," property="app">

            <echo message="Terminating running and suspended service instances for ${app}..."/>
            <terminateserviceinstances application="${app}"/>

            <echo message="Stopping and removing ${app}..."/>
            <controlbiztalkapp application="${app}" mode="StopAll" failonerror="false" verbose="true"/>
            <exec program="BTSTask.exe"
                  commandline="RemoveApp -ApplicationName:${app}"
                  verbose="true"
                  failonerror="false"/>

         </foreach>

      </if>
      
   </target>
Feb 11, 2009 at 8:14 PM
Currently we have 3 solutions - 1 is a common "core" and the other two are dependent on it.  As Tom and Scott mentioned above, we do the "regac" trick as often as possible. However, when we need to redeploy from scratch, we are able to use the deployment framework - as long as we follow the proper dependency order:

For Undeploy: dependent1 & 2 first, then undeploy core
For Deploy: core first, then deploy dependent 1 & 2

It works, but results in a longer system outage than we would like.  I am currently experimenting with side-by-side deployments that will make the process a little less "painful".
Sep 2, 2009 at 11:21 AM
scolestock wrote:
You can, of course, derive that information from the object model instead.

Hi Scott
I do not quite understand what you mean by the 'object model'. Could you please explain what it means or how I could access it in the BTDF?
Thanks and kind regards
Marcel
Coordinator
Sep 3, 2009 at 2:54 AM

What I meant in the above post was that if you are in a situation where you want the undeploy of an application to automatically undeploy dependent apps, you could write a task that would query the BizTalk operations object model to determine what those dependent applications were.

The alternative is baking in hard-coded knowledge of dependent apps, which is harder to maintain.