none
Decrypt and unzip a File + read a XML file received into the ZIP RRS feed

  • Question

  • Hello,

    I need your help to develop some a complex Biztalk application.

    Here're my needs :

    Our Busness partner send us a zip file cripted with a standard PGP(Pretty Goof Privacy).

    The zip containts an XML file that i have to deal it, and some attachments file(PDF).

    So i need to know what's the best approach for the developpement of my application.

    I want to decrypt the ZIP and then Unzip the file and them read the XML file received in the zip.

    Knowimg that we already have the pipeline compenent to dectypt the file with the strandar PGP and an other pipeline compenent to unzip the File.

    Thank you

    

    Monday, November 3, 2014 3:08 PM

Answers

All replies

  • Hi ,

    Try this code to unzip the file and send the xml message .If u face issue let me know

    namespace BizTalk.Pipeline.Component.DisUnzip
    {
        using System;
        using System.IO;
        using System.Text;
        using System.Drawing;
        using System.Resources;
        using System.Reflection;
        using System.Diagnostics;
        using System.Collections;
        using System.ComponentModel;
        using Microsoft.BizTalk.Message.Interop;
        using Microsoft.BizTalk.Component.Interop;
        using Microsoft.BizTalk.Component;
        using Microsoft.BizTalk.Messaging;
        using Ionic.Zip;
        using System.IO.Compression;
        
        
        [ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
        [System.Runtime.InteropServices.Guid("8bef7aa9-5da5-4d62-ac5b-03af2fb9d280")]
        [ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]
        public class DisUnzip : Microsoft.BizTalk.Component.Interop.IDisassemblerComponent, IBaseComponent, IPersistPropertyBag, IComponentUI
        {
            
            private System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager("BizTalk.Pipeline.Component.DisUnzip.DisUnzip", Assembly.GetExecutingAssembly());
            
            #region IBaseComponent members
            /// <summary>
            /// Name of the component
            /// </summary>
            [Browsable(false)]
            public string Name
            {
                get
                {
                    return resourceManager.GetString("COMPONENTNAME", System.Globalization.CultureInfo.InvariantCulture);
                }
            }
            
            /// <summary>
            /// Version of the component
            /// </summary>
            [Browsable(false)]
            public string Version
            {
                get
                {
                    return resourceManager.GetString("COMPONENTVERSION", System.Globalization.CultureInfo.InvariantCulture);
                }
            }
            
            /// <summary>
            /// Description of the component
            /// </summary>
            [Browsable(false)]
            public string Description
            {
                get
                {
                    return resourceManager.GetString("COMPONENTDESCRIPTION", System.Globalization.CultureInfo.InvariantCulture);
                }
            }
            #endregion
            
            #region IPersistPropertyBag members
            /// <summary>
            /// Gets class ID of component for usage from unmanaged code.
            /// </summary>
            /// <param name="classid">
            /// Class ID of the component
            /// </param>
            public void GetClassID(out System.Guid classid)
            {
                classid = new System.Guid("8bef7aa9-5da5-4d62-ac5b-03af2fb9d280");
            }
            
            /// <summary>
            /// not implemented
            /// </summary>
            public void InitNew()
            {
            }
            
            /// <summary>
            /// Loads configuration properties for the component
            /// </summary>
            /// <param name="pb">Configuration property bag</param>
            /// <param name="errlog">Error status</param>
            public virtual void Load(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, int errlog)
            {
            }
            
            /// <summary>
            /// Saves the current component configuration into the property bag
            /// </summary>
            /// <param name="pb">Configuration property bag</param>
            /// <param name="fClearDirty">not used</param>
            /// <param name="fSaveAllProperties">not used</param>
            public virtual void Save(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, bool fClearDirty, bool fSaveAllProperties)
            {
            }
            
            #region utility functionality
            /// <summary>
            /// Reads property value from property bag
            /// </summary>
            /// <param name="pb">Property bag</param>
            /// <param name="propName">Name of property</param>
            /// <returns>Value of the property</returns>
            private object ReadPropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName)
            {
                object val = null;
                try
                {
                    pb.Read(propName, out val, 0);
                }
                catch (System.ArgumentException )
                {
                    return val;
                }
                catch (System.Exception e)
                {
                    throw new System.ApplicationException(e.Message);
                }
                return val;
            }
            
            /// <summary>
            /// Writes property values into a property bag.
            /// </summary>
            /// <param name="pb">Property bag.</param>
            /// <param name="propName">Name of property.</param>
            /// <param name="val">Value of property.</param>
            private void WritePropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName, object val)
            {
                try
                {
                    pb.Write(propName, ref val);
                }
                catch (System.Exception e)
                {
                    throw new System.ApplicationException(e.Message);
                }
            }
            #endregion
            #endregion
            
            #region IComponentUI members
            /// <summary>
            /// Component icon to use in BizTalk Editor
            /// </summary>
            [Browsable(false)]
            public IntPtr Icon
            {
                get
                {
                    return ((System.Drawing.Bitmap)(this.resourceManager.GetObject("COMPONENTICON", System.Globalization.CultureInfo.InvariantCulture))).GetHicon();
                }
            }
            
            /// <summary>
            /// The Validate method is called by the BizTalk Editor during the build 
            /// of a BizTalk project.
            /// </summary>
            /// <param name="obj">An Object containing the configuration properties.</param>
            /// <returns>The IEnumerator enables the caller to enumerate through a collection of strings containing error messages. These error messages appear as compiler error messages. To report successful property validation, the method should return an empty enumerator.</returns>
            public System.Collections.IEnumerator Validate(object obj)
            {
                // example implementation:
                // ArrayList errorList = new ArrayList();
                // errorList.Add("This is a compiler error");
                // return errorList.GetEnumerator();
                return null;
            }
            #endregion
            
            /// <summary>
            /// this variable will contain any message generated by the Disassemble method
            /// </summary>
            private System.Collections.Queue _msgs = new System.Collections.Queue();
            
            #region IDisassemblerComponent members
            /// <summary>
            /// called by the messaging engine until returned null, after disassemble has been called
            /// </summary>
            /// <param name="pc">the pipeline context</param>
            /// <returns>an IBaseMessage instance representing the message created</returns>
            public Microsoft.BizTalk.Message.Interop.IBaseMessage 
                GetNext(Microsoft.BizTalk.Component.Interop.IPipelineContext pc)
            {
               
                // get the next message from the Queue and return it
                Microsoft.BizTalk.Message.Interop.IBaseMessage msg = null;
                if ((_msgs.Count > 0))
                {
                    msg = ((Microsoft.BizTalk.Message.Interop.IBaseMessage)(_msgs.Dequeue()));
                }
                return msg;
            }
            
            /// <summary>
            /// called by the messaging engine when a new message arrives
            /// </summary>
            /// <param name="pc">the pipeline context</param>
            /// <param name="inmsg">the actual message</param>
            public void Disassemble(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
            {
                IBaseMessage Temp = inmsg;
                using (ZipFile zip = ZipFile.Read(inmsg.BodyPart.GetOriginalDataStream()))
                {
                    foreach (ZipEntry e in zip)
                    {
                        var ms = new MemoryStream();
                        IBaseMessage outMsg;
                        outMsg = pc.GetMessageFactory().CreateMessage();
                        outMsg.AddPart("Body", pc.GetMessageFactory().CreateMessagePart(), true);
                        outMsg.Context=inmsg.Context;
    
                        e.Extract(ms);
                        string XMLMessage = Encoding.UTF8.GetString(ms.ToArray()); 
                                        
                        MemoryStream mstemp = new System.IO.MemoryStream(
                        System.Text.Encoding.UTF8.GetBytes(XMLMessage));
    
                        outMsg.GetPart("Body").Data = mstemp;                                     
    
                        _msgs.Enqueue(outMsg);    
                    }
                }
            }
    
           
            #endregion
        }
    }
    

    Thanks

    Abhishek

    Monday, November 3, 2014 4:26 PM
  • Don't worry too much, this can be a pretty simple implementation.

    Your Pipeline might consist of:

    PGP Component: https://code.msdn.microsoft.com/windowsdesktop/BizTalk-Sample-PGP-ebcbc8b2

    Unzip Component: https://code.msdn.microsoft.com/BizTalk-Pipeline-Custom-0c8b1487

    That particular unzip component is a Disassembler so all parts of the Zip stream will appear as separate messages which you can correlate on BTS.InterchangeID.

    Monday, November 3, 2014 4:52 PM
    Moderator
  • Hi Abhishek,

    Thank's for your reply,

    I don't understand what do you mean by "All parts of the zip stream will appear as separate messages which ..".

    After the unzip, how can i get juste the XML file into my orchestration ?

    Thanks

    Monday, November 3, 2014 5:02 PM
  • I want to unzip the forder and creat just one message for the xml file and not for all files(PDF) in the forder
    Monday, November 3, 2014 5:16 PM
  • Hi Abhishek,...I don't understand what do you mean by "All parts of the zip stream will appear as separate messages which ..".

    Who are you asking, that was my reply?

    Either way, if you just want the xml content, then in the loop where the zipped streams are extracted (this applies to any implementation), you would have to test for the xml content (since there's no way to know the order they appear in the zip) and create a Message only for that particular stream.


    Monday, November 3, 2014 6:50 PM
    Moderator
  • I want to unzip all files in the zip but creat juste one message for xml file.

    (The zip contains 1 xml file and n pdf file)

    Monday, November 3, 2014 7:07 PM
  • Sotty Johns, i reply was for you, sorry
    Monday, November 3, 2014 7:08 PM
  • Hi Hicham,

    From what I understand, you are receiving zipped file with one xml and n number of pdf file and you want to use only the xml file - It is simple, you just need to have a custom disassembler component which will unzip the zipped message and drop the unzipped messages in message box . Then after you can subscribe to the file you are interested in by applying filter on sendport or configuring the first receive shape of orchestration.

    I have an article around this, go through it and understand the process : BizTalk Server 2010: Processing Zip Message Having Multiple Type Files and code sample .

    ___________________________________

    Maheshkumar S Tiwari|User Page|Blog|BizTalk Server : Fetching UNB and UNG Segment Values From Interchange Envelope and Mapping

    • Marked as answer by Angie Xu Thursday, November 13, 2014 5:26 AM
    Tuesday, November 4, 2014 5:23 AM