Updated sample for my article ‘Dealing with base64 encoded XML documents in BizTalk’

28 October 2009

Almost a year ago I published my article on a possible way to deal with base64 embedded documents in XML messages.

Since then I received a lot of emails and comments from people that where unable to get the sample up and running. I must admit there are quite a lot manual steps to get from the downloadable source to a running BizTalk application.

This is why I updated the article. It has links to three downloads now:

I hope this will make life easier for people who want to try it out.


Was promoted

15 June 2009

Ever wanted to know in a send pipeline if a property was promoted before? The BizTalk API comes with an object called ‘ContextPropertyType’ which you can use for this purpose.

I have a very simple schema and corresponding instance:

waspromoted_schema

waspromoted_schema_instance

Above message travels through BizTalk using the following path:

receive port -> orchestration -> send port

I defined the ‘Firstname’ element as promoted property to have it promoted by the out-of-the-box XmlReceive pipeline. After that the message is sent to the message box and picked up by the orchestration to do some processing. Next the orchestration will send the message to the message box again using a send shape. Finally the send port picks up the message and sends it to some URI using an adapter.

In the send port I used a custom pipeline containing a pipeline component with this code:

waspromoted_code

 After the message has been picked up by the send port the messaging engine will alter the context of the message. The ‘Firstname’ element that was promoted before is not promoted anymore now. To prove this I call the IsPromoted method for the specific property (see code above).

So what if you want to know if the property was promoted before? This is where the ContextPropertyType object comes in. Together with the ‘GetPropertyType’ method on the context object I’m able to find the status of the property.

Running this example shows the following output in DebugView:

waspromoted_debug_view

 As you can see the PropertyType has a value equal to ContextPropertyType.WasPromoted. In the above sample I used an orchestration in the middle but the same will also apply to messaging only scenarios.

Although I recently made use of this API while implementing a very simple repair and resubmit feature, there might not be so many real world scenarios where one would use this. At least I couldn’t think of many. (Suggestion? Ping me, please.).  Also be aware that is an undocumented feature for which the BizTalk help states it is for internal use only. This basically means Microsoft will not guarantee any backward compatibility for this when new versions or SPs are released.


Custom recoverable interchange processing pipeline components

31 March 2009

In my last post I blogged about the improvements to recoverable interchange processing (RIP) in the upcoming 2009 release of BizTalk Server. One question that pop up while writing that post was whether it would be possible to write a custom pipeline component that supports RIP.

After doing some research on the Internet I found out that it is possible and fairly simple to do. Actually it was already possible in BizTalk 2006. It was just something that I (and the co-workers that I asked) didn’t know. So please stop reading if you are already familiar with this :-)

A typical  scenario is a pipeline that consists of a XmlDisassembler and this custom RIP pipeline component. The interchange is received in the pipeline and disassembled into separate body messages by the XmlDisassembler. After that, for each body stream some processing is performed by the custom pipeline component. If this processing fails the single body instance needs to be suspended instead of the whole interchange.

There are basically three things you must do in your pipeline component to enable this:

Write property “SuspendMessageOnRoutingFailure”

The property “SuspendMessageOnRoutingFailure” needs to be written to the context of the message in case the processing of the message in the pipeline components succeeds. The value of the property needs to be set to true.

This property tells the messaging engine that each body message needs to be suspended in case of a routing failure. If you don’t write this to the context you’ll get a routing failure report for each body message while there will only be one suspended message (the whole interchange).

Write property “MessageDestination”

This property needs to be written to the context of the message when the custom pipeline components has decided that the processing on this specific body message has failed.

The value needs to be ‘SuspendQueue’ so that the messaging engine knows this particular body message needs to be suspended.

Return a searchable stream

The messaging engine needs a searchable stream to be able to put the body message in the ‘SuspendQueue’. I don’t know the exact reason behind this but the engine probable needs to rewind the stream for proper error handling. Anyway we just have to make sure we return a searchable stream when the body instance needs to be suspended.

I wrote a simple test application to test this. The first I did was adding a property to enable or disable the RIP feature of my component. Much like the setting for the XmlDisassembler (and XmlValidator in BizTalk 2009)

image

The execute method of the pipeline looks like this:

image

First the incoming stream is wrapped a XpathMutatorStream object to be able to receive an event when a certain xpath is matched. I use this to check whether or not the message is wrong (and should be suspended). In this sample the body messages each contain an attribute to indicate whether they are ‘good’ or ‘wrong’.

image

Next I create a virtual stream (which is searchable) to meet the requirement of returning a searchable stream.

In the third step I create a new output message containing the searchable stream.
If the message is ‘good’ I don’t care about RIP being enabled or disabled and just return the message (using the method ‘HandleHappFlow’). The only thing I need to do is write the ‘SuspendMessageOnRoutingFailure’ context property to the message as mentioned above.

If the message is ‘wrong’ and RIP is enabled I call the method ‘HandleRecoverableError’. The code of this method:

image

It just returns the message with the searchable stream, set some error information and writes the property ‘MessageDestination’ to the context.

Finally if the message is ‘wrong’ and RIP is disabled I throw an error so that the whole interchange will be suspended by the messaging engine.

image

The sample source can be downloaded from here. It was developed using the beta release of BizTalk Server 2009. As said before the sample should also work for BizTalk 2006. The solution needs to be manually converted back to a Visual Studio 2005 solution however.


Recoverable interchange processing enhancements in BizTalk 2009

26 March 2009

The text below is based on the beta release of BizTalk 2009. It might not (completely) apply to the RTM release.

BizTalk Server 2009 brings developers a lot of new functionality. In presentations and blog posts most of those new functions have already been described and shown.

One of the new things that is not or only briefly mentioned are the enhancements to Recoverable Interchange Processing (RIP) in BizTalk 2009. Also the help file (beta) of BizTalk 2009 doesn’t provide a lot of information on this (yet) and there are no samples.

I had some time to play with RIP in BizTalk 2009. The diagram below provides an overview of the very simple BizTalk sample application that I used.

RIP sample

This is what happens:

1). First a ‘family’ envelope XML message (also called an interchange) is received by a file receive port.

2). The receive port contains custom pipeline which in turn contains two default pipeline components; XmlDisassembler and XmlValidator.

3). The XmlDisassembler disassembles the family envelope message into separate ‘person’ XML messages

4). The XmlValidator component validates the individual ‘person’ messages before they are delivered to the message box.

5.) The receive port has failed message routing turned on. So if anything fails in the steps above a send port with a subscription on the failed messages picks up the messages and writes them to an error folder (left send port in the diagram). If everything works ok the disassembled messages are saved in the out folder by the another send port (send port at the right in the diagram).

Another thing to note is that I set the recoverable interchange processing option to true in the properties of the XmlDisassembler.

RIP in BizTalk Server 2006 R2

First lets look on how this works in BizTalk Server 2006 R2.

When I post an invalid message (see message below; the second node has an invalid element named ‘Name’). The XmlValidator fails and the message is suspended, handled by failed message routing and finally written into the error folder.

The interesting thing here is that the message in in the error folder contains the full interchange (that is the original message that I provided to BizTalk). This happens because the RIP feature only applies to the XmlDisassembler component (see ‘A’ in the diagram) and not to the XmlValidator component (‘B’ in the diagram).

image

RIP in BizTalk Server 2009

Compared to BizTalk 2004 RIP was a big improvement in BizTalk 2006. In BizTalk 2009 the RIP feature has now been extended to other components. The XmlValidator pipeline component now also has the option to turn op RIP via the pipeline configuration.

image

The invalid message above is now handled in a different way. The disassembled valid person messages (1 and 3,4,5) are now put into the out folder while the invalid person message (2) is put in the error folder.

image

So now instead of the whole interchange only the failed person message is suspended while the valid messages continue their way to the message box.

The RIP setting in the XmlValidator has no relation with the RIP setting in the XmlDisassembler. So the above sample will produce the same result if the RIP setting in the XmlDisassembler is set to false. 

Internally this works because the XmlValidator pipeline component has been extended with code that will return a message stream even when there is a validation error. This stream is accompanied with special information on the context so that the message agent will put the message in the suspended queue.

RIP and maps

In BizTalk 2009 it is even possible to extend this behavior to maps that are used in the receive port. To enable this you have to write a special property called ‘SuspendMessageOnMappingFailure’ to the context of the message.

image

Setting the value of ‘SuspendMessageOnMappingFailure’ to true will only suspend the invalid message instead of the whole interchange. I personally think it is a bit cumbersome that you have to enable this in code. One has to write a custom pipeline component just to turn on a feature. It would be nice if this could be enabled by setting a property in the map configuration section of the port using the BizTalk administration console.

Anyway the BizTalk 2009 Recoverable Interchange Processing feature is a nice extension to handle interchanges in BizTalk server. It can save you from a lot of custom coding in pipeline components.


Promoting values from envelope to body

7 January 2009

I might be stating the obvious in this post but it took me and my colleague quite a while before we found what we were doing wrong. We wanted to disassemble the body messages from an envelope message and promote a value from the envelope to each body message. Not exactly rocket science :-) .

Lets take the following schema and corresponding message as example:

Envelope_Schema_wrong

Envelope_Message_wrong

In this sample the value of the ‘FamilyNumber’ element from the envelope has to be promoted to the context of each body message. Ok, very easy…… we thought.

This can be done using build in BizTalk functionality. Create a property schema, promote the element from the envelope, use the default XmlReceive pipeline to promote the value from the envelope to each body message and done.

After the first test run We were very surprised to see that none of the context messages of the disassembled bodies contained the promoted value. It took an embarrassing long time before we found out that the element to promote needs to be before the body messages instead of after the body messages.

It makes sense because the XmlDisassembler component in the XmlReceive pipeline works in a streaming forward only manner. Each time a complete body message is read from the stream it is delivered to the message box (or next pipeline component). So when the stream reaches the element to promote the bodies have already been delivered to the message box. This is why their message context does not contain the promoted value.

Changing the schema to:

Envelope_Schema_good

will do the trick.