public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { string errorMessage; if (!Validate(out errorMessage)) { throw new ArgumentException(errorMessage); } var cu = new CompressionUtil(); for (var i = 0; i < pInMsg.PartCount; i++) { string partName; var part = pInMsg.GetPartByIndex(i, out partName); var fileName = GetFileName(part); cu.AddMessage(part.GetOriginalDataStream(), fileName); } var outMsg = pContext.GetMessageFactory().CreateMessage(); outMsg.Context = pInMsg.Context; var bodyPart = pContext.GetMessageFactory().CreateMessagePart(); bodyPart.Data = cu.GetZip(); bodyPart.Charset = "utf-8"; bodyPart.ContentType = "application/zip"; outMsg.AddPart("Body",bodyPart,true); return outMsg; }
public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg) { if (pInMsg.BodyPart != null) { Stream currentPartSource = pInMsg.BodyPart.GetOriginalDataStream(); byte[] currentPartBuffer = new byte[currentPartSource.Length]; currentPartSource.Read(currentPartBuffer, 0, currentPartBuffer.Length); byte[] decompressedPartBuffer; string filename = ""; //Unzip arquive using (var unzipArchive = new ZipArchive(currentPartSource, ZipArchiveMode.Read, true)) { //Loop arquive file for message foreach (var entryStream in unzipArchive.Entries) { IBaseMessage inboundInstanceMessage; //Here we are gets the filename (with extension) of an entery present in the arquive file filename = entryStream.FullName; using (var outStream = new MemoryStream()) { entryStream.Open().CopyTo(outStream); decompressedPartBuffer = outStream.ToArray(); } MemoryStream messageInstanceStream = new MemoryStream(decompressedPartBuffer); messageInstanceStream.Position = 0; #region Generating a new inbound message //Creating a new message from the pipeline context inboundInstanceMessage = pContext.GetMessageFactory().CreateMessage(); //Cloning the context to the new message, instead of assigning it inboundInstanceMessage.Context = PipelineUtil.CloneMessageContext(pInMsg.Context); inboundInstanceMessage.AddPart("Body", pContext.GetMessageFactory().CreateMessagePart(), true); inboundInstanceMessage.BodyPart.Data = messageInstanceStream; inboundInstanceMessage.BodyPart.Charset = "UTF-8"; inboundInstanceMessage.BodyPart.ContentType = "text/xml"; //we promote the filename so that we can access it in the Send Port. inboundInstanceMessage.Context.Promote("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties", filename); #endregion inboundMsgQueue.Enqueue(inboundInstanceMessage); } } } }
public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg) { IBaseMessagePart bodyPart = pInMsg.BodyPart; if (bodyPart != null) { Stream originalStream = bodyPart.GetOriginalDataStream(); MemoryStream memStream = new MemoryStream(); byte[] buffer = new Byte[1024]; int bytesRead = 1024; while (bytesRead != 0) { bytesRead = originalStream.Read(buffer, 0, buffer.Length); memStream.Write(buffer, 0, bytesRead); } memStream.Position = 0; if (originalStream != null) { using (ZipArchive zipArchive = new ZipArchive(memStream, ZipArchiveMode.Read)) { foreach (ZipArchiveEntry entry in zipArchive.Entries) { MemoryStream entryStream = new MemoryStream(); byte[] entrybuffer = new Byte[1024]; int entryBytesRead = 1024; Stream zipArchiveEntryStream = entry.Open(); while (entryBytesRead != 0) { entryBytesRead = zipArchiveEntryStream.Read(entrybuffer, 0, entrybuffer.Length); entryStream.Write(entrybuffer, 0, entryBytesRead); } IBaseMessage outMessage; outMessage = pContext.GetMessageFactory().CreateMessage(); outMessage.AddPart("Body", pContext.GetMessageFactory().CreateMessagePart(), true); entryStream.Position = 0; outMessage.BodyPart.Data = entryStream; pInMsg.Context.Promote(new ContextProperty(FileProperties.ReceivedFileName), entry.Name); outMessage.Context = PipelineUtil.CloneMessageContext(pInMsg.Context); _qOutMessages.Enqueue(outMessage); } } } } }
/// <summary> /// Create the output message when validation errors are captured /// </summary> /// <param name="pContext">Pipeline context</param> /// <param name="pInMsg">Input message in the pipeline</param> /// <param name="errorStream">Stream for the Validation Errors</param> /// <param name="requestId">Request Id</param> /// <returns></returns> public static IBaseMessage CreateOutPutMessage(IPipelineContext pContext, IBaseMessage pInMsg, VirtualStream errorStream, string requestId) { VirtualStream seekableStream = new VirtualStream(pInMsg.BodyPart.GetOriginalDataStream()); seekableStream.Position = 0; errorStream.Position = 0; VirtualStream outMsgStream = CreateValidationErrorMessage(seekableStream, errorStream, requestId); outMsgStream.Position = 0; IBaseMessageFactory messageFactory = pContext.GetMessageFactory(); IBaseMessage pOutMsg = messageFactory.CreateMessage(); IBaseMessagePart pOutMsgBodyPart = messageFactory.CreateMessagePart(); IBasePropertyBag pOutPb = PipelineUtil.CopyPropertyBag(pInMsg.BodyPart.PartProperties, messageFactory); pOutMsg.Context = PipelineUtil.CloneMessageContext(pInMsg.Context); pOutMsgBodyPart.Charset = Constants.BodyPartCharSet; pOutMsgBodyPart.ContentType = Constants.BodyPartContentType; pOutMsgBodyPart.Data = outMsgStream; string outMessageType = string.Format("{0}#{1}", Constants.AIBPValidationErrorNameSpace, Constants.AIBPValidationErrorRootNode); pOutMsg.Context.Promote(Constants.MessageTypePropName, Constants.SystemPropertiesNamespace, outMessageType); pOutMsg.AddPart("Body", pOutMsgBodyPart, true); // Add resources to the resource tracker to be disposed of at correct time pContext.ResourceTracker.AddResource(seekableStream); pContext.ResourceTracker.AddResource(outMsgStream); pContext.ResourceTracker.AddResource(errorStream); return(pOutMsg); }
/// <summary> /// Populates a body part with content from an XML document. If no body part exists, a new one /// is created. /// </summary> /// <param name="message">The massage to which the body part will be added.</param> /// <param name="part">The existing part</param> /// <param name="pc">The pipeline context.</param> /// <returns>A message with a body part populated by the XML document content.</returns> public static bool PopulateBodyPartFromExistingPart(this IBaseMessage message, IBaseMessagePart part, IPipelineContext pc) { if (message == null || part == null) { return(false); } Func <IBaseMessagePart> clonedPart = () => { var newPart = pc.GetMessageFactory().CreateMessagePart(); newPart.Data = part.GetOriginalDataStream().Clone(); return(newPart); }; var outPart = part.IsMutable ? clonedPart() : part.WithStreamAtStart(); // Add a body part if none exists. if (message.BodyPart == null) { message.AddPart("Body", outPart, true); } return(true); }
public static IBaseMessage ShallowCloneMessage(IPipelineContext pipelineContext, IBaseMessage message) { if (pipelineContext == null) { throw new ArgumentNullException("pipelineContext"); } if (message == null) { throw new ArgumentNullException("message"); } try { IBaseMessage message1 = pipelineContext.GetMessageFactory().CreateMessage(); message1.Context = GetMininalContext(pipelineContext, message); MessageHelper.CloneAndAddMessageParts(pipelineContext, message, message1); pipelineContext.ResourceTracker.AddResource((object)message1.BodyPart.Data); return(message1); } catch (Exception ex) { DECore.TraceProvider.Logger.TraceError(ex); throw; } }
internal static IBaseMessage CloneMessage(IBaseMessage inmsg, IPipelineContext pc) { IBaseMessageFactory messageFactory = pc.GetMessageFactory(); var outmsg = messageFactory.CreateMessage(); outmsg.Context = PipelineUtil.CloneMessageContext(inmsg.Context); // Generate new empty message body part, we will retain nothing from the old IBaseMessagePart body = messageFactory.CreateMessagePart(); if ((inmsg != null) && (inmsg.BodyPart != null)) { body.PartProperties = PipelineUtil.CopyPropertyBag(inmsg.BodyPart.PartProperties, messageFactory); } // This is what the XmlWriter will end up generating, and what appears in the // directive at the top of the file body.Charset = "UTF-8"; body.ContentType = "text/xml"; body.Data = null; CloneParts(pc, inmsg, outmsg, body); return(outmsg); }
IBaseMessage CreateMessage(IPipelineContext pContext, XmlReader reader) { IBaseMessage outMsg = pContext.GetMessageFactory().CreateMessage(); outMsg.AddPart("Body", pContext.GetMessageFactory().CreateMessagePart(), true); outMsg.Context = baseMsg.Context; outMsg.Context.Promote("MessageType", _systemPropertiesNamespace, currDocument.DocType); //we add the SchemaStrongName as there could posssible exist multiple messages with the same MessageType outMsg.Context.Promote("SchemaStrongName", _systemPropertiesNamespace , currDocument.DocSpecStrongName); //Is used XmlTranslatorStream as it is the only one i could find that takes an XmlReader as input //At this point i did not want to write my own custom stream outMsg.BodyPart.Data = new XmlTranslatorStream(reader.ReadSubtree()); return(outMsg); }
/// <summary> /// Method used to update BizTalk Pipeline message from the BRE Policy. BRE Policies work with Xml messages. BizTalk Messages are immutable. Thus if in order for the BRE Policy to update the BizTalk Message, a new message needs to be created, copied, or cloned containing the updated Xml content, along with the BizTalk Promoted properties from the context. /// </summary> /// <param name="xmlMessage">Message containing the modified content</param> /// <param name="pc">Pipeline context containing the current pipeline configuration</param> /// <param name="baseMsg">BizTalk BaseMessage which is to be cloned/copied/or modified</param> private static void UpdateMessage(string xmlMessage, IPipelineContext pc, ref IBaseMessage baseMsg) { if (pc == null || baseMsg == null) { return; } IBaseMessagePart bodyPart = pc.GetMessageFactory().CreateMessagePart(); MemoryStream omstrm = new MemoryStream(Encoding.UTF8.GetBytes(xmlMessage)); omstrm.Seek(0L, SeekOrigin.Begin); bodyPart.Data = omstrm; pc.ResourceTracker.AddResource(omstrm); IBaseMessage outMsg = pc.GetMessageFactory().CreateMessage(); outMsg.AddPart("body", bodyPart, true); outMsg.Context = PipelineUtil.CloneMessageContext(baseMsg.Context); baseMsg = outMsg; }
private void CreateOutgoingMessage(IPipelineContext pContext, String messageString, string namespaceURI, string rootElement) { IBaseMessage outMsg; try { //create outgoing message outMsg = pContext.GetMessageFactory().CreateMessage(); outMsg.AddPart("Body", pContext.GetMessageFactory().CreateMessagePart(), true); outMsg.Context.Promote("MessageType", systemPropertiesNamespace, namespaceURI + "#" + rootElement.Replace("ns0:", "")); byte[] bufferOoutgoingMessage = System.Text.ASCIIEncoding.ASCII.GetBytes(messageString); outMsg.BodyPart.Data = new MemoryStream(bufferOoutgoingMessage); qOutputMsgs.Enqueue(outMsg); } catch (Exception ex) { throw new ApplicationException("Error in queueing outgoing messages: " + ex.Message); } }
public Queue DecompressAndSpliMessage(IBaseMessage inMsg, IPipelineContext pctx) { var readOnlySeekableStream = GetSeekableStream(inMsg); var messages = _decompressor.DecompressMessage(readOnlySeekableStream); var outMsgs = new Queue(); IBaseMessage outMessage; foreach (var msg in messages) { outMessage = pctx.GetMessageFactory().CreateMessage(); outMessage.AddPart("Body", pctx.GetMessageFactory().CreateMessagePart(), true); outMessage.BodyPart.Data = msg.Value; outMessage.Context = PipelineUtil.CloneMessageContext(inMsg.Context); ContextExtensions.Promote(outMessage.Context, new ContextProperty(FileProperties.ReceivedFileName), msg.Key); outMsgs.Enqueue(outMessage); } return outMsgs; }
private void CreateOutgoingMessage(IPipelineContext pContext, String messageString, IBaseMessage pInMsg) { IBaseMessage outMsg; try { //create outgoing message outMsg = pContext.GetMessageFactory().CreateMessage(); outMsg.AddPart("Body", pContext.GetMessageFactory().CreateMessagePart(), true); byte[] bufferOoutgoingMessage = System.Text.ASCIIEncoding.ASCII.GetBytes(messageString); outMsg.BodyPart.Data = new MemoryStream(bufferOoutgoingMessage); outMsg.Context = PipelineUtil.CloneMessageContext(pInMsg.Context); qOutputMsgs.Enqueue(outMsg); } catch (Exception ex) { throw new ApplicationException("Error in queueing outgoing messages: " + ex.Message); } }
private static IBaseMessagePart CloneMessagePart(IPipelineContext pipelineContext, IBaseMessagePart messagePart) { IBaseMessageFactory messageFactory = pipelineContext.GetMessageFactory(); IBaseMessagePart messagePart1 = messageFactory.CreateMessagePart(); messagePart1.Charset = messagePart.Charset; messagePart1.ContentType = messagePart.ContentType; messagePart1.PartProperties = PipelineUtil.CopyPropertyBag(messagePart.PartProperties, messageFactory); VirtualStream virtualStream = new VirtualStream(); MessageHelper.CopyStream(messagePart.Data, (Stream)virtualStream); messagePart1.Data = (Stream)virtualStream; return(messagePart1); }
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { string errorMessage; if (!Validate(out errorMessage)) { throw new ArgumentException(errorMessage); } var outMsg = pContext.GetMessageFactory().CreateMessage(); outMsg.Context = pInMsg.Context; var bodyPart = pContext.GetMessageFactory().CreateMessagePart(); using (var compressionUtil = new CompressionUtil()) { for (var i = 0; i < pInMsg.PartCount; i++) { string partName; var part = pInMsg.GetPartByIndex(i, out partName); var fileName = GetFileName(part); compressionUtil.AddMessage(part.GetOriginalDataStream(), fileName); } bodyPart.Data = compressionUtil.GetZip(); pContext.ResourceTracker.AddResource(bodyPart.Data); bodyPart.Charset = "utf-8"; bodyPart.ContentType = "application/zip"; } outMsg.AddPart("Body", bodyPart, true); return(outMsg); }
public static IBaseMessage DeepCloneMessage(IPipelineContext pipelineContext, IBaseMessage message) { if (pipelineContext == null) { throw new ArgumentNullException("pipelineContext"); } if (message == null) { throw new ArgumentNullException("message"); } IBaseMessage message1 = pipelineContext.GetMessageFactory().CreateMessage(); message1.Context = PipelineUtil.CloneMessageContext(message.Context); MessageHelper.CloneAndAddMessageParts(pipelineContext, message, message1); pipelineContext.ResourceTracker.AddResource((object)message1.BodyPart.Data); return(message1); }
/// <summary> /// Populates a body part with content from an XML document. If no body part exists, a new one /// is created. /// </summary> /// <param name="message">The massage to which the body part will be added.</param> /// <param name="xmlDocument">The XML document containing the content</param> /// <param name="pc">The pipeline context.</param> /// <returns>A message with a body part populated by the XML document content.</returns> public static bool PopulateBodyPartFromXmlDocument(this IBaseMessage message, XmlDocument xmlDocument, IPipelineContext pc) { if (message == null) { return(false); } // Add a body part if none exists. if (message.BodyPart == null) { message.AddPart("Body", pc.GetMessageFactory().CreateMessagePart(), true); } // Assign transformed message to outbound message message.BodyPart.Data = new MemoryStream().PopulateFromXmlDocument(xmlDocument); return(true); }
/// <summary> /// Deep XML message valitation method. This method copies the inbound message, processes /// the inbound message onto the copied message and returns the copied message if all went well /// </summary> /// <param name="pc">the <see cref="IPipelineContext"/></param> /// <param name="inmsg">the inbound message</param> /// <returns>the copied message instance, if all went well</returns> private IBaseMessage FullyValidateMessage(IPipelineContext pc, IBaseMessage inmsg) { IBaseMessage copiedMessage = null; if (pc != null && inmsg != null) { #region duplicate inbound message IBaseMessageFactory messageFactory = pc.GetMessageFactory(); copiedMessage = messageFactory.CreateMessage(); IBaseMessageContext copiedContext = inmsg.Context; IBaseMessagePart copiedMessagePart = inmsg.BodyPart; copiedMessage.Context = copiedContext; #endregion this.ProcessPart(pc, inmsg, copiedMessage, copiedMessagePart); } return(copiedMessage); }
public static IBaseMessageContext GetMininalContext(IPipelineContext pipelineContext, IBaseMessage message) { IBaseMessageContext outputContext = pipelineContext.GetMessageFactory().CreateMessageContext(); foreach (var context in minMessageContext) { var value = message.Context.Read(context.Item1, context.Item2); if (value != null) { var isPromoted = message.Context.IsPromoted(context.Item1, context.Item2); if (isPromoted || context.Item3) { outputContext.Promote(context.Item1, context.Item2, value); } else { outputContext.Write(context.Item1, context.Item2, value); } } } return(outputContext); }
private IBaseMessage GetValidationErrorResponse(IPipelineContext pContext, IBaseMessage pInMsg, object epmRRCorrelationToken, object correlationToken, object reqRespTransmitPipelineID, XmlValidatorException ex) { var outMsg = pContext.GetMessageFactory().CreateMessage(); outMsg.AddPart("Body", pInMsg.BodyPart, true); outMsg.Context.Promote(new ContextProperty(SystemProperties.RouteDirectToTP), true); outMsg.Context.Write(new ContextProperty(WCFProperties.OutboundHttpStatusCode), "400"); outMsg.Context.Promote(new ContextProperty(SystemProperties.IsRequestResponse), true); outMsg.Context.Promote(new ContextProperty(SystemProperties.EpmRRCorrelationToken), epmRRCorrelationToken); outMsg.Context.Promote(new ContextProperty(SystemProperties.CorrelationToken), correlationToken); outMsg.Context.Promote(new ContextProperty(SystemProperties.ReqRespTransmitPipelineID), reqRespTransmitPipelineID); var ms = new MemoryStream(); var sw = new StreamWriter(ms); sw.Write(GetExceptionDetails(ex)); sw.Flush(); ms.Seek(0, SeekOrigin.Begin); outMsg.BodyPart.Data = ms; return(outMsg); }
public static IBaseMessageContext CloneAndExcludeESBProperties(IPipelineContext pipelineContext, IBaseMessage message) { IBaseMessageContext outputContext = pipelineContext.GetMessageFactory().CreateMessageContext(); for (int i = 0; i < message.Context.CountProperties; i++) { var name = string.Empty; var nameSpace = string.Empty; var value = message.Context.ReadAt(i, out name, out nameSpace); if (!nameSpace.Equals(itineraryNamespace, StringComparison.InvariantCultureIgnoreCase) && value != null) { var isPromoted = message.Context.IsPromoted(name, nameSpace); if (isPromoted) { outputContext.Promote(name, nameSpace, value); } else { outputContext.Write(name, nameSpace, value); } } } return(outputContext); }
internal static IBaseMessage CloneMessage(IBaseMessage inmsg, IPipelineContext pc) { IBaseMessageFactory messageFactory = pc.GetMessageFactory(); var outmsg = messageFactory.CreateMessage(); outmsg.Context = PipelineUtil.CloneMessageContext(inmsg.Context); // Generate new empty message body part, we will retain nothing from the old IBaseMessagePart body = messageFactory.CreateMessagePart(); if ((inmsg != null) && (inmsg.BodyPart != null)) body.PartProperties = PipelineUtil.CopyPropertyBag(inmsg.BodyPart.PartProperties, messageFactory); // This is what the XmlWriter will end up generating, and what appears in the // directive at the top of the file body.Charset = "UTF-8"; body.ContentType = "text/xml"; body.Data = null; CloneParts(pc, inmsg, outmsg, body); return outmsg; }
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { if (!Enabled) { return(pInMsg); } string errorMessage; if (!Validate(out errorMessage)) { throw new ArgumentException(errorMessage); } IBaseMessageFactory messageFactory = pContext.GetMessageFactory(); IBaseMessage newMsg = messageFactory.CreateMessage(); newMsg.Context = pInMsg.Context; MemoryStream ms = new MemoryStream(); //Create Html body IBaseMessagePart bodyPart = messageFactory.CreateMessagePart(); if (ApplyXsltOnBodyPart) { if (string.IsNullOrEmpty(XSLTFilePath)) { throw new ArgumentNullException("XsltFilePath is null"); } if (!File.Exists(XSLTFilePath)) { throw new FileNotFoundException(string.Format("Cannot find the xslt file '{0}'.", XSLTFilePath)); } XslCompiledTransform transform = new XslCompiledTransform(); transform.Load(XSLTFilePath); Stream originalStream = pInMsg.BodyPart.GetOriginalDataStream(); if (!originalStream.CanSeek || !originalStream.CanRead) { originalStream = new ReadOnlySeekableStream(originalStream); } XmlReader reader = XmlReader.Create(originalStream); transform.Transform(reader, null, ms); originalStream.Seek(0, SeekOrigin.Begin); pInMsg.BodyPart.Data = originalStream; } else { byte[] buff = Encoding.UTF8.GetBytes(EmailBody); ms.Write(buff, 0, buff.Length); } ms.Seek(0, SeekOrigin.Begin); bodyPart.Data = ms; bodyPart.Charset = "UTF-8"; bodyPart.ContentType = "text/html"; newMsg.AddPart("body", bodyPart, true); //Add all message parts as attachments int i = 0; string[] filenames = FileNames.Split('|'); while (i < pInMsg.PartCount & i < filenames.Length) { if (!string.IsNullOrEmpty(filenames[i])) { string partName = ""; IBaseMessagePart part = pInMsg.GetPartByIndex(i, out partName), newPart = messageFactory.CreateMessagePart(); Stream originalStream = part.GetOriginalDataStream(); newPart.Data = originalStream; newPart.Charset = part.Charset; newPart.ContentType = "text/xml"; newPart.PartProperties.Write("FileName", "http://schemas.microsoft.com/BizTalk/2003/mime-properties", filenames[i]); newMsg.AddPart(filenames[i], newPart, false); } i++; } return(newMsg); }
/// <summary> /// Executes the logic for this component. /// </summary> /// <param name="pContext">Pipeline context</param> /// <param name="pInMsg">Input message</param> /// <returns>Outgoing message</returns> private IBaseMessage ExecuteInternal(IPipelineContext pContext, IBaseMessage pInMsg) { // Check arguments if (null == pContext) { throw new ArgumentNullException("pContext"); } if (null == pInMsg) { throw new ArgumentNullException("pInMsg"); } if (null == pInMsg.BodyPart) { throw new ArgumentNullException("pInMsg.BodyPart"); } if (null == pInMsg.BodyPart.GetOriginalDataStream()) { throw new ArgumentNullException("pInMsg.BodyPart.GetOriginalDataStream()"); } // // The logic behind this component is as follows: // 1. Create a seekable read-only stream over the input message body part stream // (because input message can be both large and stream can be non-seekable, // so it should have small memory footprint and change stream positions). // 2. Create a new outgoing message, new body part for it, assign seekable read-only stream // to the new body part, clone body part properties, clone message context. // 3. Get a schema for the input message or based on schemas specified during // design time. // 4. Load stream into XmlDocument. // 5. Walk through promoted properties and distinguished fields and promote/write // them to the message context of the outgoing message. // 6. Return outgoing message. // // // 1. Create a seekable read-only stream over the input message body part stream. // // Create a virtual stream, using GetOriginalDataStream() method on the IBaseMessagePart because // this call doesn't clone stream (instead of IBaseMessagePart.Data property). SeekableReadOnlyStream stream = new SeekableReadOnlyStream(pInMsg.BodyPart.GetOriginalDataStream()); // // 2. Create a new outgoing message, copy all required stuff. // // Create a new output message IBaseMessage outMessage = pContext.GetMessageFactory().CreateMessage(); // Copy message context by reference outMessage.Context = pInMsg.Context; // Create new message body part IBaseMessagePart newBodyPart = pContext.GetMessageFactory().CreateMessagePart(); // Copy body part properties by references. newBodyPart.PartProperties = pInMsg.BodyPart.PartProperties; // Set virtual stream as a data stream for the new message body part newBodyPart.Data = stream; // Copy message parts CopyMessageParts(pInMsg, outMessage, newBodyPart); // // 3. Get a schema for the message. // // Initialize schema map SchemaMap schemaMap = new SchemaMap(this.documentSchemaList); // Get message type from the message data stream string messageType = GetMessageType(stream); // Get a document spec from based on the message type IDocumentSpec documentSpec = schemaMap[messageType]; if (null == documentSpec) { documentSpec = pContext.GetDocumentSpecByType(messageType); } // Promote BTS.MessageType message context property to allow orchestration schedule instances be activated // on produced message. outMessage.Context.Promote(messageTypeWrapper.Name.Name, messageTypeWrapper.Name.Namespace, messageType); // // 4. Load document stream into XmlDocument. // // Save new message stream's current position long position = stream.Position; // Load document into XmlDocument XmlDocument document = new XmlDocument(); document.Load(stream); // Restore the 0 position for the virtual stream Debug.Assert(stream.CanSeek); // Restore new message stream's current position stream.Position = position; // // 5. Walk through promoted properties/distinguished fields and promote/write them. // // Walk through and promote properties IEnumerator annotations = documentSpec.GetPropertyAnnotationEnumerator(); while (annotations.MoveNext()) { IPropertyAnnotation annotation = (IPropertyAnnotation)annotations.Current; XmlNode propertyNode = document.SelectSingleNode(annotation.XPath); if (propertyNode != null) { // Promote context property to the message context as a typed value outMessage.Context.Promote(annotation.Name, annotation.Namespace, promotingMap.MapValue(propertyNode.InnerText, annotation.XSDType)); } } // Walk through and write distinguished fields IDictionaryEnumerator distFields = documentSpec.GetDistinguishedPropertyAnnotationEnumerator(); // IDocumentSpec.GetDistinguishedPropertyAnnotationEnumerator() can return null if (distFields != null) { while (distFields.MoveNext()) { DistinguishedFieldDefinition distField = (DistinguishedFieldDefinition)distFields.Value; XmlNode distFieldNode = document.SelectSingleNode(distField.XPath); if (distFieldNode != null) { // Write distinguished field to the message context as a string value outMessage.Context.Write(distField.XPath, Globals.DistinguishedFieldsNamespace, distFieldNode.InnerText); } } } // // 6. Return outgoing message. // return(outMessage); }
/// <summary> /// Executes the custom runtime task component to process the input message and returns the result message. /// </summary> /// <param name="pContext">A reference to <see cref="Microsoft.BizTalk.Component.Interop.IPipelineContext"/> object that contains the current pipeline context.</param> /// <param name="pInMsg">A reference to <see cref="Microsoft.BizTalk.Message.Interop.IBaseMessage"/> object that contains the message to process.</param> /// <returns>A reference to the returned <see cref="Microsoft.BizTalk.Message.Interop.IBaseMessage"/> object which will contain the output message.</returns> public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { Guard.ArgumentNotNull(pContext, "pContext"); Guard.ArgumentNotNull(pInMsg, "pInMsg"); var callToken = TraceManager.PipelineComponent.TraceIn(); // It is OK to load the entire message into XML DOM. The size of these requests is anticipated to be very small. XDocument request = XDocument.Load(pInMsg.BodyPart.GetOriginalDataStream()); string sectionName = (from childNode in request.Root.Descendants() where childNode.Name.LocalName == WellKnownContractMember.MessageParameters.SectionName select childNode.Value).FirstOrDefault <string>(); string applicationName = (from childNode in request.Root.Descendants() where childNode.Name.LocalName == WellKnownContractMember.MessageParameters.ApplicationName select childNode.Value).FirstOrDefault <string>(); string machineName = (from childNode in request.Root.Descendants() where childNode.Name.LocalName == WellKnownContractMember.MessageParameters.MachineName select childNode.Value).FirstOrDefault <string>(); TraceManager.PipelineComponent.TraceInfo(TraceLogMessages.GetConfigSectionRequest, sectionName, applicationName, machineName); IConfigurationSource configSource = ApplicationConfiguration.Current.Source; IApplicationConfigurationSource appConfigSource = configSource as IApplicationConfigurationSource; ConfigurationSection configSection = appConfigSource != null?appConfigSource.GetSection(sectionName, applicationName, machineName) : configSource.GetSection(sectionName); if (configSection != null) { IBaseMessagePart responsePart = BizTalkUtility.CreateResponsePart(pContext.GetMessageFactory(), pInMsg); XmlWriterSettings settings = new XmlWriterSettings(); MemoryStream dataStream = new MemoryStream(); pContext.ResourceTracker.AddResource(dataStream); settings.CloseOutput = false; settings.CheckCharacters = false; settings.ConformanceLevel = ConformanceLevel.Fragment; settings.NamespaceHandling = NamespaceHandling.OmitDuplicates; using (XmlWriter configDataWriter = XmlWriter.Create(dataStream, settings)) { configDataWriter.WriteResponseStartElement("r", WellKnownContractMember.MethodNames.GetConfigurationSection, WellKnownNamespace.ServiceContracts.General); configDataWriter.WriteResultStartElement("r", WellKnownContractMember.MethodNames.GetConfigurationSection, WellKnownNamespace.ServiceContracts.General); SerializableConfigurationSection serializableSection = configSection as SerializableConfigurationSection; if (serializableSection != null) { serializableSection.WriteXml(configDataWriter); } else { MethodInfo info = configSection.GetType().GetMethod(WellKnownContractMember.MethodNames.SerializeSection, BindingFlags.NonPublic | BindingFlags.Instance); string serialized = (string)info.Invoke(configSection, new object[] { configSection, sectionName, ConfigurationSaveMode.Full }); configDataWriter.WriteRaw(serialized); } configDataWriter.WriteEndElement(); configDataWriter.WriteEndElement(); configDataWriter.Flush(); } dataStream.Seek(0, SeekOrigin.Begin); responsePart.Data = dataStream; } else { throw new ApplicationException(String.Format(CultureInfo.InvariantCulture, ExceptionMessages.ConfigurationSectionNotFound, sectionName, ApplicationConfiguration.Current.Source.GetType().FullName)); } TraceManager.PipelineComponent.TraceOut(callToken); return(pInMsg); }
private static IBaseMessage MappedMessageToIBase(IPipelineContext pContext, IBaseMessage pInMsg, string resultMessage) { MemoryStream stream = new MemoryStream(System.Text.Encoding.Default.GetBytes(resultMessage)); stream.Position = 0; IBaseMessageFactory messageFactory = pContext.GetMessageFactory(); IBaseMessage transformedMessage = messageFactory.CreateMessage(); IBaseMessagePart part = messageFactory.CreateMessagePart(); part.Data = stream; transformedMessage.AddPart("Body", part, true); transformedMessage.Context = pInMsg.Context; return transformedMessage; }
private IBaseMessage CreateNewReturnMessage(IBaseMessage pInMsg, IPipelineContext pContext, Stream msgData) { IBaseMessageFactory messageFactory = pContext.GetMessageFactory(); IBaseMessage returnMsg = messageFactory.CreateMessage(); IBaseMessagePart part = messageFactory.CreateMessagePart(); msgData.Position = 0; part.Data = msgData; returnMsg.AddPart("Body", part, true); return returnMsg; }
/// <summary> /// processes the inbound message part /// </summary> /// <param name="pc"></param> /// <param name="inmsg"></param> /// <param name="outmsg"></param> /// <param name="part"></param> private void ProcessPart(IPipelineContext pc, IBaseMessage inmsg, IBaseMessage outmsg, IBaseMessagePart part) { IDocumentSpec docSpec = null; Stream dataStream = part.GetOriginalDataStream(); MarkableForwardOnlyEventingReadStream eventingDataStream = new MarkableForwardOnlyEventingReadStream(dataStream); XmlSchemaCollection schemaCollection = new XmlSchemaCollection(new NameTable()); schemaCollection.ValidationEventHandler += new ValidationEventHandler(this.ValidationCallBack); // retrieve the assigned document schemas to validate against SchemaList docSchemas = this.DocumentSchemas; // retrieve the namespace this document adheres to string contextProperty = (string)outmsg.Context.Read(XmlCompleteValidator._documentSpecNameProperty.Name.Name, XmlCompleteValidator._documentSpecNameProperty.Name.Namespace); // if the inbound message has a namespace, if (contextProperty != null && contextProperty.Length > 0) { // clear the original schemas to validate against docSchemas.Clear(); string[] contextSchemas = contextProperty.Split(new char[] { '|' }); // set it's schemas foreach (string schemaName in contextSchemas) { docSchemas.Add(new Schema(schemaName)); } } #region retrieve validation schemas, shamelessly copied from the original XmlValidator pipeline component bool validateSchemas = this.DocumentSchemas != null && this.DocumentSchemas.Count > 0; if (validateSchemas && this.DocumentSchemas.Count == 1 && this.DocumentSchemas[0].SchemaName.Length == 0) { validateSchemas = false; } if (validateSchemas) { foreach (Schema s in docSchemas) { try { docSpec = pc.GetDocumentSpecByName(s.SchemaName); } catch (COMException e) { throw new XmlCompleteValidatorException( ExceptionType.CANNOT_GET_DOCSPEC_BY_NAME, e.ErrorCode.ToString("X") + ": " + e.Message, new string[] { s.SchemaName }); } if (docSpec == null) { throw new XmlCompleteValidatorException( ExceptionType.CANNOT_GET_DOCSPEC_BY_NAME, string.Empty, new string[] { s.SchemaName }); } XmlSchemaCollection coll = docSpec.GetSchemaCollection(); schemaCollection.Add(coll); } } else { try { docSpec = pc.GetDocumentSpecByType(Utils.GetDocType(eventingDataStream)); } catch (COMException e) { throw new XmlCompleteValidatorException( ExceptionType.CANNOT_GET_DOCSPEC_BY_TYPE, e.ErrorCode.ToString("X") + ": " + e.Message, new string[] { Utils.GetDocType(eventingDataStream) }); } if (docSpec == null) { throw new XmlCompleteValidatorException( ExceptionType.CANNOT_GET_DOCSPEC_BY_TYPE, string.Empty, new string[] { Utils.GetDocType(eventingDataStream) }); } schemaCollection = docSpec.GetSchemaCollection(); } #endregion // the most critical line within this component, assign an // XmlEventingValidationStream to ensure the inbound messagestream is validated // and events can be assigned which allow us to capture any erros that might occur XmlEventingValidationStream validatingStream = new XmlEventingValidationStream(eventingDataStream); // add the schemas we'd like to validate the inbound message against validatingStream.Schemas.Add(schemaCollection); // assign a validation event which will accumulate any errors within the inbound message validatingStream.ValidatingReader.ValidationEventHandler += new ValidationEventHandler(XmlMessageValidationCallBack); // and assign the AfterLastReadEvent, which fires upon reading the last piece of information // from the inbound message stream and pushes all accumulated error information out into // the eventviewer and onto the HAT context by throwing an exception which contains the errors validatingStream.AfterLastReadEvent += new AfterLastReadEventHandler(validatingStream_AfterLastReadEvent); // duplicate the inbound message part by creating a new one and copying it's properties IBaseMessageFactory messageFactory = pc.GetMessageFactory(); IBaseMessagePart messagePart = messageFactory.CreateMessagePart(); // if the inbound message exists and has a body part, copy the part properties // into the outbound messagepart if (inmsg != null && inmsg.BodyPart != null) { messagePart.PartProperties = PipelineUtil.CopyPropertyBag(inmsg.BodyPart.PartProperties, messageFactory); } // set the outbound charset messagePart.Charset = "UTF-8"; // set the outbound content type messagePart.ContentType = "text/xml"; // and assign the outbound datastream messagePart.Data = validatingStream; // finally, copy existing message parts CopyMessageParts(pc, inmsg, outmsg, messagePart, false); }
public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg) { string errorMessage; if (!Validate(out errorMessage)) { var ex = new ArgumentException(errorMessage); _instrumentationHelper.TrackComponentError(ex); throw ex; } var data = pInMsg.BodyPart.GetOriginalDataStream(); //Determine of the request body has any data. GET request will not have any body. var hasData = HasData(data); //Get a reference to the BizTalk schema. DocumentSpec documentSpec; try { documentSpec = (DocumentSpec)pContext.GetDocumentSpecByName(DocumentSpecName); } catch (COMException cex) { _instrumentationHelper.TrackComponentError(cex); throw cex; } //Get a list of properties defined in the schema. var annotations = documentSpec.GetPropertyAnnotationEnumerator(); var doc = new XmlDocument(); var sw = new StringWriter(new StringBuilder()); //Create a new instance of the schema. doc.Load(documentSpec.CreateXmlInstance(sw)); sw.Dispose(); //Write all properties to the message body. while (annotations.MoveNext()) { var annotation = (IPropertyAnnotation)annotations.Current; var node = doc.SelectSingleNode(annotation.XPath); object propertyValue; if (pInMsg.Context.TryRead(new ContextProperty(annotation.Name, annotation.Namespace), out propertyValue)) { node.InnerText = propertyValue.ToString(); } } var ms = new MemoryStream(); doc.Save(ms); ms.Seek(0, SeekOrigin.Begin); var outMsg = pInMsg; //If the request has a body it should be preserved an the query parameters should be written to it's own message part. if (hasData) { string msgType = GetMessageType(MakeMarkable(pInMsg.BodyPart.Data)); outMsg = pInMsg; outMsg.BodyPart.Data = pInMsg.BodyPart.Data; outMsg.Context = PipelineUtil.CloneMessageContext(pInMsg.Context); outMsg.Context.Promote(new ContextProperty(SystemProperties.MessageType), msgType); var factory = pContext.GetMessageFactory(); var queryPart = factory.CreateMessagePart(); queryPart.Data = ms; outMsg.AddPart("querypart", queryPart, false); } else { outMsg.BodyPart.Data = ms; //Promote message type and SchemaStrongName outMsg.Context.Promote(new ContextProperty(SystemProperties.MessageType), documentSpec.DocType); outMsg.Context.Promote(new ContextProperty(SystemProperties.SchemaStrongName), documentSpec.DocSpecStrongName); } _outputQueue.Enqueue(outMsg); _instrumentationHelper.TrackComponentSuccess(); }
public IBaseMessage GetNext(IPipelineContext pContext) { if (_reader == null) { return null; } if (!_reader.Read()) { _reader.Dispose(); _reader = null; return null; } StringBuilder xmlBuilder = new StringBuilder(); xmlBuilder.Append(@"<?xml version=""1.0"" ?>"); xmlBuilder.Append(@"<Messages xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns=""http://tempuri.net/ExcelUpload.Messages"">"); xmlBuilder.Append(@"<AddProduct>"); xmlBuilder.Append(@"<BatchId></BatchId>"); xmlBuilder.Append(@"<RegistrationIndex></RegistrationIndex>"); xmlBuilder.Append(@"<RegistrationsInBatch></RegistrationsInBatch>"); xmlBuilder.Append(@"<BatchSourcePath></BatchSourcePath>"); xmlBuilder.Append(@"<OriginatorDestination></OriginatorDestination>"); xmlBuilder.AppendFormat(@"<Name>{0}</Name>", _reader.GetString(0)); xmlBuilder.AppendFormat(@"<ProductNumber>{0}</ProductNumber>", _reader.GetString(1)); xmlBuilder.AppendFormat(@"<SafetyStockLevel>{0}</SafetyStockLevel>", _reader.GetInt32(2)); xmlBuilder.AppendFormat(@"<ReorderPoint>{0}</ReorderPoint>", _reader.GetInt32(3)); xmlBuilder.AppendFormat(@"<StandardCost>{0}</StandardCost>", _reader.GetDecimal(4)); xmlBuilder.AppendFormat(@"<ListPrice>{0}</ListPrice>", _reader.GetDecimal(5)); xmlBuilder.AppendFormat(@"<DaysToManufacture>{0}</DaysToManufacture>", _reader.GetInt32(6)); //write date in XSD format: xmlBuilder.AppendFormat(@"<SellStartDate>{0}</SellStartDate>", DateTime.FromOADate(_reader.GetDouble(7)).ToString("yyyy-MM-ddTHH:mm:ss.fffffff")); xmlBuilder.Append(@"</AddProduct>"); xmlBuilder.Append(@"</Messages>"); byte[] data = Encoding.UTF8.GetBytes(xmlBuilder.ToString()); MemoryStream memStream = new MemoryStream(data); IBaseMessagePart messagePart = pContext.GetMessageFactory().CreateMessagePart(); messagePart.Data = memStream; messagePart.ContentType = "text/xml"; messagePart.Charset = "utf-8"; IBaseMessage outMsg = pContext.GetMessageFactory().CreateMessage(); outMsg.AddPart("Body", messagePart, true); foreach (ContextProperty property in _contextProperties) { if (property.IsPromoted) outMsg.Context.Promote(property.Name, property.Namespace, property.Value); else outMsg.Context.Write(property.Name, property.Namespace, property.Value); } outMsg.Context.Promote("MessageType", "http://schemas.microsoft.com/BizTalk/2003/system-properties", "http://tempuri.net/ExcelUpload.Messages#Messages"); return outMsg; }
public IBaseMessage GetNext(IPipelineContext pContext) { if (_reader == null) { return(null); } if (!_reader.Read()) { _reader.Dispose(); _reader = null; return(null); } StringBuilder xmlBuilder = new StringBuilder(); xmlBuilder.Append(@"<?xml version=""1.0"" ?>"); xmlBuilder.Append(@"<Messages xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns=""http://tempuri.net/ExcelUpload.Messages"">"); xmlBuilder.Append(@"<AddProduct>"); xmlBuilder.Append(@"<BatchId></BatchId>"); xmlBuilder.Append(@"<RegistrationIndex></RegistrationIndex>"); xmlBuilder.Append(@"<RegistrationsInBatch></RegistrationsInBatch>"); xmlBuilder.Append(@"<BatchSourcePath></BatchSourcePath>"); xmlBuilder.Append(@"<OriginatorDestination></OriginatorDestination>"); xmlBuilder.AppendFormat(@"<Name>{0}</Name>", _reader.GetString(0)); xmlBuilder.AppendFormat(@"<ProductNumber>{0}</ProductNumber>", _reader.GetString(1)); xmlBuilder.AppendFormat(@"<SafetyStockLevel>{0}</SafetyStockLevel>", _reader.GetInt32(2)); xmlBuilder.AppendFormat(@"<ReorderPoint>{0}</ReorderPoint>", _reader.GetInt32(3)); xmlBuilder.AppendFormat(@"<StandardCost>{0}</StandardCost>", _reader.GetDecimal(4)); xmlBuilder.AppendFormat(@"<ListPrice>{0}</ListPrice>", _reader.GetDecimal(5)); xmlBuilder.AppendFormat(@"<DaysToManufacture>{0}</DaysToManufacture>", _reader.GetInt32(6)); //write date in XSD format: xmlBuilder.AppendFormat(@"<SellStartDate>{0}</SellStartDate>", DateTime.FromOADate(_reader.GetDouble(7)).ToString("yyyy-MM-ddTHH:mm:ss.fffffff")); xmlBuilder.Append(@"</AddProduct>"); xmlBuilder.Append(@"</Messages>"); byte[] data = Encoding.UTF8.GetBytes(xmlBuilder.ToString()); MemoryStream memStream = new MemoryStream(data); IBaseMessagePart messagePart = pContext.GetMessageFactory().CreateMessagePart(); messagePart.Data = memStream; messagePart.ContentType = "text/xml"; messagePart.Charset = "utf-8"; IBaseMessage outMsg = pContext.GetMessageFactory().CreateMessage(); outMsg.AddPart("Body", messagePart, true); foreach (ContextProperty property in _contextProperties) { if (property.IsPromoted) { outMsg.Context.Promote(property.Name, property.Namespace, property.Value); } else { outMsg.Context.Write(property.Name, property.Namespace, property.Value); } } outMsg.Context.Promote("MessageType", "http://schemas.microsoft.com/BizTalk/2003/system-properties", "http://tempuri.net/ExcelUpload.Messages#Messages"); return(outMsg); }
void IDisassemblerComponent.Disassemble(IPipelineContext pContext, IBaseMessage pInMsg) { if (pContext == null) { throw new ArgumentNullException("context"); } if (pInMsg == null) { throw new ArgumentNullException("inMsg"); } bool isFault = false; object objFault = pInMsg.Context.Read("IsFault", "http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties"); if (objFault != null) { isFault = (bool)objFault; } if (!isFault) { try { this._inputmessage = pInMsg; MultipartMessageDefinition netmsg = GetMessage(this._inputmessage); List <Part> partList = new List <Part>(netmsg.Parts); #region Obsolete /// Find body part //Part bodyPart = partList.Find(p => p.IsBodyPart == true); //if (bodyPart == null) //{ // partList[0].IsBodyPart = true; // bodyPart = partList[0]; //} #endregion //ContextProperty executePipeline = netmsg.PropertyBag.FirstOrDefault(prop => // prop.Namespace == BTSProperties.executePipeline.Name.Namespace // && prop.Name == BTSProperties.executePipeline.Name.Name); IBaseMessage sourceMessage = this.BuildBTSMessage(pContext, pInMsg.Context, partList); if (sourceMessage.BodyPart == null) { throw new Exception("No part was extracted from the mock message!"); } if (this.ExecutePipeline) { object tempInstance = Activator.CreateInstance(Type.GetType(this.PipelineToExecute)); Microsoft.BizTalk.PipelineOM.ReceivePipeline rcvPipeline = (Microsoft.BizTalk.PipelineOM.ReceivePipeline)tempInstance; IBasePropertyBag propBag = pContext.GetMessageFactory().CreatePropertyBag(); ExecutableRcvPipeline pipeline = new ExecutableRcvPipeline(rcvPipeline); pipeline.Run(pContext, sourceMessage); foreach (IBaseMessage outputMsg in pipeline.OutputMsgs) { this.attachPropetyBag(outputMsg, netmsg.PropertyBag); qOutputMsgs.Enqueue(outputMsg); } } else { this.attachPropetyBag(sourceMessage, netmsg.PropertyBag); qOutputMsgs.Enqueue(sourceMessage); } #region Obsolete //if (bodyPart.Data != null) //{ // string bodyType = bodyPart.Data.NamespaceURI + "#" + bodyPart.Data.LocalName; // XmlDocument xDoc = new System.Xml.XmlDocument(); // xDoc.LoadXml(bodyPart.Data.OuterXml); // System.IO.MemoryStream memStream = new MemoryStream(); // xDoc.PreserveWhitespace = true; // xDoc.Save(memStream); // memStream.Position = 0; // memStream.Seek(0, System.IO.SeekOrigin.Begin); // /// If Body part is an enveloppe, we have to split it // IDocumentSpec docSpec = pContext.GetDocumentSpecByType(bodyType); // XPathDocument xp = new XPathDocument(memStream); // if (!String.IsNullOrEmpty(docSpec.GetBodyPath())) // { // XPathNodeIterator xNI = xp.CreateNavigator().Select(docSpec.GetBodyPath()); // while (xNI.MoveNext()) // { // string nodeName = ""; // string nodeNamespace = ""; // if (xNI.Current.MoveToFirstChild()) // { // XmlDocument tempNode = new XmlDocument(); // tempNode.LoadXml(xNI.Current.OuterXml); // nodeName = tempNode.DocumentElement.LocalName; // nodeNamespace = tempNode.DocumentElement.NamespaceURI; // this.CreateMsg(pContext, pInMsg.Context, tempNode.OuterXml, bodyPart.PartName, netmsg.PropertyBag, partList.FindAll(p => p.IsBodyPart != true)); // } // while (xNI.Current.MoveToNext(nodeName, nodeNamespace)) // { // XmlDocument tempNode = new XmlDocument(); // tempNode.LoadXml(xNI.Current.OuterXml); // this.CreateMsg(pContext, pInMsg.Context, tempNode.OuterXml, bodyPart.PartName, netmsg.PropertyBag, partList.FindAll(p => p.IsBodyPart != true)); // } // } // } // else // { // this.CreateMsg(pContext, pInMsg.Context, bodyPart.Data.OuterXml, bodyPart.PartName, netmsg.PropertyBag, partList.FindAll(p => p.IsBodyPart != true)); // } //} //else //{ // this.CreateMsg(pContext, pInMsg.Context, bodyPart.RawData, bodyPart.PartName, netmsg.PropertyBag, partList.FindAll(p => p.IsBodyPart != true)); //} #endregion } catch (Exception e) { if (this.GetFault(pInMsg) != null) { qOutputMsgs.Enqueue(pInMsg); string faultText = this.GetFault(pInMsg).SelectSingleNode("/*[local-name()='Fault']/*[local-name()='faultstring']").InnerText; throw new Exception(faultText); } else { System.Diagnostics.EventLog.WriteEntry(Constants.EVENT_SOURCE, "IDisassemblerComponent.Disassemble : \n" + e.Message + "\n" + e.StackTrace, System.Diagnostics.EventLogEntryType.Error, 8000, 1); throw e; } } } else { qOutputMsgs.Enqueue(pInMsg); } }
/// <summary> /// Executes the custom runtime task component to process the input message and returns the result message. /// </summary> /// <param name="pContext">A reference to <see cref="Microsoft.BizTalk.Component.Interop.IPipelineContext"/> object that contains the current pipeline context.</param> /// <param name="pInMsg">A reference to <see cref="Microsoft.BizTalk.Message.Interop.IBaseMessage"/> object that contains the message to process.</param> /// <returns>A reference to the returned <see cref="Microsoft.BizTalk.Message.Interop.IBaseMessage"/> object which will contain the output message.</returns> public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { Guard.ArgumentNotNull(pContext, "pContext"); Guard.ArgumentNotNull(pInMsg, "pInMsg"); var callToken = TraceManager.PipelineComponent.TraceIn(); // It is OK to load the entire message into XML DOM. The size of these requests is anticipated to be very small. XDocument request = XDocument.Load(pInMsg.BodyPart.GetOriginalDataStream()); string transformName = (from childNode in request.Root.Descendants() where childNode.Name.LocalName == WellKnownContractMember.MessageParameters.TransformName select childNode.Value).FirstOrDefault <string>(); TraceManager.PipelineComponent.TraceInfo(TraceLogMessages.GetXslTransformRequest, transformName); IBaseMessagePart responsePart = BizTalkUtility.CreateResponsePart(pContext.GetMessageFactory(), pInMsg); XmlWriterSettings settings = new XmlWriterSettings(); MemoryStream dataStream = new MemoryStream(); pContext.ResourceTracker.AddResource(dataStream); settings.CloseOutput = false; settings.CheckCharacters = false; settings.ConformanceLevel = ConformanceLevel.Fragment; settings.NamespaceHandling = NamespaceHandling.OmitDuplicates; using (XmlWriter responseWriter = XmlWriter.Create(dataStream, settings)) { responseWriter.WriteResponseStartElement("r", WellKnownContractMember.MethodNames.GetXslTransformMetadata, WellKnownNamespace.ServiceContracts.General); try { Type transformType = ResolveTransformType(transformName); if (transformType != null) { // Get the actual map from the BizTalk metadata cache. BtsTransformMetadata btsTransform = BtsTransformMetadata.For(transformType); if (btsTransform != null) { // Map existence confirmed, now it's safe to instantiate the transform type. TransformBase transform = Activator.CreateInstance(transformType) as TransformBase; // Is this really a valid map that implements TransformBase? if (transform != null) { XslTransformMetadata transformMetadata = new XslTransformMetadata(transform.XmlContent, transform.XsltArgumentListContent, transform.SourceSchemas, transform.TargetSchemas); DataContractSerializer dcSerializer = new DataContractSerializer(typeof(XslTransformMetadata), String.Concat(WellKnownContractMember.MethodNames.GetXslTransformMetadata, WellKnownContractMember.ResultMethodSuffix), WellKnownNamespace.ServiceContracts.General); dcSerializer.WriteObject(responseWriter, transformMetadata); } } } } catch (Exception ex) { // Log but do not pass the exception to the caller. TraceManager.PipelineComponent.TraceError(ex); } responseWriter.WriteEndElement(); responseWriter.Flush(); } dataStream.Seek(0, SeekOrigin.Begin); responsePart.Data = dataStream; TraceManager.PipelineComponent.TraceOut(callToken); return(pInMsg); }
/// <summary> /// Clones a pipeline message creating an entirely independent and seekable copy. /// </summary> /// <param name="message">The message to be cloned.</param> /// <param name="pc">The pipeline context.</param> /// <returns>The cloned message.</returns> public static IBaseMessage Clone(this IBaseMessage message, IPipelineContext pc) { // Create the cloned message var messageFactory = pc.GetMessageFactory(); var clonedMessage = messageFactory.CreateMessage(); // Clone each part for (var partNo = 0; partNo < message.PartCount; partNo++) { string partName; var part = message.GetPartByIndex(partNo, out partName); // Create and initilialize the new part var newPart = messageFactory.CreateMessagePart(); newPart.Charset = part.Charset; newPart.ContentType = part.ContentType; // Get the original uncloned data stream var originalStream = part.GetOriginalDataStream(); // If the original data stream is non-seekable, check the clone // returned by the Data property, and failing that, or if the // clone is not seekablem manufacture a seekable stream. if (!originalStream.CanSeek) { Stream candidateSeekableStream; try { candidateSeekableStream = part.Data; } catch (NotSupportedException) { // Some streams (e.g. ICSharpCode.SharpZipLib.Zip.ZipInputStream) throw // a System.NotSupportedException when an attempt is made to clone them candidateSeekableStream = null; } if (candidateSeekableStream != null && !candidateSeekableStream.Equals(originalStream)) { if (candidateSeekableStream.CanSeek) { originalStream = candidateSeekableStream; } else { originalStream = new ReadOnlySeekableStream(candidateSeekableStream); } } else { originalStream = new ReadOnlySeekableStream(originalStream); } } // Add the original stream to the Resource tracker to prevent it being // disposed, in case we need to clone the same stream multiple times. pc.ResourceTracker.AddResource(originalStream); originalStream.StreamAtStart(); // Create the new part with a Virtual Stream, and add the the resource tracker newPart.Data = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk); pc.ResourceTracker.AddResource(newPart.Data); // Clone the stream, and seek back to the beginning originalStream.CopyTo(newPart.Data); originalStream.StreamAtStart(); // Create and populate the property bag for the new message part. newPart.Data.StreamAtStart(); newPart.PartProperties = messageFactory.CreatePropertyBag(); var partPoperties = part.PartProperties; for (var propertyNo = 0; propertyNo < partPoperties.CountProperties; propertyNo++) { string propertyName, propertyNamespace; var property = partPoperties.ReadAt(propertyNo, out propertyName, out propertyNamespace); newPart.PartProperties.Write(propertyName, propertyNamespace, property); } // Add the new part to the cloned message clonedMessage.AddPart(partName, newPart, partName == message.BodyPartName); } // Copy the context from old to new clonedMessage.Context = message.Context; return(clonedMessage); }