/// <summary> /// Implements IComponent.Execute method. /// </summary> /// <param name="pc">Pipeline context</param> /// <param name="inmsg">Input message</param> /// <returns>Original input message</returns> /// <remarks> /// IComponent.Execute method is used to initiate /// the processing of the message in this pipeline component. /// </remarks> public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg) { var callToken = TraceManager.PipelineComponent.TraceIn(); TraceManager.PipelineComponent.TraceInfo(string.Format("{0} - {1} - START StreamingGood pipeline component.", System.DateTime.Now, callToken)); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); if (Enabled) { try { Stream bodyPartStream = inmsg.BodyPart.GetOriginalDataStream(); Base64EncoderStream newStream = new Base64EncoderStream(bodyPartStream, BufferSizeBytes); inmsg.BodyPart.Data = newStream; pc.ResourceTracker.AddResource(newStream); // Rewind output stream to the beginning, so it's ready to be read. inmsg.BodyPart.Data.Position = 0; } catch (Exception ex) { TraceManager.PipelineComponent.TraceError(ex, true, callToken); if (inmsg != null) { inmsg.SetErrorInfo(ex); } throw; } } stopwatch.Stop(); TraceManager.PipelineComponent.TraceInfo(string.Format("{0} - {1} - Stopwatch elapsed time = {2}", System.DateTime.Now, callToken, stopwatch.Elapsed)); TraceManager.PipelineComponent.TraceInfo(string.Format("{0} - {1} - END - StreamingGood pipeline component. Return.", System.DateTime.Now, callToken)); TraceManager.PipelineComponent.TraceOut(callToken); return(inmsg); }
/// <summary> /// Implements IComponent.Execute method. /// </summary> /// <param name="pc">Pipeline context</param> /// <param name="inmsg">Input message</param> /// <returns>Original input message</returns> /// <remarks> /// IComponent.Execute method is used to initiate /// the processing of the message in this pipeline component. /// </remarks> public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg) { #region Copy input stream try { IBaseMessagePart bodyPart = inmsg.BodyPart; if (bodyPart != null) { Stream originalStream = bodyPart.GetOriginalDataStream(); // Biztalk will not do property promotion in time if we do not touch the stream. Seems to be a quirk of how the send pipeline works. // If original message is returned no property promotion will happen before the EDI assembler component gets the message. if (originalStream != null) { StreamReader sReader = new StreamReader(originalStream); VirtualStream vStream = new VirtualStream(); StreamWriter sWriter = new StreamWriter(vStream); //Write message body to a virutal memory stream sWriter.Write(sReader.ReadToEnd()); sWriter.Flush(); sReader.Close(); vStream.Seek(0, SeekOrigin.Begin); pc.ResourceTracker.AddResource(vStream); inmsg.BodyPart.Data = vStream; } } #endregion #region Property promotion // Set the identificators. Make sure to set " " if missing to get property promoted (will make Biztalk fail the file on missing party) if (string.IsNullOrEmpty((string)inmsg.Context.Read(_senderId, _propertyNameSpace))) { inmsg.Context.Promote("DestinationPartySenderIdentifier", _edifactPropertyNamespace, " "); } else { inmsg.Context.Promote("DestinationPartySenderIdentifier", _edifactPropertyNamespace, inmsg.Context.Read(_senderId, _propertyNameSpace)); } if (string.IsNullOrEmpty((string)inmsg.Context.Read(_receiverId, _propertyNameSpace))) { inmsg.Context.Promote("DestinationPartyReceiverIdentifier", _edifactPropertyNamespace, " "); } else { inmsg.Context.Promote("DestinationPartyReceiverIdentifier", _edifactPropertyNamespace, inmsg.Context.Read(_receiverId, _propertyNameSpace)); } // If no qualifier is set in pipeline use " " since that will resolve as <no qualifier> in Biztalk. if (string.IsNullOrEmpty(_senderIdQualifier)) { inmsg.Context.Promote("DestinationPartySenderQualifier", _edifactPropertyNamespace, " "); } else { // If no value is found on property set space as value (<No qualifier>) if (string.IsNullOrEmpty((string)inmsg.Context.Read(_senderIdQualifier, _propertyNameSpace))) { inmsg.Context.Promote("DestinationPartySenderQualifier", _edifactPropertyNamespace, " "); } else { inmsg.Context.Promote("DestinationPartySenderQualifier", _edifactPropertyNamespace, inmsg.Context.Read(_senderIdQualifier, _propertyNameSpace)); } } // If no qualifier is set in pipeline use " " since that will resolve as <no qualifier> in Biztalk. if (string.IsNullOrEmpty(_receiverIdQualifier)) { inmsg.Context.Promote("DestinationPartyReceiverQualifier", _edifactPropertyNamespace, " "); } else { // If no value is found on property set space as value (<No qualifier>) if (string.IsNullOrEmpty((string)inmsg.Context.Read(_receiverIdQualifier, _propertyNameSpace))) { inmsg.Context.Promote("DestinationPartyReceiverQualifier", _edifactPropertyNamespace, " "); } else { inmsg.Context.Promote("DestinationPartyReceiverQualifier", _edifactPropertyNamespace, inmsg.Context.Read(_receiverIdQualifier, _propertyNameSpace)); } } return(inmsg); #endregion } catch (Exception ex) { if (inmsg != null) { inmsg.SetErrorInfo(ex); } throw; } }
/// <summary> /// Implements IComponent.Execute method. /// </summary> /// <param name="pc">Pipeline context</param> /// <param name="inmsg">Input message</param> /// <returns>Original input message</returns> /// <remarks> /// IComponent.Execute method is used to initiate /// the processing of the message in this pipeline component. /// </remarks> public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg) { // Note: this is a **NON-OPTIMAL** pipeline component to demonstrate how **NOT** to write a pipeline component!! // - It uses XDocument and a string to construct an XML message, which is memory intensive for large messages. // - It writes the entire output message into a memory stream in one go, which is memory intensive for large messages. // - Further pipeline execution is blocked while this pipeline component completes processing, which slows processing. var callToken = TraceManager.PipelineComponent.TraceIn(); TraceManager.PipelineComponent.TraceInfo(string.Format("{0} - {1} - START NotStreamingBad pipeline component.", System.DateTime.Now, callToken)); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); if (Enabled) { try { byte[] bytesOut = null; TraceManager.PipelineComponent.TraceInfo(string.Format("{0} - {1} - Read message data.", System.DateTime.Now, callToken)); BinaryReader binReader = new BinaryReader(inmsg.BodyPart.Data); bytesOut = binReader.ReadBytes((int)inmsg.BodyPart.Data.Length); binReader.Close(); TraceManager.PipelineComponent.TraceInfo(string.Format("{0} - {1} - Create XML containing base64 encoded data.", System.DateTime.Now, callToken)); // This loads the entire XML into memory, into a DOM. **NOT OPTIMAL**. XDocument xml = XDocument.Parse( System.String.Format( @"<?xml version=""1.0""?> <ns0:Invoice xmlns:ns0=""http://Invoice/v1"" MinorVersion=""1.0""> <Base64EncodedStream>{0}</Base64EncodedStream> </ns0:Invoice>" , System.Convert.ToBase64String(bytesOut))); TraceManager.PipelineComponent.TraceInfo(string.Format("{0} - {1} - Write XML to stream.", System.DateTime.Now, callToken)); Stream ms = new MemoryStream(); StreamWriter sw = new StreamWriter(ms, Encoding.ASCII); sw.Write(xml); sw.Flush(); inmsg.BodyPart.Data = ms; pc.ResourceTracker.AddResource(sw); // Rewind output stream to the beginning, so it's ready to be read. inmsg.BodyPart.Data.Position = 0; } catch (Exception ex) { TraceManager.PipelineComponent.TraceError(ex, true, callToken); if (inmsg != null) { inmsg.SetErrorInfo(ex); } throw; } } stopwatch.Stop(); TraceManager.PipelineComponent.TraceInfo(string.Format("{0} - {1} - Stopwatch elapsed time = {2}", System.DateTime.Now, callToken, stopwatch.Elapsed)); TraceManager.PipelineComponent.TraceInfo(string.Format("{0} - {1} - END - NotStreamingBad pipeline component. Return.", System.DateTime.Now, callToken)); TraceManager.PipelineComponent.TraceOut(callToken); return(inmsg); }