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.


70-241

20 March 2009

Today I took the BizTalk 2006 R2 exam and passed!  This is the third BizTalk  exam (BizTalk 2k4, BizTalk 2k6 and BizTalk 2k6r2) that I took.

There is Non Disclosure Agreement (which I didn’t read) presented to the candidates before the exam starts so I am probably not allowed to post a brain dump here ;-)

Anyway I think the exam is not so difficult if you, like me, work day to day with the product. Like all MS exams you should study on the features that are new compared to the previous version in this case BizTalk 2006 R1). These feaures are: RFID, WCF adapters and EDI/AS2.


Problem installing Windows SharePoint Services

9 March 2009

Below the annoying message box ‘The installation of this package failed‘ that popped up while building a fresh new (virtual) BizTalk Server 2009 development box on Windows Server 2008.

image

It occurred when I was installing Windows Sharepoint Services 3.0 with service pack 1, which is one the prerequisites for the SharePoint Services adapter.

I wanted to get on with the installation and didn’t want to spend much time on finding a solution. So to get around this I copied the .MSI back to my host system (in my case Windows Vista (Business edition) 64 bit). After that I used the command:

Sharepoint.exe /extract:c:tempwss

to extract the installation files from the downloaded .exe. Finally I copied the extracted files back to my virtual machine and ran ‘Setup.exe’. This time setup completed without a glitch.

image

I suspect Windows 2008 Server or one of the BizTalk 2009 prerequisites I already installed prior to WSS 3.0 to be the cause of the problem. Please comment or e-mail me if you’re not lazy like me, but took the time to find a more elegant and satisfying solution :-) . Until that time I hope I can help someone with this workaround.


Follow

Get every new post delivered to your Inbox.