Advertisement
Guest User

BizTalk Custom Pipeline Disassembler for Debugging

a guest
Jun 14th, 2012
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. using System.Xml;
  7. using Microsoft.BizTalk.Message.Interop;
  8. using Microsoft.BizTalk.Component.Interop;
  9.  
  10. namespace Delta.Import.PipelineComponents
  11. {
  12.  
  13.  
  14. [ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
  15. [ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]
  16. //[System.Runtime.InteropServices.Guid("57D51828-C973-4a62-A534-6DB3CB3CB251")]
  17. [System.Runtime.InteropServices.Guid("6118B8F0-8684-4ba2-87B4-8336D70BD4F7")]
  18. public class FPES2Custom3DayDisassembler :
  19.                 IBaseComponent,
  20.                 IComponentUI,
  21.                 IDisassemblerComponent,
  22.                 IPersistPropertyBag
  23. {
  24.  
  25. #region Private Members
  26.     System.Collections.Queue qOutputMsgs = new System.Collections.Queue();
  27.     IBaseMessagePart msgPart;
  28.     string textProperty = string.Empty;
  29.     private string systemPropertiesNamespace = @"http://schemas.microsoft.com/BizTalk/2003/system-properties";
  30.  
  31.  
  32. #endregion
  33.  
  34. #region PropertyBagVariables
  35.     public string _rootNodeName;
  36.     public string _debugLevel;
  37. #endregion
  38.  
  39. #region PropertyBagProperties
  40.     public string DefaultTargetNamespace
  41. {
  42.     get { return _rootNodeName; }
  43.     set { _rootNodeName = value; }
  44. }
  45.  
  46. /// <summary>
  47. /// Debug Parm to allow BizTalk Admin to turn it on/off from BizTalk Admin Console
  48. /// </summary> 
  49. public string DebugLevel
  50. {
  51.     get { return _debugLevel; }
  52.     set
  53.     {
  54.         // Setup to allow for None, Informational, Warning, Error, Verbose in the future.
  55.         if (value == "OFF" || value == "NONE")
  56.         {
  57.             DebugLevel = "";
  58.         }
  59.         else
  60.         {
  61.             DebugLevel = value.ToUpper();
  62.         }
  63.     }
  64. }
  65. #endregion
  66.  
  67. #region IBaseComponent Members
  68.  
  69. public string Description
  70.     {
  71.         get { return "FPES2 - Custom 3Day Disassembler"; }
  72.     }
  73.  
  74.     public string Name
  75.     {
  76.         get { return "FPES2Custom3DayDisassembler"; }
  77.     }
  78.  
  79.     public string Version
  80.     {
  81.         get { return "1.0.0.0"; }
  82.     }
  83.  
  84. #endregion
  85.  
  86.  
  87. #region IPersistPropertyBag Members
  88.  
  89.     public void GetClassID(out Guid classID)
  90.     {
  91.         classID = new Guid("25984614-BCFD-4c47-82FC-4A2300B76438");
  92.     }
  93.  
  94.     public void InitNew()
  95.     {
  96.     }
  97.  
  98.     public void Load(IPropertyBag propertyBag, int errorLog)
  99.     {
  100.         object val = ReadPropertyBag(propertyBag, "RootNodeName");
  101.         if (val != null)
  102.             _rootNodeName = (string)val;
  103.  
  104.         object val2 = ReadPropertyBag(propertyBag, "DebugLevel");
  105.         if (val2 != null)
  106.             _debugLevel = (string)val2;
  107.     }
  108.  
  109.     public void Save(IPropertyBag propertyBag, bool clearDirty,
  110.                      bool saveAllProperties)
  111.     {
  112.         propertyBag.Write("RootNodeName", _rootNodeName);
  113.         propertyBag.Write("DebugLevel", _debugLevel);
  114.     }
  115.  
  116. #endregion
  117.  
  118. #region PropertyBagHelpers
  119.         /// <summary>
  120.         /// Reads property value from property bag.
  121.         /// </summary>
  122.         /// <param name="pb">Property bag.</param>
  123.         /// <param name="propName">Name of property.</param>
  124.         /// <returns>Value of the property.</returns>
  125.         private static object ReadPropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName)
  126.         {
  127.             object val = null;
  128.             try
  129.             {
  130.                 pb.Read(propName, out val, 0);
  131.             }
  132.             catch (ArgumentException)
  133.             {
  134.                 //Do not bother about this
  135.             }
  136.             catch (Exception ex)
  137.             {
  138.                 string errorMsg = "Error in ReadPropertyBag: " + ex.Message;
  139.                 System.Diagnostics.EventLog.WriteEntry("PipelineComponent", errorMsg);
  140.                 throw new ApplicationException(errorMsg);
  141.             }
  142.             return val;
  143.         }
  144.  
  145.         /// <summary>
  146.         /// Writes property values into a property bag.
  147.         /// </summary>
  148.         /// <param name="pb">Property bag.</param>
  149.         /// <param name="propName">Name of property.</param>
  150.         /// <param name="val">Value of property.</param>
  151.         private static void WritePropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName, object val)
  152.         {
  153.             try
  154.             {
  155.                 pb.Write(propName, ref val);
  156.             }
  157.             catch (Exception ex)
  158.             {
  159.                 string errorMsg = "Error in WritePropertyBag2: " + ex.Message;
  160.                 System.Diagnostics.EventLog.WriteEntry("PipelineComponent", errorMsg);
  161.                 throw new ApplicationException(errorMsg);
  162.             }
  163.         }
  164. #endregion
  165.  
  166.  
  167. #region IComponentUI Members
  168.  
  169.     public IntPtr Icon
  170.     {
  171.         get { return System.IntPtr.Zero; }
  172.     }
  173.  
  174.     public System.Collections.IEnumerator Validate(object projectSystem)
  175.     {
  176.         return null;
  177.     }
  178.  
  179. #endregion
  180.  
  181. #region IDisassemblerComponent Members
  182.  
  183.     public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
  184.     {
  185.         string trcSource = "DeltaPipeline:SetNSForFPES2Msg";
  186.         string trcCorrId = pInMsg.Context.Read("InterchangeID", "http://schemas.microsoft.com/BizTalk/2003/system-properties").ToString();
  187.         // database size in trace is varchar(36), so we don't want the curly braces in the GUID
  188.         trcCorrId = trcCorrId.Replace("{", "");
  189.         trcCorrId = trcCorrId.Replace("}", "");
  190.         string trcGUID = trcCorrId;
  191.         string strTraceMessage = null;
  192.  
  193.         string trcCode = "0100";
  194.         strTraceMessage = "Start Debatcher _debugLevel=" + _debugLevel;
  195.         Shared.Utility.Log.WriteEntryConditional(
  196.            System.Diagnostics.TraceLevel.Info,
  197.            trcSource, trcGUID, trcCode, strTraceMessage,
  198.            null, trcCorrId);
  199.  
  200.  
  201.         System.Diagnostics.Trace.WriteLine("Pipeline Disassemble Stage Enter");
  202.         msgPart = pInMsg.BodyPart;
  203.         Stream originalStream = pInMsg.BodyPart.GetOriginalDataStream();
  204.         try
  205.         {
  206.             if (msgPart != null)
  207.             {
  208.                 if (originalStream != null)
  209.                 {
  210.                     string stream = string.Empty;
  211.  
  212.                     // do the disassembling
  213.  
  214.                     //byte[] arrByte = ConvertToByteArray(stream);    // sample code from author
  215.                     //originalStream = (new MemoryStream(arrByte));   // sample code from author
  216.  
  217.                     XmlDocument xmlDoc = new XmlDocument();
  218.                     xmlDoc.Load(pInMsg.BodyPart.Data);
  219.  
  220.                     strTraceMessage = "xmlDoc.Load";
  221.                     trcCode = "0200";
  222.                     Shared.Utility.Log.WriteEntryConditional(
  223.                        System.Diagnostics.TraceLevel.Info,
  224.                        trcSource, trcGUID, trcCode, strTraceMessage,
  225.                        xmlDoc.OuterXml, trcCorrId);
  226.  
  227.  
  228.                     string strXPath = "//FlightLeg";
  229.                     if (xmlDoc.DocumentElement.Name == "CoreFlightData")
  230.                     {
  231.                         strXPath = "//FlightLeg";
  232.                     }
  233.  
  234.                     XmlNodeList xmlNodeList = xmlDoc.SelectNodes(strXPath);
  235.                     if (xmlNodeList.Count == 0)
  236.                     {
  237.                         trcCode = "0210";
  238.                         strTraceMessage = "XPath not found: " + strXPath;
  239.                         Shared.Utility.Log.WriteEntryConditional(
  240.                            System.Diagnostics.TraceLevel.Info,
  241.                            trcSource, trcGUID, trcCode, strTraceMessage,
  242.                            xmlDoc.OuterXml, trcCorrId);
  243.                     }
  244.                     int loopCounter = 0;
  245.                     foreach (XmlNode xmlNode in xmlNodeList)
  246.                     {
  247.                         loopCounter++;
  248.                         string newMessageText =
  249.                                  "<" + xmlDoc.DocumentElement.Name + ">" +
  250.                                  "<Event code='1111' gmtTs='2012-06-13T09:39:14Z' evntSeqNbr=''>" +
  251.                                  xmlNode.OuterXml +
  252.                                  "</Event>" +
  253.                                  "</" + xmlDoc.DocumentElement.Name + ">";
  254.  
  255.                        
  256.                         XmlDocument xmlDocOut = new XmlDocument();
  257.                         xmlDocOut.LoadXml(newMessageText);
  258.                        
  259.                         if (_debugLevel == "VERBOSE")
  260.                         {
  261.  
  262.                             trcCode = "0300";
  263.                             strTraceMessage = "New Message #" + loopCounter + " pInMsg.BodyPartName=" + pInMsg.BodyPartName;
  264.                             Shared.Utility.Log.WriteEntryConditional(
  265.                                System.Diagnostics.TraceLevel.Info,
  266.                                trcSource, trcGUID, trcCode, strTraceMessage,
  267.                                newMessageText, trcCorrId);
  268.                         }
  269.  
  270.  
  271.                         // The GetNext method will return messages to BizTalk from
  272.                         // this queue of IBaseMessages
  273.  
  274.                         // convert string to stream
  275.                         //MemoryStream outStream = new MemoryStream
  276.                         //         (System.Text.Encoding.UTF8.GetBytes(newMessageText));
  277.                         MemoryStream outStream = new MemoryStream();
  278.                         xmlDocOut.Save(outStream);
  279.  
  280.                         // ?? not sure if this is needed
  281.                         // msgPart.Data = outStream;
  282.  
  283.  
  284.                         // load stream into IBaseMessage
  285.                         IBaseMessage outMsg;
  286.                         outMsg = pContext.GetMessageFactory().CreateMessage();
  287.  
  288.                         outStream.Position = 0;
  289.                         outStream.Seek(0, SeekOrigin.Begin);
  290.  
  291.                         // Using variable here results in lowercase "body"
  292.                         //outMsg.AddPart(pInMsg.BodyPartName,
  293.                         // other sources show uppercase "Body", so far doesn't seem to make any difference
  294.  
  295.                         outMsg.AddPart("Body",
  296.                                        pContext.GetMessageFactory().CreateMessagePart(),
  297.                                        true);
  298.                         outMsg.BodyPart.Data = outStream;
  299.  
  300.  
  301.  
  302.                         // copy over all context from incoming message, then change only what is needed
  303.                         outMsg.Context = pInMsg.Context;
  304.                        
  305.                         /*
  306.                         outMsg.Context.Promote("MessageType",
  307.                           "http://schemas.microsoft.com/BizTalk/2003/system-properties",
  308.                           "http://qt.bts.external.delta.schemas/FPES2#CoreFlightData");
  309.                         outMsg.Context.Promote("SchemaStrongName",
  310.                           "http://schemas.microsoft.com/BizTalk/2003/system-properties",
  311.                           "SchemaAssembly full name");
  312.                         */
  313.  
  314.                         //outMsg.BodyPart.GetOriginalDataStream().Position = 0;
  315.                         //outMsg.BodyPart.GetOriginalDataStream().Seek(0, SeekOrigin.Begin);
  316.  
  317.                         qOutputMsgs.Enqueue(outMsg);
  318.                         // pContext.ResourceTracker.AddResource(outStream); // ????
  319.                     }
  320.  
  321.  
  322.                 }
  323.             }
  324.         }
  325.         catch (Exception ex)
  326.         {
  327.             trcCode = "0210";
  328.             strTraceMessage = "Pipeline trcCode=" + trcCode + " Exception:" + ex.ToString();
  329.             Shared.Utility.Log.WriteEntryConditional(
  330.                System.Diagnostics.TraceLevel.Info,
  331.                trcSource, trcGUID, trcCode, strTraceMessage,
  332.                null, trcCorrId);
  333.             throw;
  334.         }
  335.  
  336.  
  337.        
  338.         //originalStream.Seek(0, SeekOrigin.Begin);
  339.         //msgPart.Data = originalStream;
  340.  
  341.         /*
  342.         //IBaseMessage outMsg = pInMsg;
  343.         outMsg.BodyPart.Data = originalStream;
  344.  
  345.         // promote MessageType and Schema SchemaStrongName
  346.         // in order to the Biztalk to have a unique key
  347.         // for evaluating subscription
  348.         // As an example for Namespace#Root= http://TestCustomPipeline.Schema1#roottagName
  349.         // As an example for SchemaAssembly full name=
  350.         // TestCustomPipeline.Schema1, TestCustomPipeline,
  351.         // Version=1.0.0.0, Culture=neutral, PublicKeyToken=f38e6d751bb874eb
  352.  
  353.         qOutputMsgs.Enqueue(outMsg);
  354.          */
  355.  
  356.         System.Diagnostics.Trace.WriteLine("Pipeline Disassemble Stage Exit");
  357.     }
  358.  
  359.     public IBaseMessage GetNext(IPipelineContext pContext)
  360.     {
  361.  
  362.        
  363.         string trcSource = "DeltaPipeline:SetNSForFPES2Msg";
  364.         string trcCorrId = System.Guid.NewGuid().ToString();
  365.         string strTraceMessage = null;
  366.  
  367.         string trcCode = "0100";
  368.  
  369.  
  370.         try
  371.         {
  372.             if (qOutputMsgs.Count > 0)
  373.             {
  374.                 IBaseMessage msg = (IBaseMessage)qOutputMsgs.Dequeue();
  375.  
  376.                 //XmlDocument xmlDoc = new XmlDocument();
  377.                 // xmlDoc.Load(msg.BodyPart.Data);
  378.  
  379.                 //string textFromBodyPart = ConvertToString(msg.BodyPart.Data);
  380.                
  381.  
  382.                 trcCode = "1101";
  383.                 strTraceMessage = "GetNext qOutputMsgs.Count = " + qOutputMsgs.Count +
  384.                                   " CanSeek=" + msg.BodyPart.GetOriginalDataStream().CanSeek;
  385.  
  386.                 Shared.Utility.Log.WriteEntryConditional(
  387.                    System.Diagnostics.TraceLevel.Info,
  388.                    trcSource, trcCorrId, trcCode, strTraceMessage,
  389.                    null, trcCorrId);
  390.  
  391.                 /*
  392.                 trcCode = "1102";
  393.                 string xmlDebug = "<Wrapper><![CDATA[" + textFromBodyPart + "]]></Wrapper>";
  394.                 Shared.Utility.Log.WriteEntryConditional(
  395.                    System.Diagnostics.TraceLevel.Info,
  396.                    trcSource, trcCorrId, trcCode, strTraceMessage,
  397.                    xmlDebug, trcCorrId);
  398.                 */
  399.  
  400.  
  401.                 // http://social.msdn.microsoft.com/Forums/en-US/biztalkgeneral/thread/1186c141-f8ce-4642-9abb-31e73949e5b5
  402.                 //msg.BodyPart.GetOriginalDataStream().Position = 0;
  403.                 //msg.BodyPart.GetOriginalDataStream().Seek(0, SeekOrigin.Begin);
  404.  
  405.                 //ulong nSize = 0;
  406.                 //bool bFlag;
  407.                 //msg.BodyPart.GetSize(out nSize, out bFlag);
  408.                 return msg;
  409.             }
  410.             else
  411.             {
  412.                 // we have already dequeued everything, so return a null message to signal that we are all done.
  413.                 trcCode = "1140";
  414.                 strTraceMessage = "GetNext qOutputMsgs.Count <= 0";
  415.                 Shared.Utility.Log.WriteEntryConditional(
  416.                    System.Diagnostics.TraceLevel.Info,
  417.                    trcSource, trcCorrId, trcCode, strTraceMessage,
  418.                    null, trcCorrId);
  419.  
  420.  
  421.                 return null;
  422.             }
  423.         }
  424.         catch (Exception ex)
  425.         {
  426.             string tempTrcCode = "1199";
  427.             strTraceMessage = "TrcCode=" + trcCode + ": GetNext exception: " + ex.ToString();
  428.             Shared.Utility.Log.WriteEntryConditional(
  429.                System.Diagnostics.TraceLevel.Info,
  430.                trcSource, trcCorrId, tempTrcCode, strTraceMessage,
  431.                null, trcCorrId);
  432.  
  433.             throw ex;
  434.  
  435.         }
  436.     }
  437.  
  438. #endregion
  439.  
  440.  
  441.  
  442. #region Private Helper Functions
  443.  
  444.     private byte[] ConvertToByteArray(string strInput)
  445.     {
  446.         return Encoding.ASCII.GetBytes(strInput);
  447.     }
  448.  
  449.     private string ConvertToString(Stream inStream)
  450.     {
  451.         byte[] buffer = new byte[inStream.Length];
  452.         inStream.Read(buffer, 0, (int)inStream.Length);
  453.  
  454.         return Encoding.ASCII.GetString(buffer);
  455.     }
  456.  
  457. #endregion
  458.  
  459.  
  460.  
  461.  
  462. } // end class
  463.  
  464.  
  465. } // end namespace
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement