BizTalk DW Reporting???

29 March 2012

Last week we encountered this mysterious BizTalk error in the event log:

Faulting application btsntsvc.exe, version 3.6.1404.0, stamp 4674b0a4, faulting module kernel32.dll, version 5.2.3790.4480, stamp 49c51f0a, debug? 0, fault address 0x0000bef7.

The system log contains entries every minute saying  the BizTalkServerSend  service  terminated unexpectedly.

It happened at all of our customers after updating one of our BizTalk based applications to a new version. The only clue I could find was this support article from Microsoft that describes the same scenario. However in our case no dynamic Windows SharePoint Services (WSS) send port is used. But we do use static WSS send ports. After examining I found out that the binding of one of them was corrupted!

The update of our BizTalk based solution is automated, because it has to be applied at a lot of customers. Part of the process is modification of the specific binding file, by altering the URL to the specific SharePoint document library of the customer. It is located in a string encoded XML within the <TransportTypeData> element. Something went wrong when altering the encoded xml and corrupted the content of the <TransportTypeData> element.

Advertisements

BizTalk Generic WCF Service exceptions

9 April 2010

The BizTalk WCF adapter provides a very nice feature for implementing a Generic WCF Service that eats any SOAP message it receives. However when trying to test this with Altova XMLSpy I encountered the next exceptions:

The adapter “WCF-BasicHttp” raised an error message. Details “System.NotSupportedException: Specified method is not supported.

In this case the SOAPAction was “BizTalkSubmit” which will throw a NotSupportedException as documented. So if you generate a client for this web service you need to change the SOAPAction into something else. I think anything but “BizTalkSubmit” will do.

The adapter “WCF-BasicHttp” raised an error message. Details “System.InvalidOperationException: Text cannot be written outside the root element.

The default setting of the WCF adapter uses the “contents of <soap:Body> element” option for the inbound message body. It seems that when you have an indented XML message the filtered body starts with whitespace which causes this exception. For me it was enough to use “/*” as body path expression instead to solve it.

clip_image002


How to publish an XmlDocument or Microsoft.XLANGs.BaseTypes.Any message to the MessageBox with its MessageType promoted!

7 September 2009

Sometimes you would like to have a generic orchestration that can handle any type of messages that should be send to the MessageBox through a direct bound send port. Ofcourse it would be nice if the message could be routed based on its MessageType after being published. Unfortunately when publishing an XmlDocument or Any message from an orchestration the message type is not promted. Also it can’t be promoted from within the orchestration because BTS.MessageType is read-only.

A solution for this problem was on my wish list for a while and finally I found one.

It’s a combination of calling the XMLReceive pipeline inside the orchestration and assigning an initializing correlation set with the BTS.MessageType to the send shape. The XMLReceive pipeline determines the message type and the correlation set promotes it.

First ad the following references to the orchestrations project:

Microsoft.BizTalk.Pipeline
Microsoft.BizTalk.DefaultPipelines
Microsoft.XLANGs.Pipeline

Within a scope with atomic transaction type create a variable of .Net type Microsoft.XLANGs.Pipeline.ReceivePipelineOutputMessages. Use an assignment shape to assign the XMLDocument or Any body part of the message and execute the XMLReceive pipeline. For example:

msgRetry.HeaderPart = varHeader;
msgRetry.BodyPart = xpath(msgFault, "/*[local-name()='FaultMessage' and namespace-uri()='http://schemas.microsoft.biztalk.esb.com/exception']/*[local-name()='Messages' and namespace-uri()='']/*[local-name()='Message' and namespace-uri()='' ][MessageName='BodyPart']/*[local-name()='MessageData' and namespace-uri()='']/*/*");

varPipelineMessages = Microsoft.XLANGs.Pipeline.XLANGPipelineManager.ExecuteReceivePipeline(typeof(Microsoft.BizTalk.DefaultPipelines.XMLReceive), msgRetry);

varPipelineMessages.MoveNext();
varPipelineMessages.GetCurrent(msgRetry);

Next a correlation type is needed with BTS.MessageType as correlation property. An initializing correlation set of this type needs to be assigned to the direct bound send port.

The atomic scope is needed because the ReceivePipelineOutputMessages type is not serializable. This could be avoided by wrapping the pipeline code in an external static helper method like this:

public static void DetermineMessageType(XLANGMessage message)
{
	ReceivePipelineOutputMessages pipelineMessages = XLANGPipelineManager.ExecuteReceivePipeline(typeof(Microsoft.BizTalk.DefaultPipelines.XMLReceive), message); 

	pipelineMessages.MoveNext();
	pipelineMessages.GetCurrent(message);
}

serializedForm :: Server was unable to process request

28 March 2008
After the migration of a Microsoft Dynamics CRM 3.0 application to CRM 4.0 and redirecting the BizTalk CRM adapter to the new server we received the following error message from the CRM web service when sending messages:
ErrorCode:   0x80040203
serializedForm :: Server was unable to process request.
After a few hours of puzzling we found out that this exception was caused by the fact that the send message contained an empty element for a CrmDateTime field. For example:
<contact>
  <birthdate></birthdate>
</contact>
When the empty CrmDateTime elements where removed from the message everything runs smoothly again.

Using BizTalk CrossReferencing API for parameters

17 March 2008

BizTalk has a nice feature called cross-referencing which is meant to cross-reference values between two or more systems. Usually this functionality shall be used in mappings through the cross-reference functoids. However CrossReferencing also provides a CrossReferencing Class that can be used directly in orchestration expressions or helper class libraries. This gives you the interesting opportunity to use the cross-referencing database tables to store parameters for your BizTalk applications in one place.

Below is an example of how you can implement a Parameter class that can be used in an orchestration:

using System;
using System.Data.SqlClient;
using Microsoft.BizTalk.CrossReferencing;

namespace Helpers
{
	public static class Parameters
	{
		private const string valXRef = "Helpers.Parameters";
		private const string valAppType = "MyApplication";

		internal static SqlConnection CreateDbConnection()
		{
			SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
			builder.DataSource = CrossReferencing.GetAppValue(valXRef, valAppType, "Server");
			builder.InitialCatalog = CrossReferencing.GetAppValue(valXRef, valAppType, "Database");
			builder.IntegratedSecurity = true;

			SqlConnection connection = new SqlConnection(builder.ConnectionString);
			connection.Open();

			return connection;
		}

		public static bool GoLeft
		{
			get
			{
				string val = CrossReferencing.GetAppValue(valXRef, valAppType, "GoLeft");
				return String.IsNullOrEmpty(val) ? false : Convert.ToBoolean(val);
			}
		}

		public static TimeSpan TimeOut
		{
			get
			{
				string val = CrossReferencing.GetAppValue(valXRef, valAppType, "TimeOut");
				return TimeSpan.FromSeconds(String.IsNullOrEmpty(val) ? 30 : Convert.ToDouble(val));
			}
		}
	}
}

Exception handling with the BizTalk ESB Guidance

12 March 2008

Yesterday I gave a presentation (together with Marcel Fernee of Microsoft) at the Dutch BTUG meeting (http://www.btug.nl) on my experience with the ESB Guidance. Part of the presentation was about the ESB Exception Management Framework and how I use it in the project I am working on.

Quote from the ESB Guidance documentation:

Using the ESB Failed Orchestration Exception Routing mechanism, the process steps are:

  1. Code in the exception handler that detects the error creates a fault message by calling the CreateFaultMessage method. For example:
    // Create fault exception message
    faultMsg = Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.CreateFaultMessage();
  2. The Failed Orchestration Exception Routing mechanism automatically inserts the error description into the fault message context (for example, “The Business Rule Engine threw a divide by zero error processing the LoanProcessing policy”).
  3. The Failed Orchestration Exception Routing mechanism automatically promotes failure- and application-specific properties into the fault message context, setting the values from the current environment. These properties are:
    * Application (auto-populated)
    * DateTime (auto-populated as a UTC value)
    * Description (auto-populated—the exception message)
    * ErrorType (auto-populated—the exception type)
    * MachineName (auto-populated—the current server name)
    * Scope (auto-populated—the Scope shape containing the current exception handler)
    * ServiceName (auto-populated—the orchestration name)
    * ServiceInstanceID (auto-populated—the orchestration instance ID as a GUID)

    WARNINGS:
    The DateTime property is auto-populated with a string in the format of the servers regional date and time settings. If the format can not be mapped by the SQL server adapter, you will get a BizTalk error when the fault message is published to the Exception Management Database. My proposed solution can be found at http://www.codeplex.com/esb/WorkItem/View.aspx?WorkItemId=4430.

    If the auto-populated Description is larger than 256 characters BizTalk itself will give an error when the fault message is published to the message box, because promoted properties cannot be longer. This should be fixed in the source code of the ExceptionMgmt class.

  4. Code in the exception handler sets other properties of the fault message as required, for example:
    // Set fault message properties
    faultMsg.Body.FailureCategory = "MessageBuild";
    faultMsg.Body.FaultCode = 1000;
    faultMsg.Body.FaultDescription = "Some error occurred";
    faultMsg.Body.FaultSeverity = Microsoft.Practices.ESB.ExceptionHandling.FaultSeverity.Severe;
  5. The Failed Orchestration Exception Routing mechanism automatically serializes the current Exception object into the fault message.
  6. Code in the exception handler can optionally add current orchestration messages to the fault message using the AddMessage(faultMsg, messageToAdd) method. This serializes and persists the message, including all of the context properties. For example:
    // Add other current orchestration messages to the fault message
    Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.AddMessage(faultMsg, approvedRequestMsg);
  7. Code in the exception handler publishes the fault message through a direct bound port into the Message Box database.
  8. If publishing succeeds:
    * Orchestration or send port subscriptions can process the fault, rehydrating the Exception object, and extract any added messages complete with their context property values.
    * A global exception handler (a send port) automatically publishes the fault message to the ESB Management Portal.

Below is an example of the catch blocks that we us in our orchestrations. imageIn the Construct exception shape steps 1 to 6 are taken.

Then a Start Orchestration shape is called to start the ExceptionHandler orchestration in the figure below. This is also the place where step 7 is done. Here a very nice, but undocumented, feature of the ESB Guidance Core Framework can be used to log the exception: the EventLogger!

exception = Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.GetException(faultMsg);
Microsoft.Practices.ESB.Exception.Management.EventLogger.LogMessage(
    exception.Message,
    System.Diagnostics.EventLogEntryType.Error,
    (System.Int32)Microsoft.Practices.ESB.Exception.Management.EventLogger.EventId.Default
);

image