Build BizTalk 2004 Custom Pipeline Components to Process Non-XML Data

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

BizTalk 2004 Pipelines allow you to customize the processing of XML documents received or sent via the various BizTalk 2004 adapters. Custom Pipeline components extend the behavior of Pipelines to include processing data of virtually any format. They can be a powerful solution if you support legacy systems that require integration with other products, but your legacy data format does not follow standards. It may contain carriage returns in odd places or records spanning any number of lines of text, for example. The only stipulation is that the data emerging from the Custom Pipeline must be some form of XML document.

At my company, Crowe Chizek, the time and billing system generates invoices as ASCII text files, which follow none of the standard formatting rules, such as tab delimited, fixed field length, comma delimited, etc. These files include formatting characters in the text. A separate program has to interpret the ASCII text’s formatting characters and print the invoice. Crowe Chizek’s time and billing users were spending a great deal of time printing invoices and routing hard copies with corrections to each other.

We decided to build an application to facilitate invoice creation from the time and billing system. Rather than reconstructing the business logic, which created the ASCII file, we decided to load the billing information directly from the ASCII file into our invoice facilitation application. We employed the capabilities of BizTalk 2004 to handle the ASCII files and perform workflow actions like posting email once a file has been processed. The BizTalk 2004 File Adapter worked fine for receiving the files, but we needed a custom Pipeline component and a Pipeline to process the incoming files. This article demonstrates the custom Pipeline component solution we employed.

Building the Custom Pipeline Component

As stated previously, pipelines are implemented in a BizTalk 2004 project for a variety of reasons, including encryption/decryption, splitting single XML documents into multiple documents, and converting flat files into XML documents. You begin building a Pipeline by adding a one to your BizTalk 2004 project (see Figure 1).

Figure 1. Add a Pipeline to Your BizTalk 2004 Project

To complete a Pipeline, you must select one or more Pipeline components from within Visual Studio .NET and add it/them to the Pipeline. None of the existing BizTalk 2004 Pipeline components satisfied our requirements, so we built our own.

A custom Pipeline component is a .NET assembly that implements the Microsoft.BizTalk.Component.Interop.IComponent interface, the System.Runtime.InteropServices.Guid property, and the ComponentCategory(CategoryTypes.CATID_Validate) property housed in the Microsoft.BizTalk.Pipeline.dll assembly. Samples in the BizTalk 2004 SDK and the BizTalk 2004 documentation illustrate how to implement the appropriate properties. This tutorial focuses on the areas specific to Crowe Chizek’s implementation and summarizes the items already documented in the BizTalk 2004 documentation.

IComponent contains a method called Execute. The Execute method is where the magic happens in the custom Pipeline component. In the Execute method of the Pipeline Assembly, an XML document replaces the data from the ASCII file. The following code enables you to gain access to the data from the ASCII file passed to the Pipeline:

IBaseMessagePart bodyPart = inmsg.BodyPart;

if (bodyPart!=null)
{

Inmsg is the IBaseMessage interface passed to the Execute function. IBaseMessagePart includes a function for accessing the data in the message pipeline. The GetOriginalDateStream function returns a Stream object. Stream objects are part of the .NET Framework. You can read the data from a stream by using methods like Seek and Read. The following example declares originalStrm as a Stream object:

originalStrm = bodyPart.GetOriginalDataStream();

Copying the ASCII data out of the Stream you’ve accessed via the IBaseMessagePart requires you to move the data into and out of byte arrays. The following code copies all of the data from the ASCII text file to a string variable called myData:

buffer = new byte[originalStrm.Length];

originalStrm.Read(buffer,0,Convert.ToInt32(originalStrm.Length));

myData = System.Text.ASCIIEncoding.ASCII.GetString(buffer);

To write the XML document back to the Pipeline, simply replace the Stream object with a new Stream object. The following sample code fills a MemoryStream object with the XML data and assigns the bodyPart.Data property to the MemoryStream object you loaded with the XML document:

//Change the data
bodyPart.Data = memStream;

The only remaining task to complete the Execute method is to promote the message so BizTalk can properly identify it. The following code ensures that BizTalk can identify the Namespace for the message once the XML document passes out of the Pipeline:

// You must manually set the message type
systemPropertiesNamespace = @"http://schemas.microsoft.com/BizTalk/
                                     2003/system-properties";
                            inmsg.Context.Promote("MessageType",
                            systemPropertiesNamespace,
                            _XMLMessageType);

If you did not promote the message before sending it out of the Pipeline, BizTalk could not route the message to the Receive Shape in your Orchestration.

Time to Debug

With the custom Pipeline component complete, we turn our attention to debugging. Our implementation was more complicated than the included sample code. To debug our solution, we utilized some of the BizTalk Pipeline debugging tools.

Setting up your project to debug a custom Pipeline component is not straightforward. BizTalk includes a command line utility for debugging Pipelines aptly named Pipeline.exe. The file is located in the ” Installdir:\Program Files\Microsoft BizTalk Server 2004\SDK\Utilities\PipelineTools\ ” directory. To utilize it, you must set the options shown in Figure 2 under the debugging section on the Properties dialog of the Project.

Figure 2. Settings for Utilizing Pipeline.exe Debugging Utility

Command Line Arguments include the name of the Pipeline that uses your component, the name of the sample file to pass to your Pipeline, the ” -c” to display the resulting output document, and ” -v” command line switches to display additional data, which will be useful for troubleshooting.

More by Author

Get the Free Newsletter!

Subscribe to Data Insider for top news, trends & analysis

Must Read