BizTalk : Clone Message Disassembler Pipeline Component

A custom disassembler to clone inbound messages.

To run the sample create a class library with references to,

  • Microsoft.BizTalk.Pipeline.dll
  • Microsoft.BizTalk.Streaming.dll
  • Microsoft.XLANGs.BaseTypes.dll

Sign, compile, and gac the class library with the below code.  Note how the message is being cloned and added to the queue.

using System;
using System.IO;
using System.Xml;
using System.Linq;
using System.Resources;
using System.Reflection;
using System.Collections;
using System.Diagnostics;
using System.Globalization;
using System.ComponentModel;
using System.Collections.Generic;
using Microsoft.BizTalk.Streaming;
using System.Runtime.InteropServices;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;

namespace PipelineComponents
{
    [ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
    [System.Runtime.InteropServices.Guid("eeff154c-e26b-8888-6666-bfccc0eb3448")]
    [ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]
    public class ClonePipelineComponent : Microsoft.BizTalk.Component.Interop.IDisassemblerComponent, IBaseComponent, IPersistPropertyBag, IComponentUI
    {
        #region Variables

        System.Collections.Queue queueOutMsgs = new System.Collections.Queue();

        #endregion

        #region IPersistPropertyBag

        public void GetClassID(out Guid classID)
        {
            classID = new Guid("eeff154c-e26b-8888-6666-bfccc0eb3448");
        }

        public void InitNew()
        {

        }

        IEnumerator IComponentUI.Validate(object projectSystem)
        {
            return new ArrayList(0).GetEnumerator();
        }

        public void Load(IPropertyBag propertyBag, int errorLog)
        {
            
        }

        public void Save(IPropertyBag propertyBag, bool clearDirty, bool saveAllProperties)
        {
            
        }

        #endregion

        #region IDisassemblerComponent Members

        public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
        {
            Stream inMsgStream = pInMsg.BodyPart.GetOriginalDataStream();

            if (!inMsgStream.CanSeek)
            {
                ReadOnlySeekableStream seekableStream = new ReadOnlySeekableStream(inMsgStream);
                pContext.ResourceTracker.AddResource(seekableStream);
                inMsgStream = seekableStream;
            }

            // Hardcoded here for sample.  Add this as a BRE rule or pipeline component property
            int numberOfClones = 2;

            for(int i=0; i <= numberOfClones; i++)
            {
                inMsgStream.Seek(0, SeekOrigin.Begin);

                // Clone the input message
                IBaseMessage outMsg;

                outMsg = pContext.GetMessageFactory().CreateMessage();
                outMsg.AddPart("Body", pContext.GetMessageFactory().CreateMessagePart(), true);
                outMsg.BodyPart.Data = inMsgStream;
                outMsg.Context = PipelineUtil.CloneMessageContext(pInMsg.Context);

                string contextPropertyValue = "YourSampleContextPropertyValue";

                // Promote or write any context properties here
                outMsg.Context.Promote("YourContextPropertyName", "http://YourContextPropertyNamespace", contextPropertyValue);

                // Add cloned messages to the queue
                queueOutMsgs.Enqueue(outMsg);
            }
        }

        public IBaseMessage GetNext(IPipelineContext pContext)
        {
            if (queueOutMsgs.Count > 0)
            {
                IBaseMessage outMsg = (IBaseMessage)queueOutMsgs.Dequeue();

                Stream stream = outMsg.BodyPart.GetOriginalDataStream();
 
                if (!stream.CanSeek)
                {
                    ReadOnlySeekableStream seekableStream = new ReadOnlySeekableStream(stream);
                    pContext.ResourceTracker.AddResource(seekableStream);
                    stream = seekableStream;
                }
 
                stream.Seek(0, SeekOrigin.Begin);

                return outMsg;
            }
            else
                return null;
        }

        #endregion

        #region IComponentUI Properties

        [Browsable(false)]
        public string Description
        {
            get
            {
                return "Clone Pipeline Component";
            }
        }

        [Browsable(false)]
        IntPtr IComponentUI.Icon
        {
            get
            {
                return IntPtr.Zero;
            }
        }

        [Browsable(false)]
        public string Name
        {
            get
            {
                return "Clone Pipeline Component";
            }
        }

        [Browsable(false)]
        public string Version
        {
            get
            {
                return Assembly.GetExecutingAssembly().GetName().Version.ToString(2);
            }
        }

        #endregion

    }
}
Advertisements
This entry was posted in BizTalk Server. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s