Tuesday, January 10, 2006

Biztalk Host Manager 2004


Since Isaac is publishing post after post I thought it is time for me to also post something.

I developed a useful tool, called the Biztalk Host Manager (BTSHostManager), which we use in our development team to be able to quickly stop, start and especially restart BTS host instances.

Because all our developers found it a helpful tool we thought we would make it available for download.

Some features:
- It monitors background service state change of host instances (not by default, use options to enable) .
- It works for Biztalk 2004 and 2006.

- A seperate Biztalk 2006 version (compiled against 2.0 framework) will be available soon.
- This is not the final release version. We are still testing it, so please mail me any bugs you find.

Thursday, January 05, 2006

Mapping complex conditions in BizTalk with XSLT

Recently I found myself in a situation where I needed to evaluate a set of complex conditions that I could not use the Business Rules Engine for. The BizTalk mapper was able to achieve the conditionality by chaining a series of about 21 functoids together but this became very unmanageable especially since I was combining false statements to see if both were false, then returning a true to an “And” functoid (&) which evaluated another branch as true and passed a result to the node in the destination schema, you get the idea.

An easier way is to plug in XSLT. There are disadvantages to doing this, the main one being its maintainability and transparency but when faced with the daunting set of functoids described above, it looked a decent option.

The XSLT function that I used was the <xsl:choose> statement, inside the statement was a set of conditions which, if true, would return a value/values to the destination schema. In the last part of the statement was the <xsl:otherwise> condition which could set values if the conditions presented were not valid and you had a default you wanted to present in that event.

<xsl:variable name="var:vAnnuity" select="count(/*[local-name()='InternalSupport' and namespace-uri()='http://internal_support']/*[local-name()='LoanPartItems' and namespace-uri()='' and Method='Annuity'])" />

<xsl:variable name="var:vLinear" select="count(/*[local-name()='InternalSupport' and namespace-uri()='http://internal_support']/*[local-name()='LoanPartItems' and namespace-uri()='' and Method='Linear'])" />

<xsl:variable name="var:vTotalCount" select="count(/*[local-name()='InternalSupport' and namespace-uri()='http://internal_support']/*[local-name()='PartItems' and namespace-uri()=''])" />

<xsl:variable name="var:vHasValidEndowment" select="count(/*[local-name()='InternalSupport' and namespace-uri()='http://internal_support']/*[local-name()='LoanPartItems' and namespace-uri()='' and isValid ='true'])" />

<xsl:variable name="var:vHasValidId" select="count(/*[local-name()='InternalSupport' and namespace-uri()='http://internal_support']/*[local-name()='Ready' and HasValidId ='true'])" />

<xsl:element name="LeningSoort">

    <xsl:choose>

        <xsl:when test="$var:vAnnuity = $var:vTotalCount">

            <xsl:value-of select="1" />

        </xsl:when>

        <xsl:when test="$var:vLinear = $var:vTotalCount">

            <xsl:value-of select="2" />

        </xsl:when>

        <xsl:when test="($var:vHasValidEndowment = $var:vTotalCount) and ($var:vHasValidId = $var:vTotalCount)">

            <xsl:value-of select="3" />

        </xsl:when>

        <xsl:otherwise>

            <xsl:value-of select="4" />

        </xsl:otherwise>

    </xsl:choose>

</xsl:element>




Of course each specific case requires different XSLT, but this should provide a framework of how to do this within a functoid.

To set up the XSLT:

• Create XSLT similar to the one above which meets your needs
• Drop a scripting functoid on your map
• Connect the output parameter to the node you want to create
• Note: do no include any input parameters, the XSLT is setup already to look them up
• Open the scripting functoid’s, click the (…) inside “Configure Functoid Script”
• Under “Script type” choose “Inline XSLT”
• Paste your XSLT snippet in the text box

Tuesday, January 03, 2006

Remove empty nodes in BizTalk by using XSLT

If you have ever had a map which begins to look unmanageable with tons of value mappings or extra functoids to simply manage empty nodes you don’t want in your output then you should consider using an XSLT mapping to clean the document up for you.

This involves actually making 2 mappings instead of one, but the upside is faster development with a nominal performance cost. Instead of adding functoids, testing and retesting the output, let the mapper generate the empty nodded and then add an extra mapping step with the following XSLT embedded in it:


<?xml version="1.0" ?>

<xsl:stylesheet xmlns:xsl="@@ YOUR NAMESPACE @@" version="1.0" xmlns:ns0="http://Stater.Isvcs.Iface.BO.GetLoanData.ElfV2">

    <xsl:output method="xml" indent="yes" />

    <xsl:template match="node()">

        <xsl:if test="count(descendant::text()[string-length(normalize-space(.))>0]|@*)">

            <xsl:copy>

                <xsl:apply-templates select="@*|node()" />

            </xsl:copy>

        </xsl:if>

    </xsl:template>

    <xsl:template match="@*">

        <xsl:copy />

    </xsl:template>

    <xsl:template match="text()">

        <xsl:value-of select="normalize-space(.)" />

    </xsl:template>

</xsl:stylesheet>




Save this snippet (or download it here) into your project (open the XSLT and change the namespace!) then create a new map. Make your source and destination schemas the same and in the map properties add your XSLT in the “Custom XSLT path” setting. Place the new map after the “dirty” map; the output should give you an XML document free of extra nodes and a map free of extra functoids.

Of course, if you are doing a strictly messaging based implementation then you are out of luck unless you chain ports together but within an orchestration using XSLT to remove empty nodes might work well for you.

Monday, January 02, 2006

Blogging about BizTalk? Then this is a
must have tool

I’ve found a tool recently that will make blogging about BizTalk easier. It’s been around for a while but if you are like me and have never heard of it before, CopySourceAsHtml is very useful.

If you have been in the situation of wanting to post a code or XSLT snippet onto your blog and found yourself writing HTML to make it look like it does in Visual Studio (or resort to screen shots) then fret no more, CopySourceAsHtml will take anything that you can open in VS (source code related) and convert it to HTML for you.

The tool is written by Colin Coller and can be downloaded on the CopySourceAsHtml homepage. In addition, Colin has a blog which updates progress on the tool. I read that a VS 2005 version is soon to be ready.

A couple of tips when using it:

  • After installing you should be able to open any C# source code page, highlight and right click a code snippet and see a new “Copy as HTML” item on the menu. But, if for example you want to copy XSLT, the item doesn’t show up. Use the edit menu instead.
  • When you copy something as HTML, under general, uncheck the “Number lines from:” box unless you really want them and also check the “Embed styles” box since blog tools/some browsers wont recognize the style sheet that gets created. Embeding the style makes it a simpler operation.

Wednesday, December 28, 2005

How to stop applications from unloading in
BizTalk 2004

Recently we developed a time sensitive BizTalk application where a simple set of processing steps were invoked via a web service.

The external calling application (the application calling the BizTalk process) had just 5 seconds to complete its task. Since the BizTalk part was not very complex or resource intensive, we were achieving response times of 1 second, well within the 5 second margin.

During testing, though, we were getting intermittent timeouts because the BizTalk application was unloading itself from memory and causing the calling application to timeout. Basically it took more than 5 seconds for the unloaded BizTalk application to start itself up again and caused a failure.

BizTalk relies on a configuration file to store its application information. This config file contains settings for unloading an application from memory and is located at \Program Files\Microsoft BizTalk Server 2004\BTSNTSvc.exe.config. Full documentation can be found at Microsoft’s website but here is a working example you can download.

By default BizTalk has 2 shutdown settings which are:

SecondsIdleBeforeShutdown = 1800 (seconds, or 30 minutes)
SecondsEmptyBeforeShutdown = 1200 (seconds, 20 minutes)


The link below is a sample config file that never shuts down. We are isolating these “hot” processes on a separate server from the “cold” processes (processes that can safely unload). You can run hot and cold side by side as well but that requires more changes in the config file. If you set the SecondsIdleBeforeShutdown and SecondsEmptyBeforeShutdown to -1 they will always stay in memory.

Note that this is increasing the load on the server but for time sensitive situations this could save you a rash of intermittent errors in production. Note also that you shouldn’t do this unless you really need to, unloading saves resources and with most integration scenarios the few seconds it takes to start up are minor.

You can backup your current file, download this BTSNTSvc.exe.config zip file and extract it, then stop and start your BizTalk host to see it work.

Tuesday, December 27, 2005

Fully qualified name differs for XSD’s with
multiple root nodes in the Business Rules Engine

One of the most common problems that exist when using the business rules engine is forgetting to use the fully qualified name from a schema in definition of the rule.

Posts like this on Google Groups can clarify what I mean if what I am talking about is not clear.

I have discovered something new regarding the fully qualified name which caught me out this morning and I thought I’d mention it here in case you have the same problem.

If you are using the fully qualified name of a schema with multiple root nodes in the BRE, the fully qualified name must include the name of the root node. When you go to your orchestration and try to feed a rules shape your XSD you will find it won’t recognize it (no drop down appears).

For example you can have a schema with multiple root nodes with a fully qualified name such as schma_name_fully_qualified which, with a single root node, would work just fine. But if the schema has multiple root nodes you must append the specific root node to this qualification for the orchestration to recognize the rule.

So if you had the fully qualified name schma_name_fully_qualified, look at your orchestration view, click on the message you are using and look at the message type: you will find that you must use something like schma_name_fully_qualified.header to properly identify the schema when creating your business rules. Changing this should then allow you to select a message type in your orchestration.

Thursday, December 22, 2005

"multiple schemas match the message type"
may be caused by web services

I was stuck recently with what seemed like a pair of contradictory errors.

I had an application deployed which was exposed as a web service. To test the application we built a test harness which picked up a flat file and called the web service for us and then dumped the result on the file system to see the result.

This testing system worked fine until I needed to use that same deployed schema to do some additional messaging. I wanted to route a message via a receive port and have a send port subscribe to it, then map the message to a new format and deliver it to a destination. Pretty simple, right?

Well, no. When I have my project deployed I got the following error when routing:

There was a failure executing the receive pipeline: "Microsoft.BizTalk.DefaultPipelines.XMLReceive" Source: "XML disassembler" Receive Location: " D:\dat\FileReceive\RoundTrip\*.xml Reason: Cannot locate document specification as multiple schemas match the message type "http://BO.Get.EV2#Method".

That error left me scratching my head. It means I probably have the schema deployed twice, right? I didn't, so I thought. When I undeployed the application the messaging engine could no longer match my message type:

There was a failure executing the receive pipeline: "Microsoft.BizTalk.DefaultPipelines.XMLReceive" Source: "XML disassembler" Receive Location: "D:\dat\FileReceive\RoundTrip\*.xml"
Reason: Finding document specification by message type "
http://BO.Get.EV2#Method" failed. Verify that the schema is deployed properly.

When I deployed the project with the schemas, everything suddenly worked fine. That means that, somewhere, the schema was again deployed.

So I looked thru the BizTalk Server Assemblies viewer and discovered that the web reference which existed in my test harness was the culprit. The messaging engine recognized the web reference as a second deployment of my schema. This was technically accurate but rather frustrating to find. I've seen so many of these errors posted on the newsgroups that I thought I'd mention this as a possible cause.

If you are using test harnesses coupled with web services be aware that your schema is actually deployed twice.

Friday, December 16, 2005

Easier way to add a DLL to the GAC

Often in BizTalk you’ll need to add assemblies to the Global Assembly Cache. In the past I had used a shortcut on my Quick Launch toolbar which opened the GAC, then I’d drop the assembly inside, but there is an easier way.

A registry key can be created which allows you to right click the DLL and “GAC it” in one click.

The text for the key is below; simply copy/paste it into notepad and save it as a registry file (.reg). Then double click the file to add it to the registry.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\dllfile\shell\gacutil\command]
@="c:\\windows\\Microsoft.NET\\Framework\\v1.1.4322\\gacutil.exe /i \"%1\""



You can also download the Gacutil right-click key as a zip file here.

Saturday, December 10, 2005

BizTalk exception handling with web services

Recently I needed to include exception handling in a web service call to an external party. I learned a couple of things and thought I’d highlight them here.

Exception handling doesn’t always behave the way you expect when you are trying to catch exceptions when calling a web service. While using one is very useful some things must be considered or you will not get the result you wanted.

Here is one way to do it as well as a few things to keep in mind when you want to set one up:

  • Include the external web service call (both send and receive shapes) in either a non-transactional scope shape or a long running transaction.
  • Decide if you need to catch any specific exceptions, if you don’t, using the General Exception will suffice. If you need to catch specific errors, you can use multiple catch exception blocks.
  • It may sound obvious to say this, but make sure your orchestration doesn’t have a timeout that is the same length (or shorter) than the timeout of your scope transaction.
  • Most important: in your send port which holds the reference to the web service, make sure you are not using any retries (unless, of course, you explicitly need to). If the web service fails with an error such as “There is an error in XML document (5, 10)” and you have retries enabled you will only see warnings in your event viewer (which means the exception block won’t be activated until the SOAP timeout).

Thursday, December 01, 2005

Solving BizTalk "error X2044"

I encountered a strange compilation error recently in BizTalk 2004 when importing a web service.

While I can’t put my finger on the exact cause yet, I do have a fix that works.

When you see an error message like:

C:\Project\Web References\ExtRef\MyOrch.odx(445,23): error X2044: symbol '@@@@' is already defined; the first definition is in assembly @@@.dll : It may be possible to disambiguate by using fully qualified names.

The way to fix this error is to do the following:

  • Open the orchestration in Notepad (In my case MyOrch.odx)
  • Do a find (Ctrl+F) for “#endif // __DESIGNER_DATA”
  • Delete all the code below that line
  • Save your file in Notepad
  • Say yes when Visual Studio asks if you want to update your file
  • Recompile

Note: The code will not be regenerated until you edit an expression shape, etc. Add a “//” or something and you will then see the code re-appear when you open it in Notepad again.

I hope this may serve to save someone time, it took a while for me to figure it out.