コード例 #1
0
        /// <summary>
        /// Sets the message schema strong name and message type.
        /// </summary>
        /// <param name="context">Pipeline context.</param>
        /// <param name="messageType">Message type.</param>
        /// <param name="message">Message instance.</param>
        /// <param name="docSpec">Document specification.</param>


        public static void SetDocProperties(IPipelineContext pContext, string messageType, IBaseMessage pInMsg, ref string docSpec)
        {
            try
            {
                pInMsg.Context.Promote(BtsProperties.MessageType.Name, BtsProperties.MessageType.Namespace, (object)messageType);
                IDocumentSpec documentSpecByType = pContext.GetDocumentSpecByType(messageType);
                if (documentSpecByType == null)
                {
                    return;
                }
                pInMsg.Context.Write(DasmProperties.DocumentSpecName.Name, DasmProperties.DocumentSpecName.Namespace, (object)null);
                pInMsg.Context.Write(BtsProperties.SchemaStrongName.Name, BtsProperties.SchemaStrongName.Namespace, (object)documentSpecByType.DocSpecStrongName);
                docSpec = docSpec == null ? (docSpec = documentSpecByType.DocSpecName) : docSpec;
            }
            catch (DocumentSpecException ex)
            {
                // Todo log this error
                DECore.TraceProvider.Logger.TraceInfo(ex.ToString());
            }
            catch (COMException ex)
            {
                // Todo log this errors
                DECore.TraceProvider.Logger.TraceInfo(ex.ToString());
            }
            catch (Exception ex)
            {
                DECore.TraceProvider.Logger.TraceError(ex);
                throw;
            }
        }
コード例 #2
0
        private XmlSchema GetMatchingSchema(IPipelineContext pipelineContext, Stream xmlStream)
        {
            XmlSchema     schema             = null;
            IDocumentSpec documentSpecByType = null;
            string        docType            = Utils.GetDocType(MarkableForwardOnlyEventingReadStream.EnsureMarkable(xmlStream));

            try
            {
                documentSpecByType = pipelineContext.GetDocumentSpecByType(docType);
            }
            catch (Exception)
            {
                return(null);
            }
            XmlSchemaSet schemaSet = (documentSpecByType as IDocumentSpec2).GetSchemaSet();

            if (schemaSet.Count == 0)
            {
                return(null);
            }
            foreach (XmlSchema schema2 in schemaSet.Schemas())
            {
                if (docType.Contains(schema2.TargetNamespace + "#"))
                {
                    schema = schema2;
                }
            }
            return(schema);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        public void CanLoadDocSpecWithPromotedProperties()
        {
            DocSpecLoader loader  = new DocSpecLoader();
            IDocumentSpec docSpec = loader.LoadDocSpec(typeof(Schema2_WPP));

            Assert.IsNotNull(docSpec);
        }
コード例 #5
0
        /// <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
            }));
        }
コード例 #6
0
 /// <summary>
 ///     Adds a document specification to the context
 /// </summary>
 /// <param name="docSpec">Specification to add</param>
 private void AddDocSpecToContext(IDocumentSpec docSpec)
 {
     IConfigurePipelineContext ctxt = (IConfigurePipelineContext) Context;
     ctxt.AddDocSpecByType(docSpec.DocType, docSpec);
     // Pipelines referencing local schemas in the same
     // assembly don't have use the assembly qualified name
     // of the schema when trying to find it.
     ctxt.AddDocSpecByName(docSpec.DocSpecStrongName, docSpec);
     ctxt.AddDocSpecByName(docSpec.DocSpecName, docSpec);
 }
コード例 #7
0
        /// <summary>
        ///     Adds a new document specification to the list
        ///     of Known Schemas for this pipeline.
        /// </summary>
        /// <remarks>
        ///     Adding known schemas is necessary so that
        ///     document type resolution works in the disassembler/assembler
        ///     stages. Notice that this overload does NOT do automatic checking
        ///     for multiple roots.
        /// </remarks>
        /// <param name="typeName">
        ///     The fully qualified (namespace.class) name of
        ///     the schema
        /// </param>
        /// <param name="assemblyName">
        ///     The partial or full name of the assembly
        ///     containing the schema
        /// </param>
        public void AddDocSpec(string typeName, string assemblyName)
        {
            if (String.IsNullOrEmpty(typeName))
                throw new ArgumentNullException("typeName");
            if (String.IsNullOrEmpty(assemblyName))
                throw new ArgumentNullException("assemblyName");

            IDocumentSpec spec = LoadDocSpec(typeName, assemblyName);
            AddDocSpecToContext(spec);
        }
コード例 #8
0
        public IDocumentSpec GetDocumentSpecByType(string docType)
        {
            IDocumentSpec spec = (IDocumentSpec)this.typeToDocSpecMap[docType];

            if (spec == null)
            {
                throw new COMException();
            }
            return(spec);
        }
コード例 #9
0
        /// <summary>
        ///     Adds a new document specification to the context
        /// </summary>
        /// <param name="type">XML namespace#root</param>
        /// <param name="documentSpec">Document Spec</param>
        public void AddDocSpecByType(string type, IDocumentSpec documentSpec)
        {
            if (type == null)
                throw new ArgumentNullException("type");
            if (documentSpec == null)
                throw new ArgumentNullException("documentSpec");

            if (!_docSpecsByType.ContainsKey(type))
                _docSpecsByType.Add(type, documentSpec);
        }
コード例 #10
0
        public IDocumentSpec GetDocumentSpecByName(string docspecName)
        {
            IDocumentSpec spec = (IDocumentSpec)this.nameToDocSpecMap[docspecName];

            if (spec == null)
            {
                throw new COMException();
            }
            return(spec);
        }
コード例 #11
0
        //
        // IConfigurePipelineContext Members
        //

        /// <summary>
        ///     Adds a new document specification to the context
        /// </summary>
        /// <param name="name">CLR Type name</param>
        /// <param name="documentSpec">Document Spec</param>
        public void AddDocSpecByName(string name, IDocumentSpec documentSpec)
        {
            if (name == null)
                throw new ArgumentNullException("name");
            if (documentSpec == null)
                throw new ArgumentNullException("documentSpec");

            if (!_docSpecsByName.ContainsKey(name))
                _docSpecsByName.Add(name, documentSpec);
        }
コード例 #12
0
        public void CanAddNoTargetNSDocSpec()
        {
            ReceivePipelineWrapper pipeline =
                PipelineFactory.CreateEmptyReceivePipeline();

            pipeline.AddDocSpec(typeof(NoNS));

            IDocumentSpec docSpec = pipeline.GetKnownDocSpecByType("Root");

            Assert.IsNotNull(docSpec);
        }
コード例 #13
0
        //Add schema
        public void addppDocSpec(Type schemaType)
        {
            if (schemaType == null)
            {
                throw new ArgumentNullException("schemaType");
            }

            Type[] roots = getSchRoots(schemaType);
            foreach (Type root in roots)
            {
                IDocumentSpec docSpec = getSchemaSpec(root);
                docSpecinMsgContxt(docSpec);
            }
        }
コード例 #14
0
        public void CanAddDocSpecByName()
        {
            ReceivePipelineWrapper pipeline = PipelineFactory.CreateEmptyReceivePipeline();

            pipeline.AddDocSpec("SampleSchemas.Schema1_NPP+Root", "SampleSchemas");

            IDocumentSpec docSpec =
                pipeline.GetKnownDocSpecByName(typeof(Schema1_NPP.Root).AssemblyQualifiedName);

            Assert.IsNotNull(docSpec);

            docSpec = pipeline.GetKnownDocSpecByType("http://SampleSchemas.Schema1_NPP#Root");
            Assert.IsNotNull(docSpec);
        }
コード例 #15
0
        //Add schema from assembly
        public void addppDocSpec(string typeName, string assemblyName)
        {
            if (String.IsNullOrEmpty(typeName))
            {
                throw new ArgumentNullException("typeName");
            }
            if (String.IsNullOrEmpty(assemblyName))
            {
                throw new ArgumentNullException("assemblyName");
            }

            IDocumentSpec spec = getSchemaSpec(typeName, assemblyName);

            docSpecinMsgContxt(spec);
        }
コード例 #16
0
        /// <summary>
        /// Adds a new document specification to the list
        /// of Known Schemas for this pipeline.
        /// </summary>
        /// <remarks>
        /// Adding known schemas is necessary so that
        /// document type resolution works in the disassembler/assembler
        /// stages
        /// </remarks>
        /// <param name="schemaType">Type of the document schema to add</param>
        public void AddDocSpec(Type schemaType)
        {
            if (schemaType == null)
            {
                throw new ArgumentNullException("schemaType");
            }

            DocSpecLoader loader = new DocSpecLoader();

            Type[] roots = GetSchemaRoots(schemaType);
            foreach (Type root in roots)
            {
                IDocumentSpec docSpec = loader.LoadDocSpec(root);
                AddDocSpecToContext(docSpec);
            }
        }
コード例 #17
0
        /// <summary>
        ///     Adds a new document specification to the list
        ///     of Known Schemas for this pipeline.
        /// </summary>
        /// <remarks>
        ///     Adding known schemas is necessary so that
        ///     document type resolution works in the disassembler/assembler
        ///     stages
        /// </remarks>
        /// <param name="schemaType">Type of the document schema to add</param>
        public void AddDocSpec(Type schemaType)
        {
            if (schemaType == null)
            {
                //16042014
                return;
                //16042014
                throw new ArgumentNullException("schemaType");
            }

            Type[] roots = GetSchemaRoots(schemaType);
            foreach (Type root in roots)
            {
                IDocumentSpec docSpec = LoadDocSpec(root);
                AddDocSpecToContext(docSpec);
            }
        }
コード例 #18
0
        IBaseMessage GetNextMessage(IPipelineContext pContext)
        {
            IBaseMessage outMsg = null;

            if (childReader == null || childReader.EOF)
            {
                baseMsg = innerDasm.GetNext(pContext);

                if (baseMsg == null)
                {
                    return(baseMsg);
                }

                childReader = XmlReader.Create(baseMsg.BodyPart.GetOriginalDataStream());
            }

            while (childReader.Read())
            {
                MessageType msgType = new MessageType
                {
                    RootName = childReader.LocalName
                    ,
                    TargetNamespace = childReader.NamespaceURI
                };

                if (messageTypes.ContainsKey(msgType))
                {
                    currDocument = messageTypes[msgType];
                    //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
                    // XmlTranslatorStream trans = new XmlTranslatorStream(childReader.ReadSubtree());

                    outMsg = CreateMessage(pContext, childReader);
                    break;
                }
            }

            if (outMsg == null)
            {
                outMsg = GetNextMessage(pContext); //make sure there is no more messages in base queue
            }
            return(outMsg);                        //return null if the message is null, but check if there exists more enveloped messages
        }
コード例 #19
0
ファイル: TransformService.cs プロジェクト: radtek/DevOps
        private string GetSourceMessageMatchingMapName(ArrayList mapList, string btsMsgType, IPipelineContext context)
        {
            string mapName = string.Empty;

            if (mapList.Count > 1)
            {
                foreach (string map in mapList)
                {
                    try
                    {
                        Type type = Type.GetType(map);
                        TransformMetaData transformMetaData    = TransformMetaData.For(type);
                        SchemaMetadata    sourceSchemaMetadata = transformMetaData.SourceSchemas[0];
                        string            mapSourceSchemaName  = sourceSchemaMetadata.SchemaName;
                        IDocumentSpec     documentSpec         = context.GetDocumentSpecByType(btsMsgType);
                        string            msgSourceSchemaName  = documentSpec.DocType;

                        Logger.WriteTrace("Map Source Schema Name: " + mapSourceSchemaName);
                        Logger.WriteTrace("Msg Source Schema Name: " + msgSourceSchemaName);

                        if (string.Compare(mapSourceSchemaName, msgSourceSchemaName, false, CultureInfo.CurrentCulture) == 0)
                        {
                            Logger.WriteTrace("Match found: " + map);
                            mapName = map;
                            break;
                        }
                    }
                    catch (Exception) { }
                }
            }
            else
            {
                mapName = mapList[0].ToString();
            }

            return(mapName);
        }
コード例 #20
0
        /// <summary>
        /// Wrapper To perform XmlValidation
        /// </summary>
        /// <param name="docSpec">The Document NameSpec derieved for the message</param>
        /// <param name="maxErrorCount">maximum number of Schema validation errors to be captured</param>
        /// <param name="stream">Stream representation of the incoming message</param>
        /// <param name="messageType">Message Type of the incoming message</param>
        /// <param name="messageId">Id of the incoming message</param>
        public void ValidationWrapper(IDocumentSpec docSpec, int maxErrorCount, VirtualStream stream, string messageType, string messageId)
        {
            XmlSchemaSet schemas = new XmlSchemaSet();

            try
            {
                foreach (var schema in docSpec.GetSchemaCollection())
                {
                    schemas.Add(schema);
                }
            }
            catch (XmlSchemaException ex)
            {
                string errorDescription = string.Format("An error occured while loading the schemas. Error Message: {0} \r\nLine: {1}, Position: {2} \r\n", ex.Message, ex.LineNumber, ex.LinePosition);

                throw new Exception(errorDescription);
            }
            catch (Exception sysEx)
            {
                throw new Exception("An error occured while loading the schemas. Error detail: " + sysEx.ToString());
            }

            Validate(stream, schemas, maxErrorCount, messageType, messageId);
        }
コード例 #21
0
        public static IInitializeDocumentSpec InitializeDocumentSpec(IDocumentSpec documentSpec, string documentSpecName, string schemaFileName, ArrayList propertyAnnotations)
        {
            IInitializeDocumentSpec spec        = (IInitializeDocumentSpec)documentSpec;
            XmlDocument             xmlDocument = new XmlDocument();

            xmlDocument.Load(new XmlTextReader(schemaFileName));
            string    documentType    = GetDocumentType(xmlDocument);
            string    targetNamespace = GetTargetNamespace(xmlDocument);
            string    bodyXPath       = GetBodyXPath(xmlDocument);
            Hashtable schemaList      = new Hashtable();

            schemaList.Add(targetNamespace, new FileStream(schemaFileName, FileMode.Open, FileAccess.Read));
            spec.Initialize(targetNamespace, documentSpecName, documentType, bodyXPath, schemaList);
            NameTable           nameTable = new NameTable();
            XmlNamespaceManager nsmgr     = new XmlNamespaceManager(nameTable);

            nsmgr.AddNamespace("xs", "http://www.w3.org/2001/XMLSchema");
            nsmgr.AddNamespace("b", "http://schemas.microsoft.com/BizTalk/2003");
            Hashtable hashtable2 = new Hashtable();
            Hashtable hashtable3 = new Hashtable();

            foreach (XmlNode node in xmlDocument.SelectNodes("/xs:schema/xs:annotation/xs:appinfo/b:imports/b:namespace", nsmgr))
            {
                hashtable2.Add(node.Attributes["prefix"].InnerText, node.Attributes["uri"].InnerText);
                string innerText = node.Attributes["location"].InnerText;
                if (new FileInfo(innerText).Exists)
                {
                    XmlDocument document2 = new XmlDocument();
                    document2.Load(innerText);
                    hashtable3.Add(node.Attributes["uri"].InnerText, document2);
                }
            }
            foreach (XmlNode node2 in xmlDocument.SelectNodes("/xs:schema//xs:annotation/xs:appinfo/b:properties/b:property[not(@distinguished='true')]", nsmgr))
            {
                PropertyAnnotation annotation = new PropertyAnnotation();
                string             str5       = node2.Attributes["name"].InnerText;
                annotation.Name      = str5.Split(new char[] { ':' })[1];
                annotation.Namespace = (string)hashtable2[str5.Split(new char[] { ':' })[0]];
                annotation.XPath     = node2.Attributes["xpath"].InnerText;
                annotation.XSDType   = null;
                XmlDocument document3 = (XmlDocument)hashtable3[annotation.Namespace];
                if (document3 != null)
                {
                    XmlNode node3 = document3.SelectSingleNode(string.Format(CultureInfo.CurrentCulture, "/xs:schema/xs:element[@name='{0}']", new object[] { annotation.Name }), nsmgr);
                    if (node3 != null)
                    {
                        XmlNode node4 = node3.Attributes["type"];
                        if (node4 != null)
                        {
                            string[] strArray = node4.InnerText.Split(new char[] { ':' });
                            if (2 == strArray.Length)
                            {
                                annotation.XSDType = strArray[1];
                            }
                            else if (1 == strArray.Length)
                            {
                                annotation.XSDType = strArray[0];
                            }
                        }
                    }
                }
                if (annotation.XSDType == null)
                {
                    annotation.XSDType = "string";
                }
                if (propertyAnnotations != null)
                {
                    propertyAnnotations.Add(annotation);
                }
                spec.AddAnnotation(annotation);
            }
            return(spec);
        }
コード例 #22
0
 public void AddDocSpecByName(string name, IDocumentSpec docSpec)
 {
     this.nameToDocSpecMap.Add(name, docSpec);
 }
コード例 #23
0
 public void AddDocSpecByType(string type, IDocumentSpec docSpec)
 {
     this.typeToDocSpecMap.Add(type, docSpec);
 }
コード例 #24
0
        /// <summary>
        /// Adds a new document specification to the context
        /// </summary>
        /// <param name="type">XML namespace#root</param>
        /// <param name="documentSpec">Document Spec</param>
        public void AddDocSpecByType(string type, IDocumentSpec documentSpec)
        {
            if ( type == null )
            throw new ArgumentNullException("type");
             if ( documentSpec == null )
            throw new ArgumentNullException("documentSpec");

             if ( !_docSpecsByType.ContainsKey(type) )
            _docSpecsByType.Add(type, documentSpec);
        }
コード例 #25
0
        /// <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);
        }
コード例 #26
0
        //
        // IConfigurePipelineContext Members
        //
        /// <summary>
        /// Adds a new document specification to the context
        /// </summary>
        /// <param name="name">CLR Type name</param>
        /// <param name="documentSpec">Document Spec</param>
        public void AddDocSpecByName(string name, IDocumentSpec documentSpec)
        {
            if ( name == null )
            throw new ArgumentNullException("name");
             if ( documentSpec == null )
            throw new ArgumentNullException("documentSpec");

             if ( !_docSpecsByName.ContainsKey(name) )
            _docSpecsByName.Add(name, documentSpec);
        }
コード例 #27
0
 public static bool TryGetDocumentSpecByType(this IPipelineContext pipelineContext, string docType, out IDocumentSpec documentSpec)
 {
     try
     {
         documentSpec = pipelineContext.GetDocumentSpecByType(docType);
         return(true);
     }
     catch (COMException exception)
     {
         documentSpec = null;
         // test HResult for Finding the document specification by message type "..." failed. Verify the schema deployed properly.
         if (exception.HResult == E_SCHEMA_NOT_FOUND)
         {
             return(false);
         }
         if (_logger.IsWarnEnabled)
         {
             _logger.Warn(string.Format("SafeGetDocumentSpecByType({0}) has failed.", docType), exception);
         }
         throw;
     }
 }
コード例 #28
0
        /// <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);
        }
コード例 #29
0
        /// <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);
        }
コード例 #30
0
 public static bool TryGetDocumentSpecByType(this IPipelineContext pipelineContext, string docType, out IDocumentSpec documentSpec)
 {
     if (pipelineContext == null)
     {
         throw new ArgumentNullException(nameof(pipelineContext));
     }
     try
     {
         documentSpec = pipelineContext.GetDocumentSpecByType(docType);
         return(true);
     }
     catch (COMException exception)
     {
         documentSpec = null;
         if ((uint)exception.ErrorCode == (uint)HResult.ErrorSchemaNotFound)
         {
             return(false);
         }
         if (_logger.IsWarnEnabled)
         {
             _logger.Warn($"SafeGetDocumentSpecByType({docType}) has failed.", exception);
         }
         throw;
     }
 }
コード例 #31
0
        public bool Probe(IPipelineContext pContext, IBaseMessage pInMsg)
        {
            // Check arguments
            if (null == pContext)
            {
                throw new ArgumentNullException("pContext");
            }

            if (null == pInMsg)
            {
                throw new ArgumentNullException("pInMsg");
            }

            // We need to determine a document schema to use based on message content. For the sake of simplicity of this
            // sample, we will check the first two characters in input stream and map them to some schema message types we
            // have predefined. The more sofisticated component could use UI configuration options to map identification
            // text located at specified offsets in message stream and having specified length, which could map to specified
            // message type or document spec type name.

            // Check whether input message doesn't have a body part or it is set to null, fail probe in those cases
            if (null == pInMsg.BodyPart || null == pInMsg.BodyPart.GetOriginalDataStream())
            {
                return(false);
            }

            SeekableReadOnlyStream stream = new SeekableReadOnlyStream(pInMsg.BodyPart.GetOriginalDataStream());
            Stream sourceStream           = pInMsg.BodyPart.GetOriginalDataStream();

            // Check if source stream can seek
            if (!sourceStream.CanSeek)
            {
                // Create a virtual (seekable) stream
                SeekableReadOnlyStream seekableStream = new SeekableReadOnlyStream(sourceStream);

                // Set new stream for the body part data of the input message. This new stream will then used for further processing.
                // We need to do this because input stream may not support seeking, so we wrap it with a seekable stream.
                pInMsg.BodyPart.Data = seekableStream;

                // Replace sourceStream with a new seekable stream wrapper
                sourceStream = pInMsg.BodyPart.Data;
            }

            // Preserve the stream position
            long position = sourceStream.Position;

            char [] signature = new char[2];
            try
            {
                // Read signature from a stream
                StreamReader reader = new StreamReader(sourceStream);
                if (reader.Read(signature, 0, signature.Length) < signature.Length)
                {
                    return(false);
                }

                // Don't close stream reader to avoid closing of underlying stream
            }
            finally
            {
                // Restore the stream position
                sourceStream.Position = position;
            }

            // Get message type from signature
            string messageType = GetMessageType(new string(signature));

            // Fail if message type is unknown
            if (null == messageType)
            {
                return(false);
            }

            // Get document spec from the message type
            IDocumentSpec documentSpec = pContext.GetDocumentSpecByType(messageType);

            // Instead of loading schema to get a document spec type name we could change implementation to return defined
            // during a design time document spec type name and directly specify it in the call below:

            // Write document spec type name to the message context so Flat File disassembler could access this property and
            // do message processing for a schema which has document spec type name we've discovered
            pInMsg.Context.Write(DocumentSpecNamePropertyName, XmlNormNamespaceURI, documentSpec.DocSpecStrongName);

            // Delegate call to Flat File disassembler
            return(disassembler.Probe(pContext, pInMsg));
        }
コード例 #32
0
        /// <summary>
        /// Execute the Custom Logic To Do the Schema Validation
        /// </summary>
        /// <param name="pContext">Pipeline context</param>
        /// <param name="pInMsg">Input message to the pipeline</param>
        /// <returns>Output message</returns>
        public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
        {
            _logger.Debug("PipelineComponent::XmlValidator: Executing validation pipeline component.");

            int maxErrorCount = 20;

            //Parse the maxErrorCount property value to int
            Int32.TryParse(_maxErrorCount, out maxErrorCount);

            string messageType = Convert.ToString(pInMsg.Context.Read(Constants.MessageTypePropName, Constants.SystemPropertiesNamespace));
            string messageId   = Convert.ToString(pInMsg.MessageID);
            string fileName    = Convert.ToString(pInMsg.Context.Read(Constants.ReceivedFileNamePropName, Constants.FileAdapterPropertiesNameSpace));

            fileName = PipelineHelper.GetFileNameWithoutExtension(fileName);

            XmlValidatorHelper helper = new XmlValidatorHelper(); // (maxErrorCount, fileName);

            helper.Logger = _logger;

            if (pContext == null)
            {
                throw new ArgumentNullException("Pipeline Context is null");
            }

            if (pInMsg == null)
            {
                throw new ArgumentNullException("Incoming Message in null");
            }

            //Create OutMessage

            //Invoke the XMLValidator Validate Method

            var    originalStream = pInMsg.BodyPart.GetOriginalDataStream();
            Stream seekableStream;

            if (!originalStream.CanSeek)
            {
                seekableStream       = new ReadOnlySeekableStream(originalStream);
                pInMsg.BodyPart.Data = seekableStream;
            }
            else
            {
                seekableStream = originalStream;
            }

            IDocumentSpec docSpec = null;

            try
            {
                docSpec = pContext.GetDocumentSpecByType(messageType);


                //Use a temperory Disposable Virtual Stream
                using (VirtualStream virtusalStream = new VirtualStream())
                {
                    seekableStream.CopyTo(virtusalStream);
                    virtusalStream.Position = 0;
                    helper.ValidationWrapper(docSpec, maxErrorCount, virtusalStream, messageType, messageId);
                }


                //var errorProcessStatus = null; // helper.ProcessStatus;
                ////Check if validation Helper has caught any errors
                //if (errorProcessStatus.Errors != null && errorProcessStatus.Errors.Count() > 0)
                //{

                //    return CreateOutputMessageWrapper(pContext, pInMsg, errorProcessStatus, fileName);

                //}
                //else
                //{
                //    //Need to move the wrapped seekable stream to beginning and assign to the BodyPart as incoming message is not seekable
                //    seekableStream.Seek(0, SeekOrigin.Begin);
                //    // Track the stream so that it can be disposed when the message is finially finished with
                //    pContext.ResourceTracker.AddResource(pInMsg.BodyPart.Data);
                return(pInMsg);
                //}
            }
            catch (Exception ex)
            {
                string errorMessage = string.Format("RequestId: {0} ErrorMessage: {1}", fileName, ex.Message);
                _logger.Error(errorMessage);
                return(pInMsg);
            }
        }