• TwitterFacebookGoogle PlusLinkedInRSS FeedEmail

Create Biztalk Pipeline Component

13.08.2019 
Create Biztalk Pipeline Component 7,1/10 3398 reviews

Receive and send pipelines in BizTalk are used to perform a range of processing and operations on messages. They can –



1.Encrypt and decrypt messages

Apr 01, 2011  To add the pipeline component to the Visual Studio toolbox, select ToolsChoose Toolbox Items. In the dialog box, select the BizTalk Pipeline Components tab, and then select the pipeline assembly created in step 4. The component should appear in your toolbox, as shown in Figure 2. Adding a custom pipeline component to the toolbox.


2.Sign and verify digitally signed messages


3.Validate message against schema


4.Deal with promoted properties used for content based routing


5.Disassemble or break single message into multiple


6.Wrap messages with header and footer



Pipelines contain stages and each stage can hold more than one pipeline component. Pipelines and pipeline components present out of box can do most of the tasks for you. But sometime specific message processing or massaging requirements encourage developers to develop custom pipeline components. Current series is focused on describing development of custom pipeline components.



There are multiple categories of pipeline components each doing specific job when employed on their predefined stages. These categories are –




Pipeline Components


Stages Employed


Tasks


General Component


Decode, Encode, Pre-assemble, Resolve Party or Validate


Take one message process message and produce zero or one message


Disassemble Component


Disassemble


Split message, promote custom properties


Assemble Component


Assemble


Used to wrap message with head or trailer or both


Probe Component


This is not an independent component. Any pipeline component can implement the IProbeMessage interface if it must support message probing functionality.


Enables the component to check the beginning part of the message



During development, each of these components implements particular interfaces and execute custom written job (code) on messages. I will walk through development of each of these components with sample code.



Developing General Pipeline Component


As stated earlier, pipeline components implement certain interfaces. General pipeline component implements following interfaces –



a.IBaseComponent Interface


b.IComponentUI Interface


c.IComponent Interface


d.IPersistPropertyBag (Optional. Required when pipeline design time properties are to be defined)



IBaseComponent Interface

Component

Genuine leather piano bench. All pipelines implement this interface. Interface provides members which can be implemented to provide information about pipeline.




Members


Usage


Description


Property. Used to specify small description about pipeline component. Description is visible on pipeline properties page at design time.


Name


Property used to specify name of pipeline component. Name is visible on pipeline properties page at design time.


Version


Property used to specify version (example 1.0.0.0) of pipeline component. Visible on pipeline properties page at design time.



IComponentUI Interface


All pipeline components must implement this interface. Members of this interface provide design time support.




Members


Usage


Icon


Property used to provide icon associated with pipeline component.


Validate


Method. This is called by pipeline designer before pipeline compilation to verify that all configuration properties are correctly set.



IComponent Interface


This is core interface. Member of this interface is implemented for specific message processing/massaging.




Members


Usage


Execute


Method. Does specific processing/massaging in inbound message and produces output message to be forwarded to next stages of pipeline or message box.



IPersistPropertyBag


Interface provides members which can be used to save and load pipeline design time properties with property bag. This interface is implemented only when pipeline’s design time properties are to be defined.




Members


Usage


GetClassID


Method. Retrieves the component's globally unique identifying value.


InitNew


Method. Initializes any objects needed by the component to use the persisted properties.


Load


Method. Used to load property from property bag.


Save


Method. Used to save property to property bag.



Enough theory. This is time for some coding.



Code Walk Though with Sample



I am going to create a sample general pipeline component. Scenario is very simple. Whenever, I receive a message, I want to change namespace of message in pipeline component. Namespace to be changed can be configured in design time property of pipeline.



If I get a message like following –



<Input xmlns:ns0='http://MyNamespace'>


<FirstName>Peter</FirstName>


<LastName>Decosta</LastName>


</Input>



And if changed namespace property is set to http://MyNewNamespace, then output message (which goes to next stages of pipeline and message box) would become –



<Input xmlns:ns0='http://MyNewNamespace'>


<FirstName>Peter</FirstName>


<LastName>Decosta</LastName>


</Input>



I am using VS 2005 for development.



1.Create a class library project say SampleGenPipelineComponent.proj. When project is created, rename Class1.cs to SampleGenComponent.cs.



2.Configure strong name key file in project property so that assembly can be signed.



3.Add following reference



Microsoft.BizTalk.Pipeline.dll



References can be found in folder “C:Program FilesMicrosoft BizTalk Server 2006” depending on location of BTS installation.



4.Add following namespaces.



using System.Xml;


using System.IO;


using Microsoft.BizTalk.Message.Interop;


using Microsoft.BizTalk.Component.Interop;



5.Implement following interfaces-



IBaseComponent,IComponentUI,IComponent, IPersistPropertyBag



6.Add following attributes to pipeline component class



[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]


[ComponentCategory(CategoryTypes.CATID_Decoder )]


[System.Runtime.InteropServices.Guid('9d0e4103-4cce-4536-83fa-4a5040674ad6')]


public class SampleGenComponent :


IBaseComponent,


IComponentUI,


IComponent,


IPersistPropertyBag



General components can be used in various stages – Decode, Encode, Validate etc.Component Category attribute is used to limit use of general pipeline to restricted stages. In my example, I am restricting my pipeline to be used in Decode stage only. This concept is called “Stage Affinity”. Please read following MSDN link to learn more about this –


http://msdn2.microsoft.com/en-us/library/ms964541.aspx



7.Implement members of IBaseComponent interface.



public string Description


{


get


{


return 'Pipeline component used to change namespace of message';


}


}


public string Name


{


get


{


return 'SampleGenPipelineComponent';


}


}


public string Version


{


get


{


return '1.0.0.0';


}


}



Member properties are overriden to provide description, name and version of pipeline component.



8.Implement members of IComponentUI interface.



public IntPtr Icon


{


get


{


return new System.IntPtr();


}


}



public System.Collections.IEnumerator Validate(object projectSystem)


{


return null;


}



I have kept things simple and have not provided any pipeline design time icon and validation logic. In actuall implementation, you can add an icon in piepline resouce file and point that in impelemtation. Similarily, you can also verify design time configuration/properties in Validate method and can return all inconsistancies in collection of errors.



9.Implement members of IPersistPropertyBag interface.




private string_NewNameSpace;


public string NewNameSpace


{


get { return _NewNameSpace; }


set { _NewNameSpace = value; }


}



public void GetClassID(out Guid classID)


{


classID = new Guid('655B591F-8994-4e52-8ECD-2D7E8E78B25C');

Create Biztalk Pipeline Components


}



public void InitNew()


{



}



public void Load(IPropertyBag propertyBag, int errorLog)


{


object val = null;


try


{


propertyBag.Read('NewNameSpace', out val, 0);


}


catch (Exception ex)


{


throw new ApplicationException('Error reading propertybag: ' + ex.Message);


}


if (val != null)


_NewNameSpace = (string)val;


else


_NewNameSpace = 'http://AnonymusURL';


}



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

Create Biztalk Pipeline Component Free


{


object val = (object)_NewNameSpace;


propertyBag.Write('NewNameSpace', ref val);


}



First of all, we created “NewNameSpace” property which is used to configure new namespace name at design time.



“Load” method loads value from property bag to pipeline property. “Save” method saves value to property bag from pipeline property. “GetClassID” returns component's unique identifying value in terms of GUID. “InitNew” is used to initialize object to be persisted in component properties. I have not implemented it because I don’t require.



10.Implement members of IComponent interface.



public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)


{


IBaseMessagePart bodyPart = pInMsg.BodyPart;


StringBuilder outputMessageText=null;

Component

string systemPropertiesNamespace = @'http://schemas.microsoft.com/BizTalk/2003/system-properties';


string messageType = ';



if (bodyPart != null)


{


Stream originalStream = bodyPart.GetOriginalDataStream();


if (originalStream != null)


{



XmlDocument xdoc = new XmlDocument();


xdoc.Load(originalStream);


XmlElement root = xdoc.DocumentElement;



messageType = this.NewNameSpace + '#' + root.Name;



outputMessageText = new StringBuilder();


outputMessageText.Append('<' + root.Name + 'xmlns:ns0=' + this.NewNameSpace + '>');


outputMessageText.Append(root.InnerXml);


outputMessageText.Append('</' + root.Name + '>');



byte[] outBytes = System.Text.Encoding.ASCII.GetBytes(outputMessageText.ToString());



MemoryStream memStream = new MemoryStream();


memStream.Write(outBytes, 0, outBytes.Length);


memStream.Position = 0;



bodyPart.Data = memStream;


pContext.ResourceTracker.AddResource(memStream);


}


}


pInMsg.Context.Promote('MessageType', systemPropertiesNamespace, messageType);


return pInMsg;


}



This is core of implementation. Code flow is –



-First read body part of message … = pInMsg.BodyPart;”



-Then read message content (XML) in stream “… = bodyPart.GetOriginalDataStream();”



-Change namespace of XML content “outputMessageText”



-Create a stream of new XML (with namespace)



-Assign stream back to message body part “bodyPart.Data = memStream;“



-Since namespace has changed, we need to update message type context property otherwise there is a fair chance of message routing failure. “pInMsg.Context.Promote('MessageType',…”. To understand importance of MessageType, please refer “Message Processing” section in link - http://msdn2.microsoft.com/en-us/library/ms935116.aspx



-Return message so that it can be consumed by next stages of pipeline and/or message box itself.



11.Coding is complete. Build the project.



Deploy Component and Use


To deploy pipeline component, Copy SampleGenPipelineComponent.dll to “C:Program FilesMicrosoft BizTalk Server 2006Pipeline Components”.


Pipeline component is now ready to use. In BTS receive pipeline project, add this pipeline component dll in toolbar and then use in decode stage. You will find that you can set value of “NewNameSpace” property at pipeline design time.


Summary


This was a sample general pipeline component which can be deployed to decode stage. Similarly, you can create other general pipeline components for requirement specific processing and data massaging. Hope this entry was useful. I am also attaching code zip file (SampleGenPipelineComponent.zip) for any further reference.


-->

A disassembling pipeline component receives one message on input and produces zero or more messages on output. Disassembling components are used to split interchanges of messages into individual documents. Disassembler components must implement the following interfaces:

  • IBaseComponent

  • IDisassemblerComponent

  • IComponentUI

  • IPersistPropertyBag . Refer to the .NET Framework SDK documentation for this interface.

    You can create your own disassembling component by extending the FFDasmComp or XMLDasmComp class.

Warning

If your custom disassembler will be setting the MessageDestination context property to SuspendQueue, the stream returned by the disassembler must to support Seek(0) for the suspension to work.

Note

Custom pipeline components should copy any additional parts from the input message to the output message(s). This preserves them for further processing in the pipeline.

In This Section