Click here to Skip to main content
15,881,812 members
Articles / Programming Languages / C#

Custom BizTalk Pipeline Disassembler Component

Rate me:
Please Sign up or sign in to vote.
3.89/5 (8 votes)
6 Apr 2009CPOL4 min read 95.6K   1.4K   13   30
A custom BizTalk pipeline disassembler component.

Introduction

As part of system integration, specially when dealing with non-XML communication (flat files), a conversion is needed. It is the pipelines that come into the picture and transform the data into something that BizTalk can understand – XML. Essentially, pipelines form a channel for the messages from the adapters to the message box where they are finally delivered.

Pipelines are divided into two parts:

  1. Receive Pipeline: The receive pipeline is executed after the receive adapter. It takes up the chunk of raw data that comes from the external system, and works on it, performing tasks like validation of signatures, decryption, and transformation before disassembling it into zero or more BizTalk messages. The created messages are consumed individually by the BizTalk Server.
  2. The receive pipeline consists of four stages – Decode, Disassemble, Validate, Resolve Party. These are executed in the same sequence as they appear below:

    1. Decode: This stage would involve some pre-processing like verifying message signatures to ensure integrity, or decoding the S/MIME messages.
    2. Disassembler: It is here that a message gets converted entirely into XML format so that the messaging engine can understand it. The input is, of course, a plain text or an XML stream that is passed from the Decode stage. It is processed into one or more messages that are always in XML format.
    3. Validate: Typically, the validate component would check to see if the message is in the correct format or not.
    4. Resolve Party: As MSDN explains it, "The Party Resolution pipeline component is used to map the user security ID and the certificate subject for the client to a BizTalk Server party".
  3. Send Pipeline: It expects a complete well-formed XML message from the BizTalk engine, and then works on it to assemble it into a message that the external system can understand.
  4. Complimenting the receive pipeline, this can again be a flat file. It can also be encrypted and digitally signed before sending it out on the wire.

    The send pipeline consists of four stages:

    1. Preassemble: As the message comes to the Send pipeline, this is the very first stage that gets executed. This is basically a place holder stage that can do any pre-processing of the message before it needs to be assembled. The stage can contain up to 255 components.
    2. Assemble: Once the preassemble stage does its job, the assemble stage takes over to actually convert the message in a format that can be understood by the external system.
    3. Encode: As the message is converted to the external format, it is time to do any additional processing required on the message so that the external system can decode it properly. The processing of this stage includes S/MIME encoding, custom encryption of the message, or digitally signing it to maintain its integrity, or any other processing that can be required to encode the message.

We will cover the implementation of a custom disassembler in this article.

Background

To start with this article, you should be familiar with the Microsoft BizTalk Server, the .NET Framework, and C#.

Using the code

Before we start, you have to get familiar with these three main interfaces:

  • IBaseComponent: Defines the properties that provide the basic information about a component.
  • IPersistPropertyBag: Works with IPropertyBag and IErrorlog to define an individual property-based persistence mechanism.
  • IComponentUI: Defines methods that enable pipeline components to be used within the Pipeline Designer environment.
  • IDisassemblerComponent: is responsible for providing the assembling functionality.

IBaseComponent: there are three properties that must be implemented, that will appear at design time in Visual Studio.

C#
#region IBaseComponent Members

public string Description
{
    get { return "Testdisassembler"; }
}

public string Name
{
    get { return "Test disassembler"; }
}

public string Version
{
    get { return "1.0.0.0"; }
}

#endregion

IPersistPropertyBag: is responsible for getting the design time properties. If you need to have some properties be set during design time or during the deployment stage, you must add the loading and saving functionalities for those properties.

C#
#region IPersistPropertyBag Members

public void GetClassID(out Guid classID)
{
    classID = new Guid("25984614-BCFD-4c47-82FC-4A2300B76438");
}

public void InitNew()
{
}

public void Load(IPropertyBag propertyBag, int errorLog)
{
    object val = ReadPropertyBag(propertyBag, "TextProperty");
    if (val != null)
        textProperty = (string)val;
}

public void Save(IPropertyBag propertyBag, bool clearDirty, 
                 bool saveAllProperties)
{
    object val = textProperty;
    propertyBag.Write("Namespace", ref val);
}

#endregion

IComponentUI: defines the methods that enable the pipeline components to be used within the Pipeline Designer environment.

C#
#region IComponentUI Members

public IntPtr Icon
{
    get { return System.IntPtr.Zero; }
}

public System.Collections.IEnumerator Validate(object projectSystem)
{
    return null;
}

#endregion

Now, after understanding the three main interfaces, we can start implementing the components.

Disassembler: you have to implement the IDisassemblerComponent interface for this component.

C#
#region IDisassemblerComponent Members

public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
{
    System.Diagnostics.Trace.WriteLine("Pipeline Disassemble Stage Enter");
    msgPart = pInMsg.BodyPart;
    Stream originalStream = pInMsg.BodyPart.GetOriginalDataStream();
    try
    {
        if (msgPart != null)
        {
            if (originalStream != null)
            {
                string stream = string.Empty;
                // do the disassembling
                byte[] arrByte = ConvertToByteArray(stream);
                originalStream = (new MemoryStream(arrByte));
            }
        }
    }
    catch (Exception)
    {
        System.Diagnostics.Trace.WriteLine("Pipeline Disassemble Stage Exception");
        throw;
    }

    originalStream.Seek(0, SeekOrigin.Begin);
    msgPart.Data = originalStream;

    IBaseMessage outMsg = pInMsg;
    outMsg.BodyPart.Data = originalStream;

    // promote MessageType and Schema SchemaStrongName
    // in order to the Biztalk to have a unique key
    // for evaluating subscription
    // As an example for Namespace#Root= http://TestCustomPipeline.Schema1#roottagName
    // As an example for SchemaAssembly full name=
    // TestCustomPipeline.Schema1, TestCustomPipeline, 
    // Version=1.0.0.0, Culture=neutral, PublicKeyToken=f38e6d751bb874eb
    outMsg.Context.Promote("MessageType", 
      "http://schemas.microsoft.com/BizTalk/2003/system-properties",
      "Namespace#Root");
    outMsg.Context.Promote("SchemaStrongName", 
      "http://schemas.microsoft.com/BizTalk/2003/system-properties",
      "SchemaAssembly full name");

    qOutputMsgs.Enqueue(outMsg);

    System.Diagnostics.Trace.WriteLine("Pipeline Disassemble Stage Exit");
}

public IBaseMessage GetNext(IPipelineContext pContext)
{
    if (qOutputMsgs.Count > 0)
    {
        IBaseMessage msg = (IBaseMessage)qOutputMsgs.Dequeue();
        return msg;
    }
else
    return null;
}

#endregion

Usage in Visual Studio

Copy the DLL and paste it into (Windows installation directory):\Program Files\Microsoft BizTalk Server 2006\Pipeline Components. Now, insert the DLL into the GAC, open Visual Studio, right click on the Toolbox, click Select Items -> BizTalk Pipeline Components -> select your DLL -> OK. The assembler component will be added to the toolbox. Drag and drop it into the disassemble stage and have fun!!

History

  • Version 1.0.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Program Manager
Jordan Jordan
Self-motivated, creative and results-driven technology executive who is well versed and experienced in leveraging an end-to-end, holistic vision of business objectives to drive full technology / business alignment.

Skilled in grasping business needs and sudden market demand’s shifts by diving into latest business / technology trends, selecting the best fit business model / technology to create a positive reflection on revenue. His multifaceted approach has enabled him to deliver key solutions across a wide range of disciplines including design, development, UX / UI, Business Intelligence.

Technical Specialties are in .Net, Java, Spring Boot, Maven, MS SQL, Oracle, Postgesql, Redis, Javascript, Bootstrap, Angular 2.

Comments and Discussions

 
GeneralRe: Change incoming XML message in the pipeline Pin
sacpis29-Mar-11 2:03
sacpis29-Mar-11 2:03 
GeneralRe: Change incoming XML message in the pipeline Pin
Wael Al Wirr29-Mar-11 2:42
Wael Al Wirr29-Mar-11 2:42 
GeneralRe: Change incoming XML message in the pipeline Pin
sacpis29-Mar-11 5:34
sacpis29-Mar-11 5:34 
GeneralRe: Change incoming XML message in the pipeline Pin
Wael Al Wirr29-Mar-11 22:06
Wael Al Wirr29-Mar-11 22:06 
GeneralmsgPart i- what is its purpose? (cntrl+f)-> msgPart Pin
ssb5y210-Nov-10 13:10
ssb5y210-Nov-10 13:10 
GeneralMessage Closed Pin
11-Nov-10 0:04
Wael Al Wirr11-Nov-10 0:04 
GeneralRe: msgPart i- what is its purpose? (cntrl+f)-> msgPart Pin
ssb5y211-Nov-10 5:15
ssb5y211-Nov-10 5:15 
GeneralRe: msgPart i- what is its purpose? (cntrl+f)-> msgPart Pin
Wael Al Wirr7-Feb-11 21:45
Wael Al Wirr7-Feb-11 21:45 
Dear,
you can accoplish your requirement with out calling the getnet in decode since the decode stage, You can write a custom Disassemble pipeline Component. You will need to implement IDisaasembleComponent interface. Basic idea here is there are two methods Disassemble(......) and GetNext(). Disassemble will be called once, and GetNext(...) will be called several times till it does not return a "IBaseMessage". So one way is to populate a queue (Enqueue) in Disassemble(....) method and dequeue in GetNext(.....).
Regards,
Wael Al Wirr

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.