January 23, 2012 at 4:42 PM

Recently a customer of ours asked us if it was possible to include versioning information into the title of the installed MSI.

These MSI files can be generated by right-clicking a BizTalk application and selecting "Export" and then "MSI file":

This generates the MSI file on disk.

Problem however is that the MSI file which gets generated always has version 1.0.0.0 assigned to it.
We can always use Microsoft's Orca tool to manually update the properties of the file, but this is very cumbersome to say the least.

I went on to search if there was an option to pass some parameters to BTSTask.exe.
This tool allows you to perform the "Export MSI" via the command line, allowing you to script it.
Unfortunately this tool does not allow you to set the version information at all. 

Luckily, BizTalk comes with a .NET API that allows you to update the properties of the MSI installer package.
For BizTalk 2010 this is the Microsoft.BizTalk.MSIManager assembly.

using Microsoft.BizTalk.ApplicationDeployment.MSIManager.WindowsInstaller;

This assembly allows you to query/update the MSI database structure contained within the MSI file.

Just provide the following code to update the name of the application for example:
msiPath = full path to your MSI
applicationName = your custom application name that will appear in your "Programs and Features" list under Windows.

static public void UpdateMSIApplicationName(string msiPath, string applicationName)
        {
            Database db = Installer.OpenDatabase(msiPath, DatabaseOpenMode.Transact);
            string query = @"UPDATE Property SET Property.Value = '" + applicationName + "' WHERE Property.Property = 'ProductName'";
            Microsoft.BizTalk.ApplicationDeployment.MSIManager.WindowsInstaller.View vw = db.OpenView(query);

            vw.Execute();
            vw.Close();

            db.Commit();
            db.Close();
            db.Dispose();
        }

You can also update your Manufacturer information to customize the directory where the MSI gets installed. By default this is "Generated by Biztalk".
Use this query to perform the update then:

string query = @"UPDATE Property SET Property.Value = '" + manufacturer + "' WHERE Property.Property = 'Manufacturer'";

I also tried updating the version information, but for some reason this will insert some minor errors during installation having to do with the registry.
I believe this has to do with the registry keys that are installed by default within the BizTalk MSI version. 

Incorporating all of this into a properly automated build/deployment scenario will allow you to publish your MSI files with customized versioning.

Good luck.

 

Posted in: BizTalk | Deployment

Tags:


January 13, 2012 at 11:24 AM

This blog post contains some guidelines for consuming web services, with a focus on exception handling.  We will both handle pure messaging scenario and web service calls from within an orchestration.  I also make a distinguishment between asynchronous and synchronous flows.  Synchronous means that the flow needs to return a message to the original caller.  So in case of troubles, a SoapFault needs to be returned to the calling application.  In an asynchronous flow, you just need to make sure that your web service call is resumable. 

 

Messaging Scenario – Asynchronous

When an error occurs during the web service call, the default behavior of BizTalk retry 3 times and will suspend the request message on the BizTalk Send Port and this instance will be resumable.  This is the perfect behavior for this asynchronous process.

 

Messaging Scenario - Synchronous

If you are in a synchronous process, a suspended Send Port will lead to a timeout on your Receive Port.  In this scenario you need to enable "Propagate Fault Message" on the Send Port and a SoapFault will be returned to the original caller.  Also think about the Retry Count and Retry Interval settings, because a bad configuration can also lead to timeouts.

image

 

Orchestration - Asynchronous

When you consume a web service from within an orchestration, it's getting more complex.  If the consumed web service throws an exception, BizTalk creates by default 2 suspended service instances.  Resuming them does not always have the expected behavior.

 

-  The Orchestration is suspended.  A resume will not change anything to the state of the Orchestration.
-  The Send Port is suspended.  A resume will resume the web service call as expected, but the Orchestration will not be able to continue processing afterwards.

 

image

How can we now achieve a resumable web service call?

 

First of all enable "Propagate Fault Message" on the Send Port.


Also modify the calling orchestration:

-  You need to create a loop.  This loop continues as long as the Boolean bSuccess equals false.

-  Modify the logical Orchestration Send Port and add a Fault Message.  To keep it general, you can choose the SoapFault (which is part of the Microsoft.BizTalk.GlobalPropertySchemas).

clip_image002        clip_image003

-  Add an exception handler to the web service call. Catch the Fault Message that was returned.  Add a suspend shape for human intervention. Note that it’s a good practice to also add an extra exception handler which catches a System.Exception.

-  If the web service call fails: set bSuccess == false in the exception handler.  If the call succeeds, set bSuccess == true, so the orchestration will exit the loop.

 

The result should look like this:

image

 

Now we've created a resumable web service call from within an orchestration.  When testing the orchestration in a failure scenario, you will see that there are still two suspended service instances:

-  The Orchestration is suspended.  This is the one that we've made resumable.

-  The Send Port is suspended.  To avoid this second service instance to be suspended, you can enable "Routing for Failed Messages".  This will generate an ErrorReport, instead of suspending the Send Port.  Subscribe on the ErrorReport with the filter ErrorReport.ErrorType == “FailedMessage”.

 

clip_image006

 

Orchestration - Synchronous

In this scenario, you will also need to catch the SoapFault (or other exception) and make sure that you don’t end up with suspended send port instances. See “Orchestration – Asynchronous”


The extra functionality that you’ll need to add is returning a SoapFault to the original caller.

- Add a Fault Message to the Request/Response receive port of your orchestration.

- You can choose to return a typed Fault or, to keep it general, a SoapFault (which is part of the Microsoft.BizTalk.GlobalPropertySchemas).

- Make sure you return the catched SoapFault (or the created SoapFault in case of other exception) in case of errors.

- Remark that you’ll need to add a decide shape to determine you’re in a success/failure scenario. Otherwise, the compiler will fail (complaining about unconstructed messages).

 

clip_image002[4]

 

Again, think about the Retry Count and Retry Interval settings on the send port.

 

Toon Vanhoutte

Posted in: BizTalk | SOA | WCF

Tags: , ,


January 6, 2012 at 12:25 PM

Recently, we've encountered some problems with SCOM 2007 R2 monitoring of a BizTalk 2010 environment. The SQL Agent Job "Backup BizTalk Server (BizTalkMgmtDb)" failed, but we didn’t receive any SCOM alert about that.  The first reflex was to look at the BizTalk Management Pack.

 

BizTalk Server Management Pack

The BizTalk Server Management Pack contains a rule, called “CRITICAL ERROR: A SQL Server agent job failed - Backup BizTalk Server”, which is responsible for alerting us in case of troubles.  The rule is disabled by default, but we had already enabled the rule with an override.

 

Why didn’t we receive an alert?  We had a closer look at the default rule and discovered that this is the way of identifying the backup job failure:

-    It’s a rule that subscribes on the event log [TypeID="Windows!Microsoft.Windows.EventProvider"]
-    It looks for event log entries with ID = 208 [EventDisplayNumber equals 208] in the Application log
-    The computer name is set to $Target/Property[Type="Microsoft.BizTalk.Server.2010.ServerRole"]/ComputerName$

 

When the error occurred, we indeed discovered event log entries with ID 208 on the SQL server.  But this rule is subscribing on the event log of the BizTalk server.  Conclusion: the default rule will only work on a single box installation (SQL server and BizTalk server have the same event log).

 

To solve this issue, we’ve created a custom rule, based on the default one.  The custom rule had exactly the same configuration, except for the computer name that we’ve changed to:
-    “$Target/Property[Type="Microsoft.BizTalk.Server.2010.BizTalkGroup"]/MgmtDbServerName$”

Now the rule was subscribing on the event log of the SQL Server (running the ManagementDb), and we received an alert when the backup job failed.  This worked fine, until we deployed this rule against a multi-server BizTalk environment, containing a SQL Server cluster.  Suddenly we’ve received SCOM errors, complaining that the SCOM Agent couldn’t access the event log of the MgmtDbServer.  The cause of this is that the BizTalk Management Pack actually discovers the virtual SQL Server Cluster name.  As this is not a physical server name, it’s normal that the SCOM Agent can’t access the event log.

 

To overcome this issue, we could have created a new custom rule, which uses the discovered MgmtDbServer and performs a query on the [msdb].[dbo].[sysjobhistory] system table.  The sysjob tables contain all needed information to detect SQL Agent Job failures.  As this is too complex, we decided to have a look at the SQL Server Management Pack.

 

SQL Server Management Pack

As it is actually a SQL process that fails, the SQL Server Management Pack should be responsible for alerting us.  But why didn’t that happen?  There are actually two reasons for this:

-    The discovery of SQL Agent Jobs is disabled by default.
-    The alerting for SQL Agent Job Failures is disabled by default.

We enabled the discovery and alerting, tested the solution and everything went smooth.

 

Conclusion

SQL Agent Jobs should be monitored by the SQL Server Management Pack.  This Management Pack should always be installed in a BizTalk environment, as SQL Server is the core of BizTalk.  Please, keep in mind that the alerting of SQL Agent Jobs is disabled by default.

 

It’s actually a strange approach of Microsoft to try to include the monitoring of the SQL Agent Jobs in the BizTalk Server Management Pack.  Certainly because the default implementation only works for a single box installation.  On MSDN you can find a vague description on this subject.

Toon Vanhoutte