/// <summary> /// Checks seekability of the data stream in the body part of specified message and returns a new <see cref="Microsoft.BizTalk.Streaming.ReadOnlySeekableStream"/> /// stream should the original stream fail to support the Seek operation. /// </summary> /// <param name="msg">The message instance represented by the <see cref="Microsoft.BizTalk.Message.Interop.IBaseMessage"/> object.</param> /// <param name="pContext">A reference to <see cref="Microsoft.BizTalk.Component.Interop.IPipelineContext"/> object that contains the current pipeline context.</param> /// <returns>Either the original data stream or a new stream wrapping the original stream and providing support for the Seek operation, or a null reference if the specified message doesn't contain a body part.</returns> public static Stream EnsureSeekableStream(IBaseMessage msg, IPipelineContext pContext) { if (msg != null && msg.BodyPart != null) { Stream messageDataStream = msg.BodyPart.GetOriginalDataStream(); if (!messageDataStream.CanSeek) { Stream virtualStream = new VirtualStream(VirtualStreamBufferSize, VirtualStreamThresholdSize); pContext.ResourceTracker.AddResource(virtualStream); Stream seekableStream = new ReadOnlySeekableStream(messageDataStream, virtualStream, VirtualStreamBufferSize); msg.BodyPart.Data = seekableStream; return(seekableStream); } else { return(messageDataStream); } } else { return(null); } }
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { var contentReader = new ContentReader(); var data = pInMsg.BodyPart.GetOriginalDataStream(); if (!data.CanSeek || !data.CanRead) { const int bufferSize = 0x280; const int thresholdSize = 0x100000; data = new ReadOnlySeekableStream(data, new VirtualStream(bufferSize, thresholdSize), bufferSize); pContext.ResourceTracker.AddResource(data); } if (contentReader.IsXmlContent(data)) { var encoding = contentReader.Encoding(data); data = new XmlNamespaceRemover(data, encoding); pContext.ResourceTracker.AddResource(data); pInMsg.BodyPart.Data = data; } else { data.Seek(0, SeekOrigin.Begin); pInMsg.BodyPart.Data = data; } return(pInMsg); }
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { var contentReader = new ContentReader(); var data = pInMsg.BodyPart.GetOriginalDataStream(); if (!data.CanSeek || !data.CanRead) { const int bufferSize = 0x280; const int thresholdSize = 0x100000; data = new ReadOnlySeekableStream(data, new VirtualStream(bufferSize, thresholdSize), bufferSize); pContext.ResourceTracker.AddResource(data); } if (contentReader.IsXmlContent(data)) { var encoding = contentReader.Encoding(data); data = new ContentWriter().RemoveNamespace(data, encoding); pContext.ResourceTracker.AddResource(data); pInMsg.BodyPart.Data = data; } else { data.Seek(0, SeekOrigin.Begin); pInMsg.BodyPart.Data = data; } return pInMsg; }
public void TransactionalTask(IScheduledTaskStreamProvider2 provider) { //call GetStream CommittableTransaction transaction = null; Stream result = ((IScheduledTaskStreamProvider2)provider).GetStreams(this.adapterConfiguration.Task.TaskParameters, out transaction); if (result != null) { Batch batch = null; if (transaction != null) { batch = new ReceiveTxnBatch(transportProxy, controlledTermination, transaction, batchFinished, this.adapterConfiguration.SuspendMessage); } else { batch = new ReceiveBatch(transportProxy, controlledTermination, batchFinished, 0); } Stream readonlystream = new ReadOnlySeekableStream(result); IBaseMessageFactory messageFactory = this.transportProxy.GetMessageFactory(); IBaseMessage message = this.CreateMessage(messageFactory, readonlystream, this.adapterConfiguration.Name); batch.SubmitMessage(message, new StreamAndUserData(readonlystream, null)); batch.Done(); this.batchFinished.WaitOne(); ((IScheduledTaskStreamProvider2)provider).Done(batch.OverallSuccess); } }
/// <summary> /// Retrieve the contents of a message into a stream /// </summary> /// <param name="message"></param> /// <param name="bufferSize"></param> /// <param name="thresholdSize"></param> /// <returns></returns> public Stream ProcessRequestReturnStream(XLANGMessage message, int bufferSize, int thresholdSize) { Stream partStream = null; try { using (VirtualStream virtualStream = new VirtualStream(bufferSize, thresholdSize)) { using (partStream = (Stream)message[0].RetrieveAs(typeof(Stream))) //Note that when calling this code, if the XmlDocument is quite large, keeping it in a memory with a MemoryStream may have an adverse effect on performance. //In this case, it may be worthwhile to consider an approach that uses a VirtualStream + ReadonlySeekableStream to buffer it to the file system, //if its size is bigger than the thresholdSize parameter. //Keep in mind that: // - If the message size is smaller than the threshold size, the VirtualStream class buffers the stream to a MemoryStream. // - If the message size is bigger than the threshold size, the VirtualStream class buffers the stream to a temporary file. using (ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(partStream, virtualStream, bufferSize)) { using (XmlReader reader = XmlReader.Create(readOnlySeekableStream)) { } } } } catch (Exception ex) { throw ex; } finally { message.Dispose(); } return(partStream); }
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { string errorMessage; if (!Validate(out errorMessage)) { throw new ArgumentException(errorMessage); } String value = null; IBaseMessagePart bodyPart = pInMsg.BodyPart; Stream inboundStream = bodyPart.GetOriginalDataStream(); VirtualStream virtualStream = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk); ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream); XmlTextReader xmlTextReader = new XmlTextReader(readOnlySeekableStream); XPathCollection xPathCollection = new XPathCollection(); XPathReader xPathReader = new XPathReader(xmlTextReader, xPathCollection); xPathCollection.Add(XPath); while (xPathReader.ReadUntilMatch()) { if (xPathReader.Match(0)) { if (xPathReader.NodeType == XmlNodeType.Attribute) { value = xPathReader.GetAttribute(xPathReader.Name); } else { value = xPathReader.ReadString(); } if (PromoteProperty) { pInMsg.Context.Promote(new ContextProperty(PropertyPath), value); } else { pInMsg.Context.Write(new ContextProperty(PropertyPath), value); } break; } } if (string.IsNullOrEmpty(value) && ThrowIfNoMatch) { throw new InvalidOperationException("The specified XPath did not exist or contained an empty value."); } readOnlySeekableStream.Position = 0; pContext.ResourceTracker.AddResource(readOnlySeekableStream); bodyPart.Data = readOnlySeekableStream; return(pInMsg); }
/// <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) { string ActivityID = Guid.NewGuid().ToString(); string ShareLocation = "D:\\Share\\TrackingArchive\\"; // Should be an UNC Path with desired access granted to the User Account string FileExtension = ".txt"; string FullFilePath = ShareLocation + ActivityID + FileExtension; StringBuilder SBContext = new StringBuilder(); ReadOnlySeekableStream stream = new ReadOnlySeekableStream(inmsg.BodyPart.GetOriginalDataStream()); Stream sourceStream = inmsg.BodyPart.GetOriginalDataStream(); if (!sourceStream.CanSeek) { ReadOnlySeekableStream seekableStream = new ReadOnlySeekableStream(sourceStream); inmsg.BodyPart.Data = seekableStream; sourceStream = inmsg.BodyPart.Data; } if (inmsg.BodyPart != null) { VirtualStream virtualStream = new VirtualStream(sourceStream); PipelineHelper.ArchiveToFileLocation(virtualStream, FullFilePath); PipelineHelper.ArchivetoStorage(pc, inmsg, FullFilePath, true); sourceStream.Position = 0; inmsg.BodyPart.Data = sourceStream; inmsg.BodyPart.Data.Position = 0; } return(inmsg); #endregion }
/// <summary> /// retrieve xpath value for a list of xpath query /// </summary> /// <param name="pipelineContext">Pipeline context</param> /// <param name="inputMessage">Input message</param> /// <param name="primaryXPathEventSources">a list of xpath for belonging to the primary BAM activity</param> /// <param name="relatedXPathEventSources">a list of xpath for belonging to the related BAM activity</param> /// <returns></returns> private object GetXPathValue(IPipelineContext pipelineContext, IBaseMessage inputMessage, string xpath) { var result = (object)null; // create seekable stream to work on the message Stream messageStream = new ReadOnlySeekableStream(inputMessage.BodyPart.GetOriginalDataStream()); inputMessage.BodyPart.Data = messageStream; // save the stream position long position = messageStream.Position; // create an xml reader to prevent the xpath document from closing it XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreWhitespace = false; settings.CloseInput = false; using (XmlReader reader = XmlReader.Create(messageStream, settings)) { XPathDocument xpathDoc = new XPathDocument(reader); XPathNavigator xpathNav = xpathDoc.CreateNavigator(); result = EvaluateXPath(xpath, xpathNav); } // restore the stream position messageStream.Position = position; // prevent the message stream from being GC collected pipelineContext.ResourceTracker.AddResource(messageStream); return(result); }
public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg) { IBaseMessagePart bodyPart = pInMsg.BodyPart; Stream inboundStream = bodyPart.GetOriginalDataStream(); VirtualStream virtualStream = new VirtualStream(0x280, 0x100000); ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream, 0x280); string tempFile = Path.GetTempFileName(); using (FileStream fs = new FileStream(tempFile, FileMode.Open, FileAccess.Write, FileShare.Read)) { byte[] buffer = new byte[0x280]; int bytesRead = readOnlySeekableStream.Read(buffer, 0, buffer.Length); while (bytesRead != 0) { fs.Write(buffer, 0, bytesRead); fs.Flush(); bytesRead = readOnlySeekableStream.Read(buffer, 0, buffer.Length); } } VirtualStream outputStream = new VirtualStream(); using (XmlWriter xw = XmlWriter.Create(outputStream)) { const string NameSpace = "http://Codit.LFT.Schemas"; xw.WriteStartDocument(); xw.WriteStartElement("ns0", "LFT", NameSpace); xw.WriteElementString("TempFile", tempFile); xw.WriteEndDocument(); } outputStream.Position = 0; pContext.ResourceTracker.AddResource(outputStream); pInMsg.BodyPart.Data = outputStream; return pInMsg; }
public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg) { string errorMessage; if (!Validate(out errorMessage)) { throw new ArgumentException(errorMessage); } var data = pInMsg.BodyPart.GetOriginalDataStream(); const int bufferSize = 0x280; const int thresholdSize = 0x100000; if (!data.CanSeek || !data.CanRead) { data = new ReadOnlySeekableStream(data, new VirtualStream(bufferSize, thresholdSize), bufferSize); pContext.ResourceTracker.AddResource(data); } XmlTextReader xmlTextReader = new XmlTextReader(data); XPathCollection xPathCollection = new XPathCollection(); XPathReader xPathReader = new XPathReader(xmlTextReader, xPathCollection); xPathCollection.Add(Xpath); var ms = new MemoryStream(); int readBytes = 0; bool found = false; while (xPathReader.ReadUntilMatch()) { if (xPathReader.Match(0)) { var bw = new BinaryWriter(ms); byte[] buffer = new byte[bufferSize]; while ((readBytes = xPathReader.BaseReader.ReadElementContentAsBase64(buffer, 0, bufferSize)) > 0) { bw.Write(buffer); } bw.Flush(); found = true; break; } } if (!found) { throw new ArgumentException("Could not element at specified xpath"); } ms.Seek(0, SeekOrigin.Begin); ms.Position = 0; var docType = Microsoft.BizTalk.Streaming.Utils.GetDocType(new MarkableForwardOnlyEventingReadStream(ms)); pInMsg.Context.Promote(new ContextProperty(SystemProperties.MessageType), docType); pInMsg.BodyPart.Data = ms; _outputQueue.Enqueue(pInMsg); }
private void EndpointTask() { //Stream readonlystream = null; object provider = null; object taskArguments = null; try { try { Assembly streamProviderAssembly = Assembly.Load(this.properties.StreamProviderAssemblyName); provider = streamProviderAssembly.CreateInstance(this.properties.StreamProviderTypeName); } catch (Exception provderException) { transportProxy.SetErrorInfo(new ApplicationException("Error creating IScheduledTaskStreamProvider interface", provderException)); } if (provider != null) { //create GetStream argument object object [] args = new object [] {}; object result = provider.GetType().InvokeMember("GetParameterType", BindingFlags.InvokeMethod, null, provider, args); if (result != null) { StringReader strReader = new StringReader(this.properties.StreamProviderArguments); XmlSerializer serializer = new XmlSerializer((System.Type)result); taskArguments = serializer.Deserialize(strReader); } //call GetStream args = new object[] { taskArguments }; result = provider.GetType().InvokeMember("GetStream", BindingFlags.InvokeMethod, null, provider, args); if (result != null) { Stream readonlystream = new ReadOnlySeekableStream((Stream)result); IBaseMessageFactory messageFactory = this.transportProxy.GetMessageFactory(); IBTTransportBatch batch = transportProxy.GetBatch(this, null); IBaseMessage message = this.CreateMessage(messageFactory, readonlystream, this.properties.Name); batch.SubmitMessage(message); batch.Done(null); this.batchFinished.WaitOne(); } } } catch (Exception exception) { string errorMessage = exception.Message; //transportProxy.SetErrorInfo(exception); while (exception.InnerException != null) { exception = exception.InnerException; errorMessage += "\r\n" + exception.Message; } transportProxy.ReceiverShuttingdown(this.uri, new ScheduledException(errorMessage)); } }
public IBaseMessage Execute(IPipelineContext pipelineContext, IBaseMessage inputMessage, string objectArgument) { var callToken = TraceProvider.Logger.TraceIn(this.Name); try { byte CR = 13; byte LF = 10; byte EQ = 61; // get original stream Stream messageStream = new ReadOnlySeekableStream(inputMessage.BodyPart.GetOriginalDataStream()); messageStream.Seek(0, SeekOrigin.Begin); pipelineContext.ResourceTracker.AddResource(messageStream); using (FileStream fs = new FileStream(string.Format("c:\\temp\\{0}.{1}.txt", Guid.NewGuid().ToString(), DateTime.Now.Ticks), FileMode.CreateNew)) { while (true) { byte[] buffer = new byte[1024]; int m = messageStream.Read(buffer, 0, 1024); if (m > 0) { for (int j = 0; j < m; j++) { int i = Convert.ToInt32(buffer[j]); List <byte> newBuffer = new List <byte>(); newBuffer.Add(buffer[j]); newBuffer.Add(EQ); newBuffer.AddRange(Encoding.UTF8.GetBytes("" + i).ToList <byte>()); newBuffer.Add(CR); fs.Write(newBuffer.ToArray(), 0, newBuffer.Count); } } else { break; } } } originalMessage = inputMessage; return(inputMessage); } catch (Exception ex) { // put component name as a source information in this exception, // so the event log in message could reflect this ex.Source = this.Name; TraceProvider.Logger.TraceError(ex); throw ex; } finally { TraceProvider.Logger.TraceOut(callToken, this.Name); } }
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { String value = null; bool suspend = false; IBaseMessagePart bodyPart = pInMsg.BodyPart; Stream inboundStream = bodyPart.GetOriginalDataStream(); VirtualStream virtualStream = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk); ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream); XmlTextReader xmlTextReader = new XmlTextReader(readOnlySeekableStream); XPathCollection xPathCollection = new XPathCollection(); XPathReader xPathReader = new XPathReader(xmlTextReader, xPathCollection); xPathCollection.Add(XPath); while (xPathReader.ReadUntilMatch()) { if (xPathReader.Match(0)) { if (xPathReader.NodeType == XmlNodeType.Attribute) { value = xPathReader.GetAttribute(xPathReader.Name); } else { value = xPathReader.ReadString(); } break; } } suspend = ScriptExpressionHelper.ValidateExpression(value, Expression); if (suspend) { readOnlySeekableStream.Position = 0; pContext.ResourceTracker.AddResource(readOnlySeekableStream); bodyPart.Data = readOnlySeekableStream; pInMsg.Context.Write("SuspendAsNonResumable", "http://schemas.microsoft.com/BizTalk/2003/system-properties", true); pInMsg.Context.Write("SuppressRoutingFailureDiagnosticInfo", "http://schemas.microsoft.com/BizTalk/2003/system-properties", true); throw new Exception(String.Format("Expression {0} {1} did not evaluate to true", value, Expression)); } else { pInMsg = null; } return(pInMsg); }
/// <summary> /// Archives the input message into the specified archiving location. /// </summary> /// <param name="pipelineContext">Pipeline context</param> /// <param name="inputMessage">Input message</param> /// <returns>Original input message</returns> protected override IBaseMessage Execute(IPipelineContext pipelineContext, IBaseMessage inputMessage) { TraceProvider.Logger.TraceInfo("Archiving Message Start..."); if (IsEnabled(inputMessage)) { // get original stream Stream messageStream = inputMessage.BodyPart.GetOriginalDataStream(); if (inputMessage.BodyPart != null) { try { //Get Message Id Guid msgId = inputMessage.MessageID; // create seekable stream to work on the message messageStream = new ReadOnlySeekableStream(messageStream); inputMessage.BodyPart.Data = messageStream; long position = messageStream.Position; //Get Provider var provider = GetProvider(); //Check if Db Archive is enabled if (IsArchiveToDb) { TraceProvider.Logger.TraceInfo("Archiving Message to DB"); string xmlStringProperties = GetMessageProperties(inputMessage.Context); ArchiveToDb(provider, inputMessage.BodyPart.Data, xmlStringProperties, msgId); } //Archive to File if (IsArchiveToFile) { TraceProvider.Logger.TraceInfo("Archiving Message to File"); ArchiveToFile(provider, msgId, inputMessage.Context, inputMessage.BodyPart.Data, inputMessage); } // restore the stream position messageStream.Position = position; // prevent the message stream from being GC collected pipelineContext.ResourceTracker.AddResource(messageStream); } catch (Exception exc) { TraceProvider.Logger.TraceError("BizTalk Message Archiving Component", "Encountered an error: '{0}' : '{1}'", exc.Message, exc.ToString()); } // get original stream inputMessage.BodyPart.Data.Seek(0, SeekOrigin.Begin); } else { TraceProvider.Logger.TraceInfo("Message has no body part, exiting"); } } TraceProvider.Logger.TraceInfo("Archiving Message Exit."); // return original message return(inputMessage); }
/// <summary> /// ReadOnlySeekableStream from IBaseMessage /// </summary> /// <param name="msg"></param> /// <returns></returns> private ReadOnlySeekableStream GetSeekableStream(IBaseMessage msg) { Stream inboundStream = msg.BodyPart.GetOriginalDataStream(); VirtualStream virtualStream = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk); ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream); readOnlySeekableStream.Position = 0; readOnlySeekableStream.Seek(0, SeekOrigin.Begin); return(readOnlySeekableStream); }
/// <summary> /// Set property from XPath /// </summary> /// <param name="pContext"></param> /// <param name="pInMsg"></param> /// <returns></returns> public IBaseMessage ExecuteTwo(IPipelineContext pContext, IBaseMessage pInMsg) { string errorMessage; //this error Message can be got from validate the message //if (!XmlHelper.Validate(out errorMessage)) //{ // throw new ArgumentException(errorMessage); //} String value = null; IBaseMessagePart bodyPart = pInMsg.BodyPart; Stream inboundStream = bodyPart.GetOriginalDataStream(); VirtualStream virtualStream = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk); ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream); XmlTextReader xmlTextReader = new XmlTextReader(readOnlySeekableStream); //XPathCollection xPathCollection = new XPathCollection(); //XPathReader xPathReader = new XPathReader(xmlTextReader, xPathCollection); //xPathCollection.Add(XPath); //while (xPathReader.ReadUntilMatch()) //{ // if (xPathReader.Match(0)) // { // value = xPathReader.ReadString(); // //if (PromoteProperty) // //{ // // pInMsg.Context.Promote(new ContextProperty(PropertyPath), value); // //} // //else // //{ // // pInMsg.Context.Write(new ContextProperty(PropertyPath), value); // //} // //break; // } //} //if (string.IsNullOrEmpty(value) && ThrowIfNoMatch) //{ // throw new InvalidOperationException("The specified XPath did not exist or contained an empty value."); //} readOnlySeekableStream.Position = 0; pContext.ResourceTracker.AddResource(readOnlySeekableStream); bodyPart.Data = readOnlySeekableStream; return(pInMsg); }
private ReadOnlySeekableStream GetSeekableStream(IBaseMessage msg) { Stream inboundStream = msg.BodyPart.GetOriginalDataStream(); VirtualStream virtualStream = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk); ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream); readOnlySeekableStream.Position = 0; readOnlySeekableStream.Seek(0, SeekOrigin.Begin); return readOnlySeekableStream; }
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { string errorMessage; if (!Validate(out errorMessage)) { throw new ArgumentException(errorMessage); } String value = null; IBaseMessagePart bodyPart = pInMsg.BodyPart; Stream inboundStream = bodyPart.GetOriginalDataStream(); VirtualStream virtualStream = new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk); ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream); XmlTextReader xmlTextReader = new XmlTextReader(readOnlySeekableStream); XPathCollection xPathCollection = new XPathCollection(); XPathReader xPathReader = new XPathReader(xmlTextReader, xPathCollection); xPathCollection.Add(XPath); while (xPathReader.ReadUntilMatch()) { if (xPathReader.Match(0)) { value = xPathReader.ReadString(); if (PromoteProperty) { pInMsg.Context.Promote(new ContextProperty(PropertyPath), value); } else { pInMsg.Context.Write(new ContextProperty(PropertyPath), value); } break; } } if (string.IsNullOrEmpty(value) && ThrowIfNoMatch) { throw new InvalidOperationException("The specified XPath did not exist or contained an empty value."); } readOnlySeekableStream.Position = 0; pContext.ResourceTracker.AddResource(readOnlySeekableStream); bodyPart.Data = readOnlySeekableStream; return pInMsg; }
/// <summary> /// Returns a seekable version of a message's data stream. The stream will be wrapped in a ReadOnlySeekableDataStream if needed. /// </summary> /// <param name="pipelineContext">The pipeline context of the message.</param> /// <param name="messagePart">The message part for which a seekable stream is required.</param> /// <returns>A seekable version of the message stream.</returns> public static Stream GetReadOnlySeekableDataStream(IPipelineContext pipelineContext, IBaseMessagePart messagePart) { Stream dataStream = messagePart.GetOriginalDataStream(); if (!dataStream.CanSeek) { ReadOnlySeekableStream seekableStream = new ReadOnlySeekableStream(dataStream); messagePart.Data = seekableStream; pipelineContext.ResourceTracker.AddResource(seekableStream); dataStream = seekableStream; } return(dataStream); }
public void getCorrelationTokens(IBaseMessage msg, CorrelationToken[] correlationToken) { foreach (var prp in correlationToken) { if (prp.isContext == true) { prp.value = msg.Context.Read(prp.propertyName, prp.propertynamespace).ToString(); } else { Stream MsgStream = msg.BodyPart.GetOriginalDataStream(); if (!MsgStream.CanSeek) { ReadOnlySeekableStream readStream = new ReadOnlySeekableStream(MsgStream); msg.BodyPart.Data = readStream; MsgStream = readStream; } XmlReaderSettings settings = new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document, IgnoreWhitespace = true, ValidationType = ValidationType.None, IgnoreProcessingInstructions = true, IgnoreComments = true, CloseInput = false }; MsgStream.Seek(0, SeekOrigin.Begin); XmlReader reader = XmlReader.Create(MsgStream, settings); //string strValue = null; // if (!string.IsNullOrEmpty(prp.xPath)) { if (reader.Read()) { XPathDocument xPathDoc = new XPathDocument(reader); XPathNavigator xNavigator = xPathDoc.CreateNavigator(); //foreach (var prpo in CustomTrackProp[0].propertyList) //{ XPathNodeIterator xNodes = xNavigator.Select(prp.xPath); if (xNodes.Count != 0 && xNodes.MoveNext()) { prp.value = xNodes.Current.Value; } } MsgStream.Seek(0, SeekOrigin.Begin); } } } } //Business Layer
/// <summary> /// Setup Message Content Query for filtering messages /// </summary> /// <param name="pContext"></param> /// <param name="pInMsg"></param> private void SetupMessageContentQuery(IPipelineContext pContext, ref IBaseMessage pInMsg) { //make sure the stream is seekable, otherwise, wrap it in seekable stream System.IO.Stream streamWrapper = pInMsg.BodyPart.GetOriginalDataStream(); if (!pInMsg.BodyPart.GetOriginalDataStream().CanSeek) { streamWrapper = new ReadOnlySeekableStream(pInMsg.BodyPart.GetOriginalDataStream()); pInMsg.BodyPart.Data = streamWrapper; pContext.ResourceTracker.AddResource(streamWrapper); } //clone the stream to prevent XPathNavigator closing the stream System.IO.Stream streamClone = new System.IO.MemoryStream(Encoding.UTF8.GetBytes(new System.IO.StreamReader(streamWrapper).ReadToEnd())); streamClone.Seek(0, System.IO.SeekOrigin.Begin); System.Xml.XPath.XPathNavigator navigator = new System.Xml.XPath.XPathDocument(streamClone).CreateNavigator(); //perform the queries System.Xml.XPath.XPathExpression query = null; if (!string.IsNullOrEmpty(XPathQuery1)) { query = navigator.Compile(XPathQuery1); isQuery1FoundAndMatch = Convert.ToBoolean(navigator.Evaluate(query)); } if (!string.IsNullOrEmpty(XPathQuery2)) { query = navigator.Compile(XPathQuery2); isQuery2FoundAndMatch = Convert.ToBoolean(navigator.Evaluate(query)); } if (!string.IsNullOrEmpty(XPathQuery3)) { query = navigator.Compile(XPathQuery3); isQuery3FoundAndMatch = Convert.ToBoolean(navigator.Evaluate(query)); } if (!string.IsNullOrEmpty(XPathQuery4)) { query = navigator.Compile(XPathQuery4); isQuery4FoundAndMatch = Convert.ToBoolean(navigator.Evaluate(query)); } if (!string.IsNullOrEmpty(XPathQuery5)) { query = navigator.Compile(XPathQuery5); isQuery5FoundAndMatch = Convert.ToBoolean(navigator.Evaluate(query)); } streamWrapper.Seek(0, System.IO.SeekOrigin.Begin); pContext.ResourceTracker.AddResource(streamWrapper); }
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { string errorMessage; if (!Validate(out errorMessage)) { throw new ArgumentException(errorMessage); } var contentReader = new ContentReader(); var data = pInMsg.BodyPart.GetOriginalDataStream(); const int bufferSize = 0x280; const int thresholdSize = 0x100000; if (!data.CanSeek || !data.CanRead) { data = new ReadOnlySeekableStream(data, new VirtualStream(bufferSize, thresholdSize), bufferSize); pContext.ResourceTracker.AddResource(data); } if (contentReader.IsXmlContent(data) && contentReader.NamespacExists(data, NamespaceToModify)) { var encoding = contentReader.Encoding(data); data = new XmlNamespaceModifier(data, encoding, NewNamespace, null, NamespaceToModify); data = new ReadOnlySeekableStream(data, new VirtualStream(bufferSize, thresholdSize), bufferSize); pContext.ResourceTracker.AddResource(data); pInMsg.BodyPart.Data = data; if (ShouldUpdateMessageTypeContext) { var rootName = contentReader.GetRootNode(data); var contextReader = new ContextReader(); contextReader.UpdateMessageTypeContext(pInMsg.Context, NewNamespace, rootName); } } else { data.Seek(0, SeekOrigin.Begin); pInMsg.BodyPart.Data = data; } return(pInMsg); }
/// <summary> /// Creates a new message with some notification description, /// and adds it to the BatchMessage /// </summary> /// <param name="uri"></param> /// <returns></returns> internal IBaseMessage CreateEmptyBatchMessage(string uri) { try { //string errorMessageFormat = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Error message=\"Empty Batch\" datetime=\"{0}\" source=\"{1}\"/>"; string errorMessageFormat = "<bLogical:EmptyBatch message=\"Empty Batch\" datetime=\"{0}\" source=\"{1}\" xmlns:bLogical=\"http://Blogical.Shared.Adapters.Sftp.Schemas.EmptyBatch\" />"; string errorMessage = String.Format(errorMessageFormat, DateTime.Now.ToString(), uri); UTF8Encoding utf8Encoding = new UTF8Encoding(); byte[] messageBuffer = utf8Encoding.GetBytes(errorMessage); MemoryStream ms = new MemoryStream(messageBuffer.Length); ms.Write(messageBuffer, 0, messageBuffer.Length); ms.Position = 0; ReadOnlySeekableStream ross = new ReadOnlySeekableStream(ms); IBaseMessageFactory messageFactory = _transportProxy.GetMessageFactory(); IBaseMessagePart part = messageFactory.CreateMessagePart(); part.Data = ross; var message = messageFactory.CreateMessage(); message.AddPart(MessageBody, part, true); SystemMessageContext context = new SystemMessageContext(message.Context) { InboundTransportLocation = uri, InboundTransportType = _transportType }; //Write/Promote any adapter specific properties on the message context message.Context.Write(Remotefilename, _propertyNamespace, Emptybatchfilename); // Add the file to the batch Files.Add(new BatchMessage(message, Emptybatchfilename, BatchOperationType.Submit)); // Add the size of the file to the stream message.BodyPart.Data.SetLength(ms.Length); ms.Close(); return(message); } catch (Exception) { return(null); } }
/// <summary> /// Setup the BREPipelineMetaInstructionCollection by copying over the body and context from the input message /// </summary> private void SetupBREPipelineMetaInstructionCollection(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg) { _BREPipelineMetaInstructionCollection = new BREPipelineMetaInstructionCollection(_XMLFactsApplicationStage, instructionExecutionOrder, partNames, callToken); _BREPipelineMetaInstructionCollection.Pc = pc; // Create a copy of the original body part and copy over it's properties as well IBaseMessagePart copiedBodyPart = pc.GetMessageFactory().CreateMessagePart(); string streamType = inmsg.BodyPart.Data.GetType().ToString(); TraceManager.PipelineComponent.TraceInfo("{0} - Inbound message body had a stream type of {1}", callToken, streamType); // If the input stream is not seekable then wrap it with a ReadOnlySeekableStream so that it can have it's position set if (!inmsg.BodyPart.GetOriginalDataStream().CanSeek) { TraceManager.PipelineComponent.TraceInfo("{0} - Inbound message body stream was not seekable so wrapping it with a ReadOnlySeekableStream", callToken); ReadOnlySeekableStream seekableDataStream = new ReadOnlySeekableStream(inmsg.BodyPart.GetOriginalDataStream()); originalStream = seekableDataStream; pc.ResourceTracker.AddResource(seekableDataStream); } else { TraceManager.PipelineComponent.TraceInfo("{0} - Inbound message body stream was seekable so no need to wrap it", callToken); originalStream = inmsg.BodyPart.GetOriginalDataStream(); } //Explicitly set the stream position to 0 in case the position was shifted while referencing it originalStream.Position = 0; pc.ResourceTracker.AddResource(originalStream); copiedBodyPart.Data = originalStream; ReadStreamIfNecessary(pc, inmsg, copiedBodyPart, streamType); //Copy over part properties copiedBodyPart.PartProperties = inmsg.BodyPart.PartProperties; // Create a new message in the _BREPipelineMetaInstructionCollection and copy over the body and any additional parts _BREPipelineMetaInstructionCollection.InMsg = pc.GetMessageFactory().CreateMessage(); CopyMessageParts(inmsg, _BREPipelineMetaInstructionCollection.InMsg, copiedBodyPart); // Copy over context by reference, this is to ensure that context isn't lost if using an XML Disassembler prior to BRE component // and not reading the stream prior to cloning context _BREPipelineMetaInstructionCollection.InMsg.Context = inmsg.Context; }
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { string errorMessage; if (!Validate(out errorMessage)) { throw new ArgumentException(errorMessage); } var contentReader = new ContentReader(); var data = pInMsg.BodyPart.GetOriginalDataStream(); if (!data.CanSeek || !data.CanRead) { const int bufferSize = 0x280; const int thresholdSize = 0x100000; data = new ReadOnlySeekableStream(data, new VirtualStream(bufferSize, thresholdSize), bufferSize); pContext.ResourceTracker.AddResource(data); } if (contentReader.IsXmlContent(data) && contentReader.NamespacExists(data, NamespaceToModify)) { var encoding = contentReader.Encoding(data); data = new ContentWriter().ModifyNamespace(data, NamespaceToModify, NewNamespace, encoding); pContext.ResourceTracker.AddResource(data); pInMsg.BodyPart.Data = data; if (ShouldUpdateMessageTypeContext) { var rootName = contentReader.GetRootNode(data); var contextReader = new ContextReader(); contextReader.UpdateMessageTypeContext(pInMsg.Context, NewNamespace, rootName); } } else { data.Seek(0, SeekOrigin.Begin); pInMsg.BodyPart.Data = data; } return pInMsg; }
/* * /// <summary> * /// Populate a stream from an XML Document. * /// </summary> * /// <param name="stream">The stream to be populated.</param> * /// <param name="originalStream">The original stream containing the content.</param> * /// <returns>A stream populated from an XML document.</returns> * public static Stream PopulateFromStream(this Stream stream, Stream originalStream) * { * return originalStream == null || stream == null ? new MemoryStream() : originalStream.Clone(); * } */ /// <summary> /// Seeks back to the origin of a stream. /// </summary> /// <param name="stream">A stream.</param> /// <returns>A seekable stream set at its origin.</returns> public static Stream StreamAtStart(this Stream stream) { var outStream = stream; if (outStream == null) { return(null); } if (!outStream.CanSeek) { // If the stream is not seekable, create a seekable stream over a virtual stream to provide buffering and large message handling outStream = new ReadOnlySeekableStream(stream, new VirtualStream(VirtualStream.MemoryFlag.AutoOverFlowToDisk), 0x1000); } outStream.Position = 0; return(outStream); }
private bool HasData(Stream data) { byte[] buffer = new byte[10]; const int bufferSize = 0x280; const int thresholdSize = 0x100000; if (!data.CanSeek || !data.CanRead) { data = new ReadOnlySeekableStream(data, new VirtualStream(bufferSize, thresholdSize), bufferSize); } int num = data.Read(buffer, 0, buffer.Length); data.Seek(0, SeekOrigin.Begin); data.Position = 0; return(num > 0); }
public void NonTransactionalTask(IScheduledTaskStreamProvider provider) { //call GetStream Stream result = ((IScheduledTaskStreamProvider)provider).GetStream(this.adapterConfiguration.Task.TaskParameters); if (result != null) { Stream readonlystream = new ReadOnlySeekableStream(result); ReceiveBatch batch = new ReceiveBatch(transportProxy, controlledTermination, batchFinished, 0); IBaseMessageFactory messageFactory = this.transportProxy.GetMessageFactory(); IBaseMessage message = this.CreateMessage(messageFactory, readonlystream, this.adapterConfiguration.Name); batch.SubmitMessage(message, new StreamAndUserData(readonlystream, null)); batch.Done(); this.batchFinished.WaitOne(); } }
private static Stream GetSeekeableMessageStream(IBaseMessage message) { var messageStream = message.BodyPart.GetOriginalDataStream(); if (messageStream.CanSeek) { return(messageStream); } // Create a virtual and seekable stream const int bufferSize = 0x280; const int thresholdSize = 0x100000; Stream virtualReadStream = new VirtualStream(bufferSize, thresholdSize); Stream seekableReadStream = new ReadOnlySeekableStream(messageStream, virtualReadStream, bufferSize); messageStream = seekableReadStream; message.BodyPart.Data = messageStream; return(messageStream); }
}//DataLayer public void ArchiveMessage(IBaseMessage msg, ActivityInfo activityInfo) { if (!msg.BodyPart.Data.CanSeek) { ReadOnlySeekableStream seekableStream = new ReadOnlySeekableStream(msg.BodyPart.Data); msg.BodyPart.Data = seekableStream; } if (msg.BodyPart != null) { byte[] messageBody = new byte[msg.BodyPart.Data.Length]; msg.BodyPart.Data.Read(messageBody, 0, (int)msg.BodyPart.Data.Length); string contextProperties = ReadProperties(msg); ArchiveMessage(messageBody, contextProperties, _activityInfo); msg.BodyPart.Data.Position = 0; } }//Business Layer
public static Dictionary <string, string> SelectMultiple(this IBaseMessage pInMsg, params string[] xPaths) { Stream inboundStream = pInMsg.BodyPart.GetOriginalDataStream(); var virtualStream = new VirtualStream(); var readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream); readOnlySeekableStream.Seek(0, SeekOrigin.Begin); var xmlTextReader = new XmlTextReader(readOnlySeekableStream); var xPathCollection = new XPathCollection(); //Keep track of the mapping between XPaths and their position in the XPathCollection var indexToXPathMap = new Dictionary <int, string>(); foreach (var xPath in xPaths) { int index = xPathCollection.Add(xPath); indexToXPathMap.Add(index, xPath); } var xPathReader = new XPathReader(xmlTextReader, xPathCollection); var xPathToValueMap = new Dictionary <string, string>(); while (xPathReader.ReadUntilMatch()) { string value = xPathReader.NodeType == XmlNodeType.Attribute ? xPathReader.GetAttribute(xPathReader.Name) : xPathReader.ReadString(); //Which XPath triggered the match int index = indexToXPathMap.Keys.First(x => xPathReader.Match(x)); //Only return the first match for each XPath if (!xPathToValueMap.ContainsKey(indexToXPathMap[index])) { xPathToValueMap.Add(indexToXPathMap[index], value); } } readOnlySeekableStream.Seek(0, SeekOrigin.Begin); return(xPathToValueMap); }
/// <summary> /// Archives the input message into the specified archiving location. /// </summary> /// <param name="pipelineContext">Pipeline context</param> /// <param name="inputMessage">Input message</param> /// <returns>Original input message</returns> protected override IBaseMessage Execute(IPipelineContext pipelineContext, IBaseMessage inputMessage) { if (inputMessage.BodyPart != null) { // expand macros and build the archive file path this.auditFileFullPath = this.GetAuditFilePath(inputMessage); // get original stream Stream messageStream = inputMessage.BodyPart.GetOriginalDataStream(); // check if the optimized flag is on bool optimized = inputMessage.Context.Read <bool>(ArchiverProperties.Optimized.Name, ArchiverProperties.Optimized.Namespace, this.Optimized); TraceProvider.Logger.TraceInfo("Auditing file: Optimized = {0}; FilePath = {1}", optimized, this.auditFileFullPath); if (optimized == true) { // create a forward-only eventing stream messageStream = this.CreateForwardOnlyEventingStream(messageStream); inputMessage.BodyPart.Data = messageStream; } else { // create seekable stream to work on the message messageStream = new ReadOnlySeekableStream(messageStream); inputMessage.BodyPart.Data = messageStream; // save the stream position long position = messageStream.Position; // copy stream to file this.CopyStreamToFile(messageStream); // restore the stream position messageStream.Position = position; } // prevent the message stream from being GC collected pipelineContext.ResourceTracker.AddResource(messageStream); } else { TraceProvider.Logger.TraceInfo("Message has no body part, exiting"); } // return original message return(inputMessage); }
/// <summary> /// Determine whether the message being probed exists in our assembly /// </summary> /// <param name="messageType"></param> /// <returns></returns> //private bool CanHandleMessage(string messageType, string docSpecName) //{ // bool canHandle = false; // //query the biztalk management database to see if the messageType is defined in our Assembly (actually our docSpecName) // SqlDbHelper. //} /// <summary> /// Read the incoming message to determine the messageType /// </summary> /// <param name="inMsg">The Biztalk Message to read</param> /// <returns>The messageType (namespace+rootnodename)</returns> private string GetMessageType(Microsoft.BizTalk.Message.Interop.IBaseMessage inMsg, out string rootNodeName) { string messageType = string.Empty; //string messageType = (string)inMsg.Context.Read("MessageType", MessageContext.SystemPropertiesNamespace); //if (messageType != null) //{ // return messageType; //} //read the message body to determine rootnode and namespace //Wrap the originalStream in a seekable stream so that position can be rewound to 0 before returning var originalStream = inMsg.BodyPart.GetOriginalDataStream(); Stream seekableStream; if (!originalStream.CanSeek) { seekableStream = new ReadOnlySeekableStream(originalStream); inMsg.BodyPart.Data = seekableStream; } else { seekableStream = originalStream; } //Stream that will be set to the xml extracted from the incoming message using (var copiedStream = new MemoryStream()) { seekableStream.CopyTo(copiedStream); copiedStream.Position = 0; seekableStream.Position = 0; XDocument xDoc = XDocument.Load(copiedStream); messageType = string.Format("{0}#{1}", xDoc.Root.Name.NamespaceName, xDoc.Root.Name.LocalName); rootNodeName = xDoc.Root.Name.LocalName; } //_logger.DebugFormat("XmlSchemaResolver:: GetMessageType: Processing Message, determined message type {0}", messageType); return(messageType); }
public Microsoft.BizTalk.Message.Interop.IBaseMessage ExecuteThree(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg) { IBaseMessagePart bodyPart = pInMsg.BodyPart; Stream inboundStream = bodyPart.GetOriginalDataStream(); VirtualStream virtualStream = new VirtualStream(0x280, 0x100000); ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream, 0x280); XmlTextReader xmlTextReader = new XmlTextReader(readOnlySeekableStream); //XPathCollection xPathCollection = new XPathCollection(); //xPathCollection.Add("/*[local-name()='LFT' and namespace-uri()='http://Codit.LFT.Schemas']/*[local-name()='TempFile' and namespace-uri()='']"); //XPathReader xPathReader = new XPathReader(xmlTextReader, xPathCollection); bool ok = false; string val = string.Empty; //while (xPathReader.ReadUntilMatch()) //{ // if (xPathReader.Match(0) && !ok) // { // val = xPathReader.ReadString(); // ok = true; // } //} if (ok) { VirtualStream outboundStream = new VirtualStream(0x280, 0xA00000); using (FileStream fs = new FileStream(val, FileMode.Open, FileAccess.Read, FileShare.Read)) { byte[] buffer = new byte[4096]; int bytesRead = fs.Read(buffer, 0, buffer.Length); while (bytesRead != 0) { outboundStream.Write(buffer, 0, bytesRead); outboundStream.Flush(); bytesRead = fs.Read(buffer, 0, buffer.Length); } } outboundStream.Position = 0; bodyPart.Data = outboundStream; } return(pInMsg); }
public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg) { IBaseMessagePart bodyPart = pInMsg.BodyPart; Stream inboundStream = bodyPart.GetOriginalDataStream(); VirtualStream virtualStream = new VirtualStream(0x280, 0x100000); ReadOnlySeekableStream readOnlySeekableStream = new ReadOnlySeekableStream(inboundStream, virtualStream, 0x280); XmlTextReader xmlTextReader = new XmlTextReader(readOnlySeekableStream); XPathCollection xPathCollection = new XPathCollection(); xPathCollection.Add("/*[local-name()='LFT' and namespace-uri()='http://Codit.LFT.Schemas']/*[local-name()='TempFile' and namespace-uri()='']"); XPathReader xPathReader = new XPathReader(xmlTextReader, xPathCollection); bool ok = false; string val = string.Empty; while (xPathReader.ReadUntilMatch()) { if (xPathReader.Match(0) && !ok) { val = xPathReader.ReadString(); ok = true; } } if (ok) { VirtualStream outboundStream = new VirtualStream(0x280, 0xA00000); using (FileStream fs = new FileStream(val, FileMode.Open, FileAccess.Read, FileShare.Read)) { byte[] buffer = new byte[4096]; int bytesRead = fs.Read(buffer, 0, buffer.Length); while (bytesRead != 0) { outboundStream.Write(buffer, 0, bytesRead); outboundStream.Flush(); bytesRead = fs.Read(buffer, 0, buffer.Length); } } outboundStream.Position = 0; bodyPart.Data = outboundStream; } return pInMsg; }
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg) { var contentReader = new ContentReader(); const int bufferSize = 0x280; const int thresholdSize = 0x100000; Stream virtualStream = new VirtualStream(bufferSize, thresholdSize); Stream data = new ReadOnlySeekableStream(pInMsg.BodyPart.GetOriginalDataStream(), virtualStream, bufferSize); if (contentReader.IsXmlContent(data)) { var encoding = contentReader.Encoding(data); pInMsg.BodyPart.Data = new ContentWriter().RemoveNamespace(data, encoding); } else { data.Seek(0, SeekOrigin.Begin); pInMsg.BodyPart.Data = data; } return(pInMsg); }
/// <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 Handle CORS Requests // Detect of the incoming message is an HTTP CORS request // http://www.w3.org/TR/cors/ // If it is, we will promote both the RouteDirectToTP property and the // EpmRRCorrelationToken so that the request is immediately routed // back to the send pipeline of this receive port object httpMethod = null; httpMethod = inmsg.Context.Read(HTTP_METHOD_PROPNAME, WCF_PROPERTIES_NS); if (httpMethod != null && (httpMethod as string) == OPTIONS_METHOD) { object curCorrToken = inmsg.Context.Read(EPM_RR_CORRELATION_TOKEN_PROPNAME, SYSTEM_PROPERTIES_NS); inmsg.Context.Promote(EPM_RR_CORRELATION_TOKEN_PROPNAME, SYSTEM_PROPERTIES_NS, curCorrToken); inmsg.Context.Promote(ROUTE_DIRECT_TO_TP_PROPNAME, SYSTEM_PROPERTIES_NS, true); var corsDoc = new XmlDocument(); corsDoc.AppendChild(corsDoc.CreateElement(DEFAULT_PREFIX, CORS_MSG_ROOT, JSON_SCHEMAS_NS)); writeMessage(inmsg, corsDoc); return inmsg; } #endregion #region Handle JSONP Request // Here we are detecting if there has been any value promoted to the jsonp callback property // which will contain the name of the function that should be passed the JSON data returned // by the service. object jsonpCallback = inmsg.Context.Read(JSONP_CALLBACK_PROPNAME, JSON_SCHEMAS_NS); string jsonpCallbackName = (jsonpCallback ?? (object)string.Empty) as string; if (!string.IsNullOrWhiteSpace(jsonpCallbackName)) { var jsonpDoc = new XmlDocument(); jsonpDoc.AppendChild(jsonpDoc.CreateElement(DEFAULT_PREFIX, JSONP_MSG_ROOT, JSON_SCHEMAS_NS)); writeMessage(inmsg, jsonpDoc); return inmsg; } #endregion // Determine the current operation. We will use this as the root node // of the document if there isn't one specified as a property on the // component object operation = null; operation = inmsg.Context.Read(OPERATION_NAME_PROPNAME, SYSTEM_PROPERTIES_NS); string operationName = (operation ?? (object)string.Empty) as string; // Make message seekable if (!inmsg.BodyPart.Data.CanSeek) { var originalStream = inmsg.BodyPart.Data; Stream seekableStream = new ReadOnlySeekableStream(originalStream); inmsg.BodyPart.Data = seekableStream; pc.ResourceTracker.AddResource(originalStream); } // We are going to do something terrible and bring the entire message in memory. // Then we are going to create a string out of it, because that's how the library // wants it. // Please don't use this code for production purposes with large messages. // You have been warned. MemoryStream jsonStream = new MemoryStream(); inmsg.BodyPart.Data.CopyTo(jsonStream); inmsg.BodyPart.Data.Seek(0, SeekOrigin.Begin); // I am not going to assume any specific encoding. The BodyPart tells us // which encoding to use, so we will use that to get the string -- except // when it doesn't, then I will be a horrible person and assume an encoding. var jsonString = jsonStream.Length == 0 ? string.Empty : Encoding.GetEncoding(inmsg.BodyPart.Charset ?? Encoding.UTF8.WebName).GetString(jsonStream.ToArray()); var rawDoc = JsonConvert.DeserializeXmlNode(jsonString, string.IsNullOrWhiteSpace(this.RootNode) ? operationName : this.RootNode, true); // Here we are ensuring that the custom namespace shows up on the root node // so that we have a nice clean message type on the request messages var xmlDoc = new XmlDocument(); xmlDoc.AppendChild(xmlDoc.CreateElement(DEFAULT_PREFIX, rawDoc.DocumentElement.LocalName, this.Namespace)); xmlDoc.DocumentElement.InnerXml = rawDoc.DocumentElement.InnerXml; // All of the heavy lifting has been done, now we just have to shuffle this // new data over to the output message writeMessage(inmsg, xmlDoc); 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 Handle CORS Requests // Detect of the incoming message is an HTTP CORS request // http://www.w3.org/TR/cors/ object httpMethod = null; httpMethod = inmsg.Context.Read(HTTP_METHOD_PROPNAME, WCF_PROPERTIES_NS); if (httpMethod != null && (httpMethod as string) == OPTIONS_METHOD) { // Remove the message body before returning var emptyOutputStream = new VirtualStream(); inmsg.BodyPart.Data = emptyOutputStream; return inmsg; } #endregion // Make message seekable if (!inmsg.BodyPart.Data.CanSeek) { var originalStream = inmsg.BodyPart.Data; Stream seekableStream = new ReadOnlySeekableStream(originalStream); inmsg.BodyPart.Data = seekableStream; pc.ResourceTracker.AddResource(originalStream); } // Here again we are loading the entire document into memory // this is still a bad plan, and shouldn't be done in production // if you expect larger message sizes XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(inmsg.BodyPart.Data); if (xmlDoc.FirstChild.LocalName == "xml") xmlDoc.RemoveChild(xmlDoc.FirstChild); // Remove any root-level attributes added in the process of creating the XML // (Think xmlns attributes that have no meaning in JSON) xmlDoc.DocumentElement.Attributes.RemoveAll(); string jsonString = JsonConvert.SerializeXmlNode(xmlDoc, Newtonsoft.Json.Formatting.Indented, true); #region Handle JSONP Request // Here we are detecting if there has been any value promoted to the jsonp callback property // which will contain the name of the function that should be passed the JSON data returned // by the service. object jsonpCallback = inmsg.Context.Read(JSONP_CALLBACK_PROPNAME, JSON_SCHEMAS_NS); string jsonpCallbackName = (jsonpCallback ?? (object)string.Empty) as string; if (!string.IsNullOrWhiteSpace(jsonpCallbackName)) jsonString = string.Format("{0}({1});", jsonpCallbackName, jsonString); #endregion var outputStream = new VirtualStream(new MemoryStream(Encoding.UTF8.GetBytes(jsonString))); inmsg.BodyPart.Data = outputStream; return inmsg; }
private static Stream GetSeekeableMessageStream(IBaseMessage message) { var messageStream = message.BodyPart.GetOriginalDataStream(); if (messageStream.CanSeek) return messageStream; // Create a virtual and seekable stream const int bufferSize = 0x280; const int thresholdSize = 0x100000; Stream virtualReadStream = new VirtualStream(bufferSize, thresholdSize); Stream seekableReadStream = new ReadOnlySeekableStream(messageStream, virtualReadStream, bufferSize); messageStream = seekableReadStream; message.BodyPart.Data = messageStream; return messageStream; }