Category: Deployment


As much as I am a fan of the Business Rules Engine (BRE) shipped with BizTalk Server there are times when I think it could use some more love from our friends at Microsoft, and never have I felt this more so than during a recent deployment exercise. I was aiming to deploy BRE Policies that made use of .NET based facts via BizTalk MSIs and I ran into the below problems which have made me somewhat rethink how I will carry out deployments of BRE Policies in the future.

  • You can’t import MSIs containing BRE Policies which make use of .NET classes into the BizTalk Runtime until those .NET assemblies have already been added to the GAC. This is fair enough, but once you’ve added the assemblies to the GAC you need to remember to close and reopen the BizTalk Administration console before you try to import the MSI or the MMC will not acknowledge that the assemblies are now in the GAC as seen in the below screenshot. This isn’t the biggest of deals, but it does push you towards installing your MSIs before importing them, which is the opposite of what I’ve seen most BizTalk administrators do.
Unable to locate assembly

Could not load file or assembly or one of its dependencies

  • The second problem which is much worse is that if the fully qualified namespace of the .NET classes that are used to make up your BRE Vocabularies are long enough then you will encounter the below error during installation of the MSI claiming that the fully qualified file name must be less that 260 characters. This is fair enough, however the problem is exacerbated by the fact that BizTalk creates a very complex folder structure when it writes the vocabularies to the file system during the MSI install process. I don’t think that breaking away from namespace standards at an organization to hack your MSI deployments as an acceptable solution so I needed to find another deployment pattern.

File path too long

I like that MSIs make our lives a lot easier during BizTalk deployments and I didn’t want to veer far away from this model when working out a solution. What I decided was that I was going to export my BRE Policies into a separate MSI, containing only the BRE policies and nothing else. I then added that MSI as a resource in my BizTalk application. Next up I created a .cmd file which calls on the BTSTask command during MSI installs (see my previous post regarding selectively executing pre/post processing scripts if you want to understand how this works) to deploy the BRE Policies MSI into the BizTalk Runtime, the contents of the file being as below.

If “%BTAD_InstallMode%” == “Install” If “%BTAD_ChangeRequestAction%” == “Update” (“C:\Program Files (x86)\Microsoft BizTalk Server 2010\BTSTask.exe” ImportApp /Package:”C:\Program Files (x86)\Generated by BizTalk\AppName\AppName BRE.msi” /ApplicationName:AppName /Overwrite)

I then added this .cmd file as a resource in BizTalk as well and the file type to Post Processing. An MSI can now be exported for the entire application excluding the BRE Policies which are contained within the BRE Policy only MSI.

The deployment flow is now as below.

  • The deployer installs the full-application MSI file first (if this is not a first time release then they might want to stop the application using the BizTalk Administration Console or through some other means, depending whether there are orchestrations involved or not / whether they are overwriting existing policy versions).
    • First the .NET assemblies are added to the GAC by the MSI install, including any within the contained application which the BRE Policy might be dependant on.
    • The post processing script will then deploy the BRE Policy only MSI to the BizTalk runtime, thus publishing the BRE Policies. Because we are not doing this via the BizTalk Administration console there is no need to close and reopen the MMC. Since the BRE Policies are not contained within the full-application MSI but only in the BRE policy MSI (which is only being imported, not installed), we will not run into the greater than 260 character issue.
  • The deployer then imports the full-application MSI through the BizTalk Administration console, restarts host instances, starts the application etc….

This isn’t the only way to work around these problems, but it does work. If anyone has any other ideas please do let me know.

I was recently asked to help out at a site which was having a problem with one of their production deployments.  Every time they tried to delete their application before importing the new version (which is standard practice at this site) they were getting an error message saying “The service action could not be performed because the service is not registered” as below (note that the error message is from my re-creation of the problem on my own machine).

ServiceNotRegistered

What immediately struck me about this error message was that the error says that “The Message Agent failed to register orchestration” and then lists an assembly name instead of an orchestration name.  Something is definitely majorly wrong in this environment.

The application was running without any problems at runtime prior to this release, but the client mentioned that they had attempted the same release a few weeks ago, had gotten to the stage where they deleted the application and were attempting to import the new version however hit a snag and decided to rollback the BizTalk databases.  Post the rollback they started the application back up and it performed fine since then until they attempted to do the deployment again at which point they started getting the service is not registered error message.

Once we gained an outage window and performed all the required backups, I stopped the application and started playing around a bit.  One of the first things I tried to do was to delete the individual assembly that was mentioned in the error message seen during the deployment and was quickly greeted by the same error message.  Attempting to move the orchestration or any of the send and receive ports (even if they made use of no maps, and only used out of the box pipelines, and weren’t bound to any orchestrations) also raised similar errors as did trying to import an MSI which overwrites the existing assemblies.  Attempting to delete a send or receive port (after unbinding it from any bound orchestrations) raised a different variant of the error message as below.

ServiceNotRegisteredDelete

Attempting to rename the application resulted in yet another error message, this time saying “The application action could not be performed because the application is not registered” as below.

ApplicationNotRegistered

It was fairly obvious at this stage that something was not properly registered in the BizTalk databases.  A quick look around the bts_assembly, bts_application, bts_orchestration, bts_receiveport, and bts_sendport tables in the BizTalkMgmtDb showed that the BizTalk assemblies, application, orchestration, receive and send ports were all known to the management database.

I discussed the rollback procedure that was followed a few weeks ago a bit further with the on-site technicians and it turned out that while all the databases were being backed up on a regular schedule, only the BizTalkMgmtDb and SSODB were actually restored.  Suspicions quickly started turning towards the BizTalkMsgBoxDb being out of sync with the BizTalkMgmtDb.  It made a lot of sense because the application in question had been deleted and then the BizTalkMgmtDb and SSODB had been rolled back, leaving the BizTalkMsgBoxDb with no knowledge of the deleted application.

It took a while to isolate the tables which were out of sync but we did finally get there.  The Modules table in the BizTalkMsgBoxDb table contains a column of all the application names and our application in question was missing from the list.  The Services table in the BizTalkMsgBoxDb contains a column called uidServiceID (which contains GUIDs) which corresponds to the uidGUID column on the bts_orchestration, bts_receiveport, and bts_sendport tables in the BizTalkMgmtDb.  Each row in the services table also holds a nModuleID which corresponds to the nModuleID on the Modules table also in the BizTalkMsgBoxDb.

Armed with this knowledge we had to decide on one of the below courses of action.

  • Attempt to rollback the BizTalkMsgBoxDb back to the same time at which the backups used to roll back the BizTalkMgmtDb and SSODB were made.
  • Attempt to rollback the BizTalkMsgboxDb, BizTalkMgmtDb, and SSODB to the same time at which the backups used to roll back the BizTalkMgmtDb and SSODB were made.
  • Manually fix up the database using SQL scripts.

A judgement call was made to go down the route of manually fixing the database, while acknowledging the risk that there might still be some other discrepancies which we hadn’t accounted for which would have to be reconciled later.

The first thing we did was to add the missing application back into the modules table with a SQL Insert statement similar to the below.

InsertIntoModules

A quick test now shows that we are able to rename the application MsgBoxSyncTest but we still can’t delete it.

Next up we had to collate a list of all the uidGUID values for all the relevant orchestrations, receive ports and send ports from the bts_orchestration, bts_receiveport, and bts_sendport tables respectively in the BizTalkMgmtDb.  We also made note of the nModuleID which was assigned to the record in the Modules table which we had just created.  We then ran a SQL Insert statement similar to the below to add those missing uidServiceID values into the Services table.

InsertIntoServices

After this was done we could once again delete individual artifacts, move them to different applications, or even delete the entire application itself.  Deleting the application at this stage was definitely desirable as recreating it from scratch should be a near guarantee that the BizTalk databases should be in sync after this (at least as far as this application is concerned).

While this problem was observed in a BizTalk Server 2006 environment, I have managed to successfully recreate it in a BizTalk Server 2010 environment as well.

When mentioning this to some of my colleagues I was provided with a few more suggestions.  One colleague suggested that we should restore a backup of the BizTalkMsgBoxDb to a different database name and then run a comparison tool against the two databases to search for any more discrepancies, which is a very good suggestion.  Another colleague suggested that the MsgBoxViewer tool might have been able to pinpoint and resolve the issue.  I did attempt to use the tool when I recreated the problem on my machine however did not find any results that really helped me solve the problem, however I would definitely recommend that the MsgBoxViewer tool is run against a BizTalk environment that has recovered from serious problems such as this to search for any more hidden issues.

While trying to search for solutions for this problem it did appear that there are an unfortunate bunch of people who have encountered similar issues before but I don’t see anyone who has posted a resolution, so I do hope that this helps others who encounter this problem.

What a surprise today finding out that Microsoft has decided to brand it’s next version of BizTalk Server as BizTalk Server 2013.  Even better, they’ve already thrown a beta version at the general public which is a whole lot more full-fledged in terms of new features compared to some earlier builds made available to a select audience.

While its early days and features are bound to evolve between now and the release date, I’m sure many are curious to find out quite how Microsoft has decided to implement some of the promised features.

In today’s blog post which is the first in a series focusing on the new features in BizTalk Server 2013, I will focus on the much awaited dependency modelling feature that has been added to the administration console.  Such a feature has been sorely lacking in previous versions of BizTalk, making it very difficult for operations staff to get an idea of how BizTalk artifacts relate to each other.  Freeware tools such as BizTalk Documenter have filled this role reasonably well but there hasn’t really been a live view on dependencies available without peeking into the source code.

There is now a new option in the “Action” pane in the Administration Console called “View Dependencies” which can also be seen if you right-click on a supported artifact type.  This option exposes the new functionality by filling in the dependency details in the “Dependency Statistics” section at the bottom of the console.  Neither the View Dependencies option nor the Dependency Statistics section of the screen will be seen when browsing to artifact types that don’t support dependency modelling.

Well, I’ve built and deployed my first BizTalk Server 2013 application with the goal towards getting an initial understanding of how dependency modelling has been implemented.  The application consists of the below :

  • Four schemas (two external schemas and two internal schemas)
  • Three maps
    • From the first external schema to the first internal schema
    • From the first internal schema to the second internal schema
    • From the second internal schema to the second external schema
  • Two orchestrations – each of these orchestrations receive a message of internal schema one, map it to internal schema two, exercise a very simple BRE (Business Rules Engine) policy, and send the message out
    • The first orchestration contains logical ports with a specify later binding, bound to the receive and send ports mentioned below
    • The second orchestration contains logical ports with direct binding, not making use of any filter expressions.  Just for funsies this orchestration exercises the XMLTransmit pipeline on the outbound message before it is sent out
  • The aforementioned BRE policy
  • A one-way receive port which is bound to the first orchestration and a corresponding file receive location.  The receive port uses the XMLReceive pipeline and exercises the map that transforms the first external schema to the first internal schema
  • A one-way file send port which is bound to the first orchestration and also contains a filter so that it subscribes to messages with a message type of the second internal schema

I kept my schemas, maps, and orchestrations in separate BizTalk projects so I could see if there was any cross assembly dependency tracking.  I was a bit disappointed to find out that there is no visibility of cross assembly dependencies, at least not at this stage.

Let’s start with receive ports.  If we right-click on the receive port that I created and choose view dependencies then we see the below.

So interestingly we now see that this receive port has listings in the Used by (other artifacts are dependent on) section as well as the Using section.  Clicking on any of these numbers will give you a handy consolidated list of all the artifacts of that type which depend on or are dependents for this receive port.  Only the specify later bound orchestration is listed as dependant on this receive port whereas the one that uses direct binding is not listed.  This makes good sense because the direct bound orchestration has a loose subscription based purely on message context whereas the specify later binding orchestration is bound to the receive port.  The inbound map that is exercised by this receive port is listed in the using section since the receive port is dependant on it.  The receive location is also listed here.  I think that being able to see a list of all the receive locations for a given receive port will be well received by BizTalk Operators.

Next up lets inspect the dependencies for the receive location.  As one might have guessed, the receive location is used by it’s parent receive port.  The pipeline that it makes use of is listed as an artifact that the receive location is dependent on which is quite handy.

If we try to inspect the dependencies for the XMLReceive pipeline we see that the receive location that makes use of it is listed as dependent on the pipeline.  This provides some really fantastic information for those planning deployments which involve new versions of pipelines.

I was disappointed to find that when I tried to view dependencies on the XMLTransmit pipeline there was no information listed even though it was used by our second orchestration.  It looks like dependencies between pipelines and orchestrations aren’t quite catered for.

Next up let’s take a look at the dependencies for the map that is used on our receive port which transforms the first external message to the first internal message.  As seen below the schemas which make up the map are listed as dependents, and the receive port that makes use of this map is listed in the used by section.

On inspection of the map that transforms the first internal message to the second internal message and is used in the two orchestrations I found once more that the dependency between the maps and the orchestrations were not listed.

Viewing the dependencies on the second internal schema showed that it is used by two maps, the link to the orchestration is once more ignored.

On to the orchestrations.  Viewing dependencies on the specify later bound orchestration shows a dependency on the receive and send port that the orchestration is bound to but no mention of schemas and maps.

Viewing dependencies on the direct bound orchestration displays an empty Dependency Statistics screen, even ignoring the XMLTransmit pipeline that was exercised in this orchestration.

It became quickly apparent that there is no support for dependency modelling on the BRE policy, which once more is a bit disappointing but of course these are early days.

And finally viewing the send port shows that the orchestration with specify later binding is dependent on this send port, and that this send port is dependant on the map and pipeline which it exercises.

So while I have used the word disappointing quite a few times in this blog post, I am actually fairly happy with this implementation.  It is a big leap forward compared to what was previously available and one can only hope that Microsoft chooses to flesh out this feature even more.  It should make planning for deployments and everyday administration a whole lot easier and reduce the amount of detective work that is required to prepare for deployments.

If I’ve made a mistake or if I’ve left out a type of artifact that you are interested in and want me to explore further do let me know and I’ll update this post.

Nothing quite beats a totally scripted BizTalk installation.  It might not be a one click install (unless you’re using advanced tools such as the BizTalk Deployment framework) seeing as there are quite a few screens to get through in the BizTalk msi import/install wizards, but you sure can make it a brainless task.

Some common tasks you might want to script are creation of hosts/host instances, addings send/receive handlers, configuring IIS etc….  You have a few options here such as using the WMI framework to carry out these commands in either a VBScript or a Batch file.  You can then add this script file as a BizTalk resource and set it’s file type to either be a pre or post processing script.  Think of a pre-processing script as a script that runs prior to your BizTalk install and a post-processing script as one that runs after your BizTalk install.

What you will notice is that the scripts execute when you import your MSI (whether it’s the first install or whether you’re overwriting an existing application), when you install the MSI, during a rollback of an import or install, and even when you uninstall the application.  It is possible for you to restrict your script to only execute code selectively based on the current execution stage of the install, or to even implement different behavior based on the execution stage.

Microsoft allows you to query the execution stage (what they refer to as deployment state) from within your script through the use of environment variables (see http://msdn.microsoft.com/en-us/library/aa546763(v=bts.20).aspx).  The values of the BTAD_ChangeRequestAction, and the BTAD_InstallMode environment variables can be used to uniquely identify the execution stage (the linked article also mentions the BTAD_HostClass environment variable but you really only need the first two to uniquely identify the execution stage).

The below screenshot is an example query within a VBScript script that is used to ensure that the code contained in the If…Then statement will only execute if the MSI is currently being installed, the code will not be executed for imports/rollbacks/uninstalls.

The below screenshot is an example query within a Batch file that is used to go to the Create block in the script if the MSI is currently being imported without an overwrite flag.

%d bloggers like this: