Click here to Skip to main content
6,295,667 members and growing! (12,938 online)
Email Password   helpLost your password?
Enterprise Systems » Microsoft BizTalk Server » General     Beginner

Debatching large messages and extending Flatfile pipeline disassembler component in Biztalk 2006

By Selvan

This article is aimed to explain the basics of custom flatfile disassembler
Windows, Visual Studio, Dev
Posted:13 Jan 2007
Views:22,101
Bookmarked:14 times
Unedited contribution
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
5 votes for this article.
Popularity: 3.24 Rating: 4.64 out of 5

1

2

3
1 vote, 20.0%
4
4 votes, 80.0%
5

Introduction

Extending the components or API is not new to the IT industries; it was introduced in Object oriented programming model long back. The method of extending the components based on your requirement is so called Overriding. Modern programming languages like Java, .NET and many other languages supports it.

Similarly BizTalk 2004/ 2006 supports extending the Pipeline component or assembler to give a new meaning of the existing functionalities. Unlike .NET framework or Java Virtual machine base class libraries. BizTalk 2006 offers very good documentation on all supported classes, more over there are very good blogs and Newsgroups serves you better information.

Prerequisites

This article assumes that you have knowledge of custom pipeline creation and deployment.

Debatching

Integration projects mostly requires splitting the large messages in to chunk of small message in the receive pipeline or in the orchestration. This process is so called De-batching. De-batching messages using biztalk can be achieved in many ways as follows

(Available in many Geek blogs)

  • Envelope Message debatching: In general two schemas are configured in receive pipeline and called either from Adapter or Orchestration (BizTalk 2006 only)
  • Orchestration debatching: Orchestration is designed to loop through until end of messages and splits by calling custom .NET component or using the xpath function in the orchestration expression editor.
  • Custom Pipeline debatching:Disassemble() and GetNext() methods of Pipeline disassembler component will be overridden to debatch the input messages.

Scenario

Assume that you work for a Health care Insurance company and you receive all the participants list who have completed activities like "Master Health check up" from different Hospitals all over country from the third party data vendors. You are scheduled to receive the participant list as a pipe delimited large flat file (size of 10 MB approx) once in a week.

Your company expose you a .NET web service that accepts array of participant details as input and helps you storing the details into global database. Your requirement is to poll the flat file using Biztalk 2006 , split it into 50 participant details record as a batch and pass it to intranet web service. Sounds easy?

Extending FF Disassembler Component

Custom Flatfile disassembler class can be extended by inheriting "FFDasmComp" class which is available under namespace "Microsoft.BizTalk.Pipeline.Components". For accessing namespace "Microsoft.BizTalk.Pipeline.Components" you have to add the following dll as reference under your project.

Microsoft BizTalk Server 2006\Pipeline Components\Microsoft.BizTalk.Pipeline.Components.dll

FFDasmCompclass exposes the following methods and properties

A short description of core members

InitNew:

Initialize the current FFDasm class, This method called only once.

Accepts Nothing

Returns Nothing

Disassemble:

Takes apart of the given message and make it as Biztalk understandable Xml message and stores it into message set. This method will be called only once for the given message.

Accepts IPipelineContext and IBaseMessage as input parameters, where as IPipelineContext is the context of executing pipeline and IBaseMessage is the Flatfile in our case.

Returns Nothing

GetNext:

Returns a single message from the Message set, that was stored in Disassmble() method call, This method will be called until it returns Null.

Accepts IPipelineContext as input parameter, where as IPipelineContext is the context of executing pipeline.

Returns IBaseMessage from the message set.

Load:

Load the Key value pair from property bag.

Save

Store the key value pair into property bag for the future execution.

DocumentSpecName:

Gets or sets the Schema name for the disassemble method to parse the given input file into BizTalk understandable format.

Developing Component

Let us delve into develop the component now.

Step 1:

Create your own class and inherit class and interfaces as shown below.

[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]

[ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]

[System.Runtime.InteropServices.Guid("57D51828-C973-4a62-A534-6DB3CB3CB251")]

public class LargeFlatfileSplitter :

FFDasmComp,

IBaseComponent,

Microsoft.BizTalk.Component.Interop.IDisassemblerComponent,

Microsoft.BizTalk.Component.Interop.IPersistPropertyBag

{

publicLargeFlatfileSplitter()

{

}

��

}

Step 2:

As usual give a meaningful Description, Name and Version to your component.

Step 3:

Create your GUID using .NET GUIDGen tool , copy it to clipboard and paste into your GetClassID method.

#regionIPersistPropertyBag Members

void IPersistPropertyBag.GetClassID(out Guid classID)

{

classID = new Guid("57D51828-C973-4a62-A534-6DB3CB3CB251");

}

void IPersistPropertyBag.InitNew()

{

base.InitNew();

}

void IPersistPropertyBag.Load(IPropertyBag propertyBag, int errorLog)

{

base.Load(propertyBag, errorLog);

}

void IPersistPropertyBag.Save(IPropertyBag propertyBag, bool clearDirty, bool saveAllProperties)

{

base.Save(propertyBag, clearDirty, saveAllProperties);

}

#endregion

Note InitNew, Load and Save method calls the base class (FFDasmComp) methods respectively.

Step 4:

public new void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)

{

try

{

base.DocumentSpecName = this.DocumentSpecName;

base.Disassemble(pContext, pInMsg);

}

catch (Exception ex)

{

System.Diagnostics.EventLog.WriteEntry("Disassemble:Error", ex.Message);

}

}

The above method diassembles the input flatfile into xml message, Flatfile schema (DocumentSpecName) you mention in property browser will be used here.

Step 4:

publicnew IBaseMessage GetNext(IPipelineContext pContext)

{

//System.Diagnostics.EventLog.WriteEntry("GetNext:Called", currentMessage.ToString());

try

{

if (stopCollectingMessages == false)

{

IBaseMessage ibmTemp = base.GetNext(pContext);

GetSplittedMessages(ibmTemp, pContext);

stopCollectingMessages = true;

if (0 == outboundMessages.Count)

return null;

}

}

catch (Exception ex)

{

System.Diagnostics.EventLog.WriteEntry("GetNext:Error", ex.Message);

}

if (currentMessage == outboundMessages.Count)

return null;

// Return the current collected message

return (IBaseMessage)outboundMessages[currentMessage++];

}

The above mentioned method is a core method in our case. This loads your disassembled message stream into XPathDocument (This is were your performance goes down if your message is greater than 10 MB, we will discuss it later).

Using Xpath expression we split your XPathDocument, loop through each child node of your interest 50 times and append it into new XmlDocument.

So you collected 50 child nodes in XmlDocument, then you create a new IBaseMessage and save the XmlDocument into IBaseMessage Data stream at the same time you store them into collection list.

Do these steps until you complete collecting messages and mark your stopCollectingMessage flag as true, so that when next time Biztalk calls your GetNext function, you return IBaseMessage from the CollectionList.

Compile the project and copy the dll into your PipelineComponets directory and GAC it.

That's all you are ready to go

Performance

This component is suitable for only the message size of less than 15 MB. Since this article only aims to explain about the other way of splitting message in pipeline, you can easily enhance this component using SeekableReadOnlyStream and Microsoft.BizTalk.XPathReader classes for extremely large messages (100 MB+).

SeekableReadOnlyStream is a wrapper class of System.IO.Stream provides a faster and better way of accessing IBaseMessage stream when you are not required to modify the input stream. XPathReader class is not directly available to add reference in your component. You have to go browse your GAC directory from command shell, get the path of "Microsoft.Biztalk.XpathReader.dll" and refer in your component. Most likely it can be found in the "C:\WINDOWS\assembly\GAC_MSIL\Microsoft.BizTalk.XPathReader\3.0.1.0__31bf3856ad364e35" directory.

private void GetSplittedMessages(IBaseMessage ibmParam, IPipelineContext pCxt)

{

System.Xml.XmlDocument xDoc;

string temp = "";

if (ibmParam != null)

{

XPathDocument xp = new XPathDocument(ibmParam.BodyPart.Data);

XPathNodeIterator xNI = xp.CreateNavigator().Select("/*[local-name()='CustomersList' and namespace-uri()='http://BiztalkArticle.Customers']/*[local-name()='Customers' and namespace-uri()='']");

bool blnMoveNext = true;

while (blnMoveNext)

{

xDoc = new System.Xml.XmlDocument();

System.Xml.XmlElement xParent = xDoc.CreateElement("CustomersList", "http://BiztalkArticle.Customers ");

for (int i = 0; i < this.recordsPerMsg; i++)

{

blnMoveNext = xNI.MoveNext();

if (blnMoveNext == false) break;

XPathNavigator xn = xNI.Current;

if (xn != null)

{

temp = xn.InnerXml;

System.Xml.XmlElement xe = xDoc.CreateElement("Customers");

xe.InnerXml = temp;

xParent.AppendChild(xe);

}

}

xDoc.AppendChild(xParent);

//System.Diagnostics.EventLog.WriteEntry("GetNext:Xml", xDoc.OuterXml);

IBaseMessage msg = null;

msg = pCxt.GetMessageFactory().CreateMessage();

//System.Diagnostics.EventLog.WriteEntry("GetNext:After Msg", "");

msg.Context = ibmParam.Context;

IBaseMessagePart msgPart = pCxt.GetMessageFactory().CreateMessagePart();

System.IO.MemoryStream memStrm = new MemoryStream();

xDoc.Save(memStrm);

memStrm.Position = 0;

memStrm.Seek(0, System.IO.SeekOrigin.Begin);

msgPart.Data = memStrm;

msg.AddPart(ibmParam.BodyPartName, msgPart, true);

outboundMessages.Add(msg);

pCxt.ResourceTracker.AddResource(memStrm);

}

}

}

#regionIBaseComponent Members

[Browsable(false)]

public newstring Description

{

get { return "Biztalk Large flatfile splitting"; }

}

[Browsable(false)]

public new string Name

{

get { return "Large Flat File Disassembler"; }

}

[Browsable(false)]

public new string Version

{

get { return "1.0"; }

}

#endregion

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Selvan


Member
Tamilselvan Subramanian is a Lead consultant working on Microsoft Technologies for the past 6 years, Currently living in Newyork, US. Technical experience most specifically Biztalk 2004/2006, Webservices, C# and .NET framework,VB.NET, XML, XSLT, Flat file,Java.

He was awarded 'Community Star' by Microsoft for resolving .NET community people questions.
http://www.microsoft.com/india/communitystar/CurrentSelections.aspx

He blogs @ http://biztek.blogspot.com here.
You can reach him at tamilselvan +2 gmail.com.
Occupation: Software Developer (Senior)
Location: United States United States

Other popular Microsoft BizTalk Server articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 3 of 3 (Total in Forum: 3) (Refresh)FirstPrevNext
GeneralPlz..post the source code Pinmemberkotha rajesh0:07 5 Jan '09  
GeneralcurrentMessage variable PinmemberKarthikcse21:23 13 Mar '07  
GeneralSource Code PinmemberDDIA16:10 23 Jan '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 13 Jan 2007
Editor:
Copyright 2007 by Selvan
Everything else Copyright © CodeProject, 1999-2009
Web17 | Advertise on the Code Project