void IDisassemblerComponent.Disassemble(IPipelineContext pContext, IBaseMessage pInMsg) { innerDasm.EnvelopeSpecNames = this.EnvelopeSpecNames; //Important not to add the DocumentSpecNames to the inner disassembler as it will not allow messages //that we want to ignore, that is not the same as AllowUnrecognizedMessage = true as UnrecognizedMessage //means a message without corresponding installed schema //This is also why i could not sublass XmlDasmComp innerDasm.AllowUnrecognizedMessage = true; innerDasm.ValidateDocument = this.ValidateDocument; innerDasm.RecoverableInterchangeProcessing = this.RecoverableInterchangeProcessing; SchemaList documents = this.DocumentSpecNames; foreach (Schema item in documents) { IDocumentSpec documentSpec = pContext.GetDocumentSpecByName(item.SchemaName); string[] messageParts = documentSpec.DocType.Split(new char[] { '#' }); MessageType msgType = new MessageType { RootName = messageParts[1] , TargetNamespace = messageParts[0] }; if (messageTypes.ContainsKey(msgType) == false) { messageTypes.Add(msgType, documentSpec); } } innerDasm.Disassemble(pContext, pInMsg); }
/// <summary> /// Sets the message schema strong name and message type. /// </summary> /// <param name="context">Pipeline context.</param> /// <param name="message">Message instance.</param> public static void SetDocProperties(IPipelineContext context, IBaseMessage msg) { if (context == null) { throw new ArgumentNullException("context"); } if (msg == null) { throw new ArgumentNullException("msg"); } object obj = msg.Context.Read(BtsProperties.SchemaStrongName.Name, BtsProperties.SchemaStrongName.Namespace); if (obj != null && string.Compare(obj.ToString(), "Microsoft.XLANGs.BaseTypes.Any, Microsoft.XLANGs.BaseTypes, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", true, CultureInfo.CurrentCulture) == 0) { msg.Context.Write(BtsProperties.SchemaStrongName.Name, BtsProperties.SchemaStrongName.Namespace, (object)null); } string DocSpecName = (string)msg.Context.Read(BtsProperties.SchemaStrongName.Name, BtsProperties.SchemaStrongName.Namespace) ?? string.Empty; DECore.TraceProvider.Logger.TraceInfo(string.Format("Schema strong name is {0} after first context read.", new object[1] { obj })); string str = (string)msg.Context.Read(BtsProperties.MessageType.Name, BtsProperties.MessageType.Namespace) ?? string.Empty; DECore.TraceProvider.Logger.TraceInfo(string.Format("Document message type is {0} after first context read.", new object[1] { (object)str })); if (!string.IsNullOrEmpty(str)) { return; } if (!string.IsNullOrEmpty(DocSpecName)) { IDocumentSpec documentSpec = (IDocumentSpec)null; try { documentSpec = context.GetDocumentSpecByName(DocSpecName); } catch (DocumentSpecException ex) { // Todo Log this Error DECore.TraceProvider.Logger.TraceInfo(ex.ToString()); } catch (COMException ex) { // todo Log this erro DECore.TraceProvider.Logger.TraceInfo(ex.ToString()); } if (documentSpec != null) { str = documentSpec.DocType; } } msg.Context.Write(BtsProperties.MessageType.Name, BtsProperties.MessageType.Namespace, (object)str); DECore.TraceProvider.Logger.TraceInfo(string.Format("Message type is {0}.", new object[1] { (object)str })); }
public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg) { string errorMessage; //if (!Validate(out errorMessage)) //{ // throw new ArgumentException(errorMessage); //} //Get a reference to the BizTalk schema. string DocumentSpecName = "ProviderRequest"; var documentSpec = pContext.GetDocumentSpecByName(DocumentSpecName); //Get a list of properties defined in the schema. var annotations = documentSpec.GetPropertyAnnotationEnumerator(); var doc = new XmlDocument(); using (var sw = new StringWriter(new StringBuilder())) { //Create a new instance of the schema. doc.Load(((IFFDocumentSpec)documentSpec).CreateXmlInstance(sw)); } //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 data = new VirtualStream(); pContext.ResourceTracker.AddResource(data); doc.Save(data); data.Seek(0, SeekOrigin.Begin); var outMsg = pInMsg; outMsg.BodyPart.Data = data; //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); }
public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg) { string errorMessage; if (!Validate(out errorMessage)) { throw new ArgumentException(errorMessage); } //Get a reference to the BizTalk schema. var documentSpec = pContext.GetDocumentSpecByName(DocumentSpecName); //Get a list of properties defined in the schema. var annotations = documentSpec.GetPropertyAnnotationEnumerator(); var doc = new XmlDocument(); using (var sw = new StringWriter(new StringBuilder())) { //Create a new instance of the schema. doc.Load(((IFFDocumentSpec)documentSpec).CreateXmlInstance(sw)); } //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 data = new VirtualStream(); pContext.ResourceTracker.AddResource(data); doc.Save(data); data.Seek(0, SeekOrigin.Begin); var outMsg = pInMsg; outMsg.BodyPart.Data = data; //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); }
/// <summary> /// /// </summary> /// <param name="pContext"></param> /// <param name="pInMsg"></param> public void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg) { //Get a reference to the BizTalk schema. var documentSpec = (DocumentSpec)pContext.GetDocumentSpecByName(DocumentSpecName); //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; 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); }
/// <summary> /// Examine the incoming message and determine which document spec name (specifically which strong name) to assign. /// </summary> /// <param name="pContext"></param> /// <param name="pInMsg"></param> /// <returns></returns> public bool Probe(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg) { bool handled = false; //the messagetype is not unique, which is why the biztalk resolver fails. However, the docSpecName IS unique as it contains //the FQN, eg the docspecName for the SAM unLockBAResponse is ES.FS.WG.SAM.Schemas.SAMSchemas.SAMServiceSchemas.SamServiceService_servlet_x2esam_x2eedscs_x2eeds_x2ecom+unLockBAResponse //Whereas the docSpecName for the STAX unLockBAResponse is ES.FS.WG.STAX.Schemas.SAMSchemas.SamServiceService_servlet_x2esam_x2eedscs_x2eeds_x2ecom+unLockBAResponse. string rootNodeName = string.Empty; string messageType = GetMessageType(pInMsg, out rootNodeName); //Is this a messageType we know how to handle //ie does the messageType exist in the schema assembly we are resolving to. //NOTE: If the schema contains only a single root node, the docSpecName does NOT include the rootNodeName string docSpecName = string.Empty; if (_multiElementSchema) { docSpecName = string.Format("{0}.{1}+{2}", DocSpecQN, DocSpecClassName, rootNodeName); } else { docSpecName = string.Format("{0}.{1}", DocSpecQN, DocSpecClassName); } string docSpecStrongName = string.Format("{0}, {1}", docSpecName, AssemblyStrongName); IDocumentSpec docSpec = null; try { //determine if this is a valid doc spec name by loading the doc spec (effectively queries the BT mgt database for us) //look up from Biztalk to ensure strongname is valid, if lookup fails an exception is thrown docSpec = pContext.GetDocumentSpecByName(docSpecStrongName); //first check the cache, if not in cache retrieve from Biztalk and place in cache //if it is in the cache, it is inherently a valid docSpecStrongName as it must have already been looked up from Biztalk //so no need to do anything further, just assign the strong name to the message //if (!StrongNameCache.ContainsKey(rootNodeName)) //{ // //look up from Biztalk to ensure strongname is valid, if lookup fails an exception is thrown // docSpec = pContext.GetDocumentSpecByName(docSpecStrongName); // //if capacity reached, remove the first entry added to the cache. // if (StrongNameCache.Count == CacheCapacity) // { // string keyToRemove = StrongNameCache.ElementAt(0).Key; // StrongNameCache.Remove(keyToRemove); // } // StrongNameCache[rootNodeName] = docSpec.DocSpecStrongName; //} //make sure the incoming message matches the docSpec we found handled = (docSpec.DocType == messageType); } catch (Exception) { //consume the exception and return false (not handled by this component) //_logger.DebugFormat("XmlSchemaResolver:: Probe: Message not being handled {0}, DocSpecName {1}", messageType, docSpecStrongName); } if (handled) { pInMsg.Context.Write("DocumentSpecName", "http://schemas.microsoft.com/BizTalk/2003/xmlnorm-properties", docSpecStrongName); } else { handled = _xmlDissambler.Probe(pContext, pInMsg); } return(handled); }
/// <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 void AddDocument(IPipelineContext pContext, IBaseMessage pInMsg) { string errorMessage; if (!Validate(out errorMessage)) { var ex = new ArgumentException(errorMessage); throw ex; } DocumentSpec documentSpec; try { documentSpec = (DocumentSpec)pContext.GetDocumentSpecByName(DocumentSpecName); } catch (COMException) { throw new ArgumentException(string.Format("Could not find document with documentspecname = {0}", DocumentSpecName)); } var doc = new XmlDocument(); using (var sw = new StringWriter(new StringBuilder())) { doc.Load(documentSpec.CreateXmlInstance(sw)); } 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); } var ms = new MemoryStream(); data.CopyTo(ms); ms.Seek(0, SeekOrigin.Begin); ms.Position = 0; var node = doc.SelectSingleNode(DestinationXpath); if (node == null) { throw new ArgumentException("Could not find element at {0}", DestinationXpath); } node.InnerText = Convert.ToBase64String(ms.ToArray()); var outMs = new MemoryStream(); doc.Save(outMs); outMs.Seek(0, SeekOrigin.Begin); pInMsg.BodyPart.Data = outMs; _outputQueue.Enqueue(pInMsg); }