Unzip disassemble pipeline component in BizTalk Skip to main content

Unzip disassemble pipeline component in BizTalk

Hello everyone today I am going to write BizTalk custom pipeline code to unzip file and copy same zip file in local directory then after unzip xml files also route in BizTalk orchestration. There is also an advantage of using biztalk xlangs classes to use context promote value in expression shape of orchestration. In the last of this post you can download complete source code with an example.

Kindly follows are following steps to achieve to do process a zip file in biztalk orchestration using custom pipeline component-

Before follows all steps, please read- BizTalk Pipeline
1. Open Microsoft Visual Studio as Administrator user and Click File>New>Project… In Installed Templates click BizTalk Projects then Empty BizTalk Server Project and Name as “BizTalkLive.Unzip.Disassemble” and click OK.

2. Now leave every thing as it, we will do later, Now right click on your solution and a new C# class library project name as "BizTalkLive.UnZip" then rename class1 as "UnZip".

3. Add dll reference of Ionic for use unzip method in pipeline disassembler stage and also add reference Microsoft.BizTalk.Pipeline for use pipeline method. In the last of this post you are able to download Ionic.dll or It is open source library, download from some another website.
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
usig Ionic.Zip;

4. Now add following attribute and GUID (it is unique value of across network in the word) You can create your own unique GUID or use already that is already created, just click on Tools menu in VS then click on Create GUI, see the following picture-
namespace BizTalkLive.UnZip
{
    //Attributes of class
    [ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
    [ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]

    //Generate unique identifier
    [System.Runtime.InteropServices.Guid("F7EA6794-5E97-4E20-9C4B-EA9C3FD10FA9")]

5. Now use interface IBasecomponent, IComponentUI, IDisassemblerComponent, IPersistPropertyBag in UnZip class and also Create two string methods PropertyNamespace and ShemaMessageType respectively for add message type that use in xml file and PropertyNamespace of use promote context message. Both method are used in receive pipeline disassembler stage.

    public class UnZip : IBaseComponent, IComponentUI, IDisassemblerComponent, IPersistPropertyBag
    {
        private string _ShemaMessageType;
        private string _PropertyNamespace;
        public string ShemaMessageType
        {
            get
            {
                return _ShemaMessageType;
            }
            set
            {
                _ShemaMessageType = value;
            }
        }

6. As I understand that you know basic concept of IBasecomponent, IComponentUI, IDisassemblerComponent, IPersistPropertyBag so now come to final point IDisassemblerComponent stage.

public void Disassemble(IPipelineContext pc, IBaseMessage inmsg)
        {
            //Microsoft.BizTalk.CAT.BestPractices.Framework.Instrumentation.TraceManager.WorkflowComponent.TraceInfo("TSAUnZipDecode : Unzip process has started at " + DateTime.Now.ToLongDateString());
            Byte[] TextFileBytes = null;
            string FileStatus = "0";
            string extension = "";
            string strReceivePortName = "";
            string strReceivedFileName = "";
            string _filename = "";

            IBaseMessagePart msgBodyPart1 = inmsg.BodyPart;

            Stream msgBodyPartStream1 = msgBodyPart1.GetOriginalDataStream();

            MemoryStream memStream1 = new MemoryStream();
            byte[] buffer1 = new Byte[1024];

            int bytesRead1 = 1024;
            while (bytesRead1 != 0)
            {
                bytesRead1 = msgBodyPartStream1.Read(buffer1, 0, buffer1.Length);
                memStream1.Write(buffer1, 0, bytesRead1);
            }

            IBaseMessage outMessage1;
            outMessage1 = pc.GetMessageFactory().CreateMessage();
            outMessage1.AddPart("Body", pc.GetMessageFactory().CreateMessagePart(), true);
            memStream1.Position = 0L;
            outMessage1.BodyPart.Data = memStream1;
            if (this.ShemaMessageType != null)
            {
                outMessage1.Context.Promote("MessageType", "http://schemas.microsoft.com/BizTalk/2003/system-properties", this.ShemaMessageType);

            }
            outMessage1.Context.Promote("FileExtension", PropertyNamespace, ".zip");

            IBaseMessageContext context = inmsg.Context;
            strReceivePortName = context.Read("ReceivePortName", "http://schemas.microsoft.com/BizTalk/2003/system-properties").ToString();
            strReceivedFileName = context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties").ToString();
            strReceivedFileName = strReceivedFileName.Substring(strReceivedFileName.LastIndexOf("\\") + 1);
            strReceivedFileName = ((string)strReceivedFileName).Replace(".zip", "");
            outMessage1.Context.Promote("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties", strReceivedFileName);
            outMessage1.Context.Promote("ReceivePortName", "http://schemas.microsoft.com/BizTalk/2003/system-properties", strReceivePortName);

            //outMessage1.Context = PipelineUtil.CloneMessageContext(inmsg.Context);

            OutFiles.Enqueue(outMessage1);

In above code I am using IBaseMessage and IBaseMessageContext interface try to get receive port name and received file name and also add original zip message in Enqueue method of System.Collections.Queue then promote message context FileExtension and MessageType. Basically I am try to store my original zip file in my local folder with help of message routing.
 
7. Continue following code in  Disassemble method to unzip zip file and enqueue xml file in
System.Collections.Queue and also promote message type of xml and some property promotion value too so that we can use it in expression shape of orchestration.

IBaseMessagePart msgBodyPart_XML = inmsg.BodyPart;

            IBaseMessage outMessage;

            if (msgBodyPart_XML != null)
            {
                Stream msgBodyPartStream = msgBodyPart_XML.GetOriginalDataStream();
                msgBodyPartStream.Position = 0L;

                if (msgBodyPartStream != null)
                {
                    using (ZipInputStream zipInputStream = new ZipInputStream(msgBodyPartStream))
                    {
                        ZipEntry entry = zipInputStream.GetNextEntry();
                        while (entry != null)
                        {
                            Stream memStream = new MemoryStream();
                            byte[] buffer = new Byte[4096];

                            int bytesRead = 4096;
                            while (bytesRead != 0)
                            {
                                bytesRead = zipInputStream.Read(buffer, 0, buffer.Length);
                                memStream.Write(buffer, 0, bytesRead);
                            }

                            //Creating custom context property to hold extension of file
                            extension = entry.FileName.Substring(entry.FileName.IndexOf(".")).ToUpper();
                            _filename = entry.FileName.ToString();

                            if (extension == ".XML")
                            {
                                FileStatus = "1";
                                outMessage = pc.GetMessageFactory().CreateMessage();
                                outMessage.AddPart("Body", pc.GetMessageFactory().CreateMessagePart(), true);
                                memStream.Position = 0L;
                                outMessage.BodyPart.Data = memStream;

                                outMessage.Context = PipelineUtil.CloneMessageContext(inmsg.Context);
                                if (this.ShemaMessageType != null)
                                {
                                    outMessage.Context.Promote("MessageType", "http://schemas.microsoft.com/BizTalk/2003/system-properties", this.ShemaMessageType);

                                }
                                _filename = ((string)_filename).Replace(".xml", "");
                                outMessage.Context.Promote("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties", _filename);
                                outMessage.Context.Promote("FileStatus", PropertyNamespace, FileStatus.ToString());
                                outMessage.Context.Promote("FileExtension", PropertyNamespace, extension.ToLower());

                                OutFiles.Enqueue(outMessage);

                            }
                            else
                            {
                                FileStatus = "0";
                                //outMessage.Context.Promote("FileStatus", PropertyNamespace, FileStatus.ToString());
                                //outMessage.Context.Promote("FileExtension", PropertyNamespace, extension.ToLower());
                            }

                            entry = zipInputStream.GetNextEntry();
                        }

                    }

                }

            }
        }

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

In above code there is IBaseMessage method GetNext() that Dequeue all message one by one in pipeline so that we can easily route this message either in orchestration or direct in send port.

8. In the last right click on same project BizTalkLive.UnZip then click on Property after click on sign tag and then add new strong name file. Now right click same project and build it.

9. Now go to folder location and go to bin\Debug and installed Ionic and UnZip dll in gac. You can reference how to install dll in gac - Install DLL into GAC

10. Move next step and right click solution of same project and add new class library of C# as name "BizTalkLive.ContextPropertyAccessor" that do to call property promoted value in biztalk orchestration expression shape. See the following code then build this project and finally installed dll in gac.
using Microsoft.XLANGs.BaseTypes;
using Microsoft.XLANGs.Core;
using System;
using System.Collections;

namespace BizTalkLive.ContextPropertyAccessor
{
    public class ContextAccessor
    {
        public static Hashtable GetContext(XLANGMessage message)
        {
            try
            {
                foreach (Segment segment in Service.RootService._segments)
                {
                    IDictionary fields =
                        Context.FindFields(
                          typeof(XLANGMessage)
                        , segment.ExceptionContext);

                    foreach (DictionaryEntry field in fields)
                    {
                        XMessage msg = (field.Value as XMessage);
                        if (msg == null)
                            continue;

                        if (String.Compare(msg.Name, message.Name) != 0)
                            continue;


                        return msg.GetContextProperties();
                    }
                }
            }
            catch (Exception ex)
            {
                // do not provoke failure
                throw ex;
            }

            return new Hashtable();
        }

        public static string GetContextProperty(XLANGMessage message, string PropertyName, string PropertyNamespace)
        {
            string Property = "False";
            try
            {

                Microsoft.XLANGs.BaseTypes.XmlQName qname = new XmlQName(PropertyName, PropertyNamespace);
                foreach (Segment segment in Service.RootService._segments)
                {
                    IDictionary fields =
                        Context.FindFields(
                          typeof(XLANGMessage)
                        , segment.ExceptionContext);

                    foreach (DictionaryEntry field in fields)
                    {
                        XMessage msg = (field.Value as XMessage);
                        if (msg == null)
                            continue;

                        if (String.Compare(msg.Name, message.Name) != 0)
                            continue;

                        if (msg.GetContextProperties().ContainsKey(qname))
                        {
                            // get the property from GetContextProperties
                            Property = msg.GetContextProperties()[qname].ToString();
                        }
                        else if (msg.GetContentProperties().ContainsKey(qname))
                        {
                            // get the property from GetContentProperties
                            Property = msg.GetContentProperties()[qname].ToString();
                        }

                        return Property;

                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
                // do not provoke failure
                // probably best to add some logging here
            }

            return Property;
        }
    }
}

11. Now reference both dll i.e. BizTalkLive.UnZip and BizTalkLive.ContextPropertyAccessor in biztalk project "BizTalkLive.Unzip.Disassemble", see the following image-


12. Add new receive pipeline name as "Rcv_UnZipDisassemble" now Click on toolbox of receive pipeline and then right click and click choose items.. and select BizTalk Pipeline Component tag and click Browse.. button from right side of bottom and select BizTalkLive.UnZip.dll from the already installed gac assembly. Now a new toolbox added in pipeline toolbox name as unzip_Disassembler then select it and place on disassemble stage and also after add XML disassembler.

13. Now add two schema one property schema and one schema for xml file that unzip from zip file, Please see the following picture and also you can download complete source in the last of this post so that you can easily create both schemas.
 

14. Now see the following below picture its show how I will design orchestration flow, firstly message come from receive location using custom unzip receive pipeline then I am using a expression shape where i get filestatus value by using xlangs context message promote schema property. In the last configure port, configure logical file port to send xml file in local directory.


15. In the last part of biztalk project unzip custom pipeline disassembler, right click on solution and set same name of biztalk project as it solution name and again right click on solution and deployed it. Now create receive port then create receive location and select receive pipeline set two disassemble component i.e. one is property schema's target namespace and for 2nd one message type of xml schema that use in xml files are zipped. see the following image-

16. Now create two send port one for route same zip file to local directory by using filter condition that I have promoted in UnZip disassemble method i.e. file extension a d receive port and second send port use to copy all xml files in local folder. Please see the following picture-

To download Ionic dll please click this link -  Downlaod Ionic Dll
To download complete project source code please click this link -  Download Source Code 

!! Keep Visiting BizTalkLive !!

Comments

Post a Comment

Please write comment only that belongs to this blog

Popular posts from this blog

BizTalk Interview Question and Answer

1. What is BizTalk? BizTalk is a middleware that sits in the middle of any two software who wish to communicate with each other and agree on some specified communication pattern. It uses SQL Server as back end database. “Microsoft BizTalk Server is an Inter-Organizational Middleware System (IOMS) that enables companies to automate business processes, through the use of adapters which are tailored to communicate with different software systems used in an enterprise. Created by Microsoft, it provides enterprise application integration, business process automation, business-to-business communication, message broker and business activity monitoring.”                 2. What is BizTalk Server Architecture and Life Cycle of Message? BizTalk Server Architecture: Life Cycle of Message: In this simplified view, a message is received through a receive location defined...

Configuring BizTalk WCF Timeout Values on a Binding

There are a number of timeout settings available in WCF bindings. Setting these timeout settings correctly can improve not only your service’s performance but also play a role in the usability and security of your service. The following timeouts are available on WCF bindings: OpenTimeout CloseTimeout SendTimeout ReceiveTimeout Open Timeout :  This property represents the amount of time a channel open operation has to complete. Send Timeout :  Use this property to set the amount of time that a send operation has to complete. When used as part of a solicit-response scenario, this value encompasses the total amount of time for the interaction to complete. If we are sending a large message, we may need to increase this timeout to allow for the request and response messages to be processed within this window. Close Timeout :  A time-stamp that is used to indicate the amount Receive Timeout :  Used by the Service Framework Layer to initialize the...

PowerShell Script to enable BizTalk Receive Location

We are facing problem in BizTalk server 2016 that few of running SFTP Receive location would be stopped after some time due to sftp connectivity issue of their threshold so I am going to share PowerShell script to enable receive location by window task scheduler. Before execute following script Please do following task a. Set Server name in ConnectionString b. Set ( $hostname) host name value that is using in SFTP Receive location c. Set ( $rcvLocation) Receive location name # Import external assembly and create a new object [ void ] [ System.reflection.Assembly ]:: LoadWithPartialName( "Microsoft.BizTalk.ExplorerOM" ) $Catalog = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer   #BizTalk Config $Catalog . ConnectionString = "SERVER=.;DATABASE=BizTalkMgmtDb;Integrated Security=SSPI"   #connectionstring for the BizTalkMgmtDb $hostname = "BizTalkServerApplication" #hostname $rcvLocation = "RL_GetAccReq_SQL...

Publish a web service in biztalk using BizTalk WCF Service Publishing Wizard

Welcome you again in my Blog and let us do another mind blowing achievement that how to publish a WCF web service in BizTalk and as in previous post to Complete BizTalk project to host Schema as Web Service  so If you want to expose/publish a web service, you should run through the BizTalk WCF Service Publishing Wizard. This wizard guides you through choosing what you want to expose as a web service. This section walks you through the wizard step by step to publish WCF Web Service using  WCF-WSHttp- Step-1:  To start the wizard, go to Start, All Programs, Microsoft BizTalk Server 2016(version), BizTalk WCF Service Publishing Wizard. This fires up a welcoming screen, on which you just click Next. Consider disabling the welcoming screen for the future by checking the check box at the bottom. You will now see the screen shown in above figure. Step-2: Choose the Service Endpoint option, and choose which adapter to use. Check Enable Metadata Endpoint if you wa...

Step by step solution of BizTalk Two-Way WCF-SQL XmlPolling in Send Port

I am going to share most awaited Two way WCF_SQL Two Way XmlPolling so that you can easily enhance your old SQL procedure and BizTalk Map without any big change. I know there is no content available in any website to how work with XmlPolling in WCF-SQL two-way adapter. In the last of this post you can download complete source code with an example. Please follow carefully all steps – 1. Open Microsoft Visual Studio as Administrator user and Click File>New>Project… In Installed Templates click BizTalk Projects then Empty BizTalk Server Project and Name as “BizTalkLive-WCF-SQL” and click OK. 2. Now see the below picture and create all respective folders separately for Schema, Map, Orchestration, Pipeline, Binding- 3. Create Schemas in Schema folder as shown below picture to get Account request using One Way WCF-SQL XmlPolling a) Create Envelope Schema first with Target NameSpace - http://BizTalkLive_WCF_SQL.AccountRequest b) Create Second Sch...