Beispiel #1
0
        /// <summary>
        /// Validates the specified <paramref name="xDoc"/> against the specified <paramref name="schema"/>.
        /// </summary>
        /// <param name="xDoc">The <see cref="XDocument"/> of the XML to validate.</param>
        /// <param name="schema">The <see cref="XmlSchema"/> to validate the <paramref name="xDoc"/> against.</param>
        /// <returns></returns>
        protected virtual bool ValidateXml(XDocument xDoc, XmlSchema schema)
        {
            bool   result = true;
            string xml    = xDoc.ToString();

            TransactionScope.WriteActivity("XML Document is validating...");

            //get the root element of the doc
            var rootElement = xDoc.Root;

            //try and obtain the targetNamespace
            var targetNamespace = rootElement.GetDefaultNamespace();

            if (string.IsNullOrWhiteSpace(targetNamespace.NamespaceName))
            {
                //couldn't obtain the schema we need because the root node didn't have a default non-prefixed xmlns attribute.
                //lets see of the document is using prefixes and look for the xmlns:cers="" attribute.
                targetNamespace = rootElement.GetNamespaceOfPrefix("cers");
            }

            //if we have no targetNamespace then we should not proceed any further.
            if (targetNamespace == null || targetNamespace.NamespaceName == string.Empty)
            {
                TransactionScope.WriteMessage("Unable to resolve the targetNamespace of the received XML data.", EDTTransactionMessageType.Error);
                throw new Exception("Unable to resolve the targetNamespace of the received XML data.");
            }

            //check the version
            string version = targetNamespace.ExtractVersion();

            XmlSchemaValidationResult schemaValidationResult = xml.IsValidAgainstSchema(schema, version);

            if (!schemaValidationResult.IsValid)
            {
                //package is invalid due to schema validation errors, update the transaction status write some info.
                //Merge in the schema validation error messages and associate them with the transaction.

                TransactionScope.SetStatus(EDTTransactionStatus.Rejected);
                TransactionScope.WriteActivity("XML Document is NOT valid against the schema.");
                TransactionScope.WriteMessage("XML document does not validate against the schema.", EDTTransactionMessageType.Error);
                foreach (var error in schemaValidationResult.Errors)
                {
                    TransactionScope.WriteMessage("Schema Validation Error: " + error, EDTTransactionMessageType.Error);
                }

                result = false;
            }
            else
            {
                TransactionScope.WriteActivity("XML Document is valid against the schema.");
            }
            return(result);
        }
Beispiel #2
0
        public XElement Process(Stream stream, int regulatorCode)
        {
            Regulator contextRegulator = Repository.Regulators.GetByEDTIdentityKey(regulatorCode);

            if (contextRegulator == null)
            {
                throw new ArgumentException("RegulatorCode does not contain a valid number.", "regulatorCode");
            }

            //Connect the regulator after we verified it exists.
            TransactionScope.Connect(contextRegulator);

            //this endpoint supports multiple versions of the schema simultaneously.
            IXmlSchemaMetadata inputSchemaMetadata  = null;
            IXmlSchemaMetadata outputSchemaMetadata = null;
            string             version = null;

            RegulatorFacilityCreateResponseXmlSerializer responseSerializer = new RegulatorFacilityCreateResponseXmlSerializer(Repository);

            //lets default to Trial mode in case the XML is so messed up we can't parse it, and this is obviously less danagerous than
            //a Commit.
            RegulatorFacilityCreateMode mode = RegulatorFacilityCreateMode.Trial;

            //declare the package to be use to inflate the XML.
            RegulatorXmlObjectPacket <RegulatorFacilityCreateMode, FacilityCreatePackage> package = null;

            XmlSchemaValidationResult schemaValidationResult = null;
            var rfcXml = ConvertStreamToXDocument(stream);

            if (rfcXml != null)
            {
                string xml = rfcXml.ToString();
                TransactionScope.SaveXml(xml, EDTTransactionXmlDirection.Inbound);
                TransactionScope.WriteActivity("XML Document is validating...");

                //get the root element of the doc (should be named RegulatorFacilityCreate).
                var rootElement = rfcXml.Root;

                //try and obtain the targetNamespace
                var targetNamespace = rootElement.GetDefaultNamespace();
                if (string.IsNullOrWhiteSpace(targetNamespace.NamespaceName))
                {
                    //couldn't obtain the schema we need because the root node didn't have a default non-prefixed xmlns attribute.
                    //lets see of the document is using prefixes and look for the xmlns:cers="" attribute.
                    targetNamespace = rootElement.GetNamespaceOfPrefix("cers");
                }

                //if we have no targetNamespace then we should not proceed any further.
                if (targetNamespace == null || targetNamespace.NamespaceName == string.Empty)
                {
                    TransactionScope.WriteMessage("Unable to resolve the targetNamespace of the received XML data.", EDTTransactionMessageType.Error);
                    throw new Exception("Unable to resolve the targetNamespace of the received XML data.");
                }

                //find the metadata for the RegulatorFacilityCreate schema with the specified targetNamespace.
                inputSchemaMetadata = XmlSchemas.GetSchemaMetdataForNamespace(XmlSchema.RegulatorFacilityCreate, targetNamespace);                   //XmlSchemas.GetSchemaMetadata( XmlSchema.RegulatorFacilityCreate, version );
                if (inputSchemaMetadata == null)
                {
                    TransactionScope.WriteMessage("Unable to find a RegulatorFacilityCreate schema with the specified namespace: " + targetNamespace.NamespaceName, EDTTransactionMessageType.Error);
                    throw new Exception("Unable to find a RegulatorFacilityCreate schema with the specified version: " + version);
                }

                //the outgoing schema version is dependant on the version specified in the input schema.
                //so parse the version and then look for the appropriate output (response schema).
                version = targetNamespace.ExtractVersion();

                //now try and find the response schema with the version parsed from the targetSchema.
                outputSchemaMetadata = XmlSchemas.GetSchemaMetadata(XmlSchema.RegulatorFacilityCreateResponse, version);
                if (outputSchemaMetadata == null)
                {
                    TransactionScope.WriteMessage("Unable to find a RegulatorFacilityCreateResponse schema with the specified version: " + version, EDTTransactionMessageType.Error);
                    throw new Exception("Unable to find a RegulatorFacilityCreateResponse schema with the specified version: " + version);
                }

                schemaValidationResult = xml.IsValidAgainstSchema(inputSchemaMetadata);
                if (!schemaValidationResult.IsValid)
                {
                    //make a new package so we have a storage area for the errors to be shipped back in the response xml.
                    package = new RegulatorXmlObjectPacket <RegulatorFacilityCreateMode, FacilityCreatePackage>();

                    //package is invalid due to schema validation errors, update the transaction status, and write some diagnostic information.
                    //Merge in the schema validation error messages and associate them with the transaction.
                    TransactionScope.WriteActivity("XML Document is not valid against the schema.");
                    package.Packet.Workspace.Messages.Add("XML Document is not valid against the schema.", FacilityOperationMessageType.Error);

                    foreach (var error in schemaValidationResult.Errors)
                    {
                        TransactionScope.WriteMessage("Schema Validation Error: " + error, EDTTransactionMessageType.Error);
                        package.Packet.Workspace.Messages.Add("Schema Validation Error: " + error, FacilityOperationMessageType.Error);
                    }

                    TransactionScope.WriteMessage("XML document does not validate against the schema.", EDTTransactionMessageType.Error);
                    TransactionScope.Complete(EDTTransactionStatus.Rejected);
                }
                else
                {
                    TransactionScope.WriteActivity("XML Document is valid against the schema.");

                    //deserialize the data into the object structure.
                    RegulatorFacilityCreateXmlSerializer serializer = new RegulatorFacilityCreateXmlSerializer(Repository);
                    package = serializer.Deserialize(rfcXml);
                    package.Packet.Version = version;                     //add in the version 4/1/2014.
                    mode = package.Mode;

                    // error if DataCollectionDate is less than 1970 and greater than today at 11:59
                    if (package.Packet.CERSPoint != null &&
                        package.Packet.CERSPoint.DataCollectionDate != null &&
                        (package.Packet.CERSPoint.DataCollectionDate < new DateTime(1970, 1, 1) || package.Packet.CERSPoint.DataCollectionDate > DateTime.Now.AddDays(1).AddTicks(-1)))
                    {
                        package.Packet.Workspace.Messages.Add("DataCollectionDate is out of range.", FacilityOperationMessageType.Error);
                    }

                    if (!package.Packet.HasErrors())
                    {
                        ServiceManager.Facilities.Create(package.Packet, regulatorCode, mode, true);

                        if (mode == RegulatorFacilityCreateMode.Commit && package.Packet.Workspace.FacilityCreated)
                        {
                            TransactionScope.Connect(package.Packet.Workspace.Facility);
                        }
                    }

                    //if the package had errors, set rejected, otherwise set accepted.
                    if (package.Packet.HasErrors())
                    {
                        TransactionScope.Complete(EDTTransactionStatus.Rejected);
                    }
                    else
                    {
                        TransactionScope.Complete(EDTTransactionStatus.Accepted);
                    }
                }
            }

            //prepare our output response XML.
            XElement responseXml = responseSerializer.PreparePackage(TransactionScope.Transaction, outputSchemaMetadata);

            responseSerializer.AddTransaction(responseXml, TransactionScope.Transaction, mode);

            //we should always have a package (unless schema validation failed).
            if (package != null)
            {
                //add the result hive to the root node if we created a facility (or virtually did in trial mode)
                responseSerializer.AddResult(responseXml, package.Packet, mode);

                //if using the 1/06 schema version...
                if (!string.IsNullOrWhiteSpace(package.Packet.Version) && (package.Packet.Version.IndexOf("1/06") > -1))
                {
                    responseSerializer.AddPotentialDuplicates(responseXml, package.Packet);
                }
            }

            //add the messages generated during the process.
            responseSerializer.AddMessages(responseXml, package.Packet);

            TransactionScope.SaveXml(responseXml, EDTTransactionXmlDirection.Outbound);
            return(responseXml);
        }
        public XElement Process(Stream stream, int regulatorCode)
        {
            //make serializers needed
            RegulatorFacilitySubmittalResponseXmlSerializer           responseSerializer = new RegulatorFacilitySubmittalResponseXmlSerializer(Repository);
            RegulatorFacilitySubmittalActionNotificationXmlSerializer serializer         = new RegulatorFacilitySubmittalActionNotificationXmlSerializer(Repository);

            //contextRegulator is always the regulator this Processor is working under the context of. In this case, the assumption is, this Regulator is
            //ALWAYS a CUPA.
            Regulator contextRegulator = Repository.Regulators.GetByEDTIdentityKey(regulatorCode);

            if (contextRegulator == null)
            {
                throw new ArgumentException("RegulatorCode does not contain a valid number.", "regulatorCode");
            }

            TransactionScope.Connect(contextRegulator);

            XmlSchemaValidationResult schemaValidationResult = null;

            var rfsanXml = ConvertStreamToXDocument(stream);

            if (rfsanXml != null)
            {
                string xml = rfsanXml.ToString();
                TransactionScope.SaveXml(xml, EDTTransactionXmlDirection.Inbound);
                TransactionScope.WriteActivity("XML Document is validating...");

                schemaValidationResult = xml.IsValidAgainstSchema(XmlSchema.RegulatorFacilitySubmittalActionNotification);
                if (!schemaValidationResult.IsValid)
                {
                    //package is invalid due to schema validation errors, update the transaction status write some info.
                    //Merge in the schema validation error messages and associate them with the transaction.
                    TransactionScope.WriteActivity("XML Document is not valid against the schema.");
                    foreach (var error in schemaValidationResult.Errors)
                    {
                        TransactionScope.WriteMessage("Schema Validation Error: " + error, EDTTransactionMessageType.Error);
                    }
                    TransactionScope.WriteMessage("XML document does not validate against the schema.", EDTTransactionMessageType.Error);
                    TransactionScope.Complete(EDTTransactionStatus.Rejected);
                }
                else
                {
                    TransactionScope.WriteActivity("XML Document is valid against the schema.");

                    //deserialize the XML into an object graph package.
                    var package = serializer.Deserialize(rfsanXml);
                    TransactionScope.SetEDTClientKey(package.RegulatorTransactionKey);
                    int totalErrorCount = 0;
                    int errorCount      = 0;

                    //lets analyze and process each one.
                    foreach (var se in package.Packets)
                    {
                        errorCount = 0;
                        var targetSE = Repository.FacilitySubmittalElements.FindByKey(se.CERSUniqueKey.Value);
                        if (targetSE != null)
                        {
                            //verify the CERSID from the XML matches the FSE
                            if (targetSE.CERSID != se.CERSID.Value)
                            {
                                errorCount++;
                                TransactionScope.WriteMessage("Facility Submittal Element with CERSUniqueKey '" + se.CERSUniqueKey.Value.ToString() + "' does not belong to CERSID '" + se.CERSID.Value + "'.", EDTTransactionMessageType.Error);
                            }

                            //Verify the SubmittalElementID from the XML matches the FSE
                            if (targetSE.SubmittalElementID != (int)se.SubmittalElement.Value)
                            {
                                errorCount++;
                                TransactionScope.WriteMessage("Facility Submittal Element with CERSUniqueKey '" + se.CERSUniqueKey.Value.ToString() + "' is not a Submittal Element of type '" + (int)se.SubmittalElement.Value + "'.", EDTTransactionMessageType.Error);
                            }

                            if (targetSE.SubmittalActionDateTime.HasValue)
                            {
                                //verify the SubmittalActionDateTime on the existing FSE is prior to the SubmittalActionDateTime on the targetFSE (from XML)
                                if (se.ActionOn.Value < targetSE.SubmittalActionDateTime.Value)
                                {
                                    TransactionScope.WriteMessage("The SubmittalActionOn value must be greater than the existing SubmittalActionOn value (" + targetSE.SubmittalActionDateTime.Value.ToString() + ") for Submittal Element with CERSUniqueKey " + se.CERSUniqueKey.Value.ToString() + ".", EDTTransactionMessageType.Error);
                                }
                            }

                            //Get the Facility, and make sure it exists first.
                            Facility facility = Repository.Facilities.GetByID(targetSE.CERSID);
                            if (facility != null)
                            {
                                //figure out the CUPA.
                                var CUPARegulator = Repository.Facilities.GetCUPA(facility);
                                if (CUPARegulator != null)
                                {
                                    //Ensure that the Facilities CUPA is associated with the CUPA calling this processor.
                                    if (contextRegulator.ID != CUPARegulator.ID)
                                    {
                                        errorCount++;
                                        TransactionScope.WriteMessage("Facility Submittal Element with CERSUniqueKey '" + se.CERSUniqueKey.Value.ToString() + "' is assigned to a CUPA the current account is not authorized to submit for.", EDTTransactionMessageType.Error);
                                    }
                                }
                                else
                                {
                                    errorCount++;
                                    TransactionScope.WriteMessage("Cannot identify the CUPA for the Facility Submittal Element with CERSUniqueKey '" + se.CERSUniqueKey.Value.ToString() + "'.", EDTTransactionMessageType.Error);
                                }
                            }
                            else
                            {
                                errorCount++;
                                TransactionScope.WriteMessage("A facility with CERSID '" + targetSE.CERSID + "' cannot be found and therefore Facility Submittal Element with CERSUniqueKey '" + se.CERSUniqueKey.Value.ToString() + "' cannot be updated/found.", EDTTransactionMessageType.Error);
                            }

                            //Get the regulator that is described in the XML as the Regulating body that is changing the submittal action information.
                            var regulator = Repository.Regulators.GetByEDTIdentityKey(se.RegulatorCode.Value);
                            if (regulator != null)
                            {
                                se.TargetRegulator = regulator;
                            }
                            else
                            {
                                errorCount++;
                                TransactionScope.WriteMessage("Facility Submittal Element with CERSUniqueKey '" + se.CERSUniqueKey.Value.ToString() + "' specifies '" + se.RegulatorCode.Value + "' for the RegulatorCode element which is not valid.", EDTTransactionMessageType.Error);
                            }

                            //make sure that NextDueDate is in the future.
                            if (se.NextDueDate != null)
                            {
                                if (se.NextDueDate.Value < DateTime.Now)
                                {
                                    errorCount++;
                                    TransactionScope.WriteMessage("Facility Submittal Element with CERSUniqueKey '" + se.CERSUniqueKey.Value.ToString() + "' has a NextDueDate of '" + se.NextDueDate.Value + "' which occurs in the past and is not allowed.", EDTTransactionMessageType.Error);
                                }
                            }
                        }
                        else
                        {
                            errorCount++;
                            TransactionScope.WriteMessage("Facility Submittal Element with CERSUniqueKey '" + se.CERSUniqueKey.Value.ToString() + "' was not found.", EDTTransactionMessageType.Error);
                        }

                        if (errorCount == 0)
                        {
                            se.FacilitySubmittalElement = targetSE;
                        }

                        totalErrorCount += errorCount;
                    }

                    if (totalErrorCount > 0)
                    {
                        TransactionScope.WriteActivity("Found " + totalErrorCount + " total error(s) with package. Setting to Rejected.");
                        TransactionScope.Complete(EDTTransactionStatus.Rejected);
                    }
                    else
                    {
                        try
                        {
                            FacilitySubmittalElement fse = null;

                            //all is good, so lets update them all and process it.
                            foreach (var se in package.Packets)
                            {
                                fse = se.FacilitySubmittalElement;
                                if (fse != null)
                                {
                                    ServiceManager.BusinessLogic.SubmittalElements.UpdateFacilitySubmittalElementStatus
                                    (
                                        fse,
                                        se.Status.Value,
                                        se.ActionOn,
                                        se.Comments,
                                        se.NextDueDate,
                                        Repository.ContextAccount,
                                        se.TargetRegulator.ID,
                                        se.AgentName,
                                        se.AgentEmail,
                                        submittalActionEDTTransaction: TransactionScope.Transaction
                                    );

                                    TransactionScope.Connect(fse);
                                }
                            }
                            TransactionScope.WriteActivity("All Facility Submittal Elements (" + package.Packets + ") updated successfully.");
                            TransactionScope.SetStatus(EDTTransactionStatus.Accepted);
                            TransactionScope.SetProcessedOn();
                        }
                        catch (Exception ex)
                        {
                            TransactionScope.WriteActivity("Errors occurred persisting updates to database.", ex);
                            TransactionScope.Complete(EDTTransactionStatus.ErrorProcessing);
                        }
                    }
                }
            }
            else
            {
                TransactionScope.WriteMessage("No package received.", EDTTransactionMessageType.Error);
                TransactionScope.Complete(EDTTransactionStatus.ErrorProcessing);
            }

            XElement responseXml = responseSerializer.PreparePackage(TransactionScope.Transaction);

            responseSerializer.AddTransaction(responseXml, TransactionScope.Transaction);
            responseSerializer.AddSummary(responseXml, TransactionScope.Transaction);
            TransactionScope.SaveXml(responseXml, EDTTransactionXmlDirection.Outbound);
            return(responseXml);
        }
Beispiel #4
0
        public XElement Process(Stream stream, int regulatorCode)
        {
            RegulatorFacilityMetadataResponseXmlSerializer responseSerializer = new RegulatorFacilityMetadataResponseXmlSerializer(Repository);
            Regulator regulator = Repository.Regulators.GetByEDTIdentityKey(regulatorCode);

            if (regulator == null)
            {
                throw new ArgumentException("RegulatorCode does not contain a valid number.", "regulatorCode");
            }

            TransactionScope.Connect(regulator);

            //declare the package to be use to inflate the XML.
            RegulatorXmlObjectPacket <RegulatorFacilityMetadataPackage> package = null;

            XmlSchemaValidationResult schemaValidationResult = null;
            var rfmXml = ConvertStreamToXDocument(stream);

            if (rfmXml != null)
            {
                string xml = rfmXml.ToString();
                TransactionScope.SaveXml(xml, EDTTransactionXmlDirection.Inbound);
                TransactionScope.WriteActivity("XML Document is validating...");

                schemaValidationResult = xml.IsValidAgainstSchema(XmlSchema.RegulatorFacilityMetadata);
                if (!schemaValidationResult.IsValid)
                {
                    //package is invalid due to schema validation errors, update the transaction status write some info.
                    //Merge in the schema validation error messages and associate them with the transaction.

                    TransactionScope.WriteActivity("XML Document is not valid against the schema.");
                    foreach (var error in schemaValidationResult.Errors)
                    {
                        TransactionScope.WriteMessage("Schema Validation Error: " + error, EDTTransactionMessageType.Error);
                    }
                    TransactionScope.WriteMessage("XML document does not validate against the schema.", EDTTransactionMessageType.Error);
                    TransactionScope.Complete(EDTTransactionStatus.Rejected);
                }
                else
                {
                    TransactionScope.WriteActivity("XML Document is valid against the schema.");

                    //deserialize the data into the object structure.
                    RegulatorFacilityMetadataXmlSerializer serializer = new RegulatorFacilityMetadataXmlSerializer(Repository);
                    package = serializer.Deserialize(rfmXml);

                    TransactionScope.SetEDTClientKey(package.RegulatorTransactionKey);

                    package.Packet.Workspace.Facility = Repository.Facilities.GetByID(package.Packet.CERSID);
                    if (package.Packet.Workspace.Facility == null)
                    {
                        TransactionScope.WriteMessage("There is no facility with CERSID " + package.Packet.CERSID, EDTTransactionMessageType.Error);
                        package.Packet.Workspace.Messages.Add("There is no facility with CERSID " + package.Packet.CERSID, FacilityOperationMessageType.Error);
                        TransactionScope.Complete(EDTTransactionStatus.Rejected);
                    }
                    else
                    {
                        //get the original FRSE Mappings
                        var originalFRSEMappings = GetOriginalFRSEMappings(package.Packet.CERSID);

                        //merge the XML data into the existing FRSE objects.
                        ServiceManager.Facilities.MergeFacilityRegulatorSubmittalElementCustomMappings(package.Packet, regulator.ID);

                        //generate debug messages so we know what happened here.
                        DetermineFacilityRegulatorSubmittalElementChanges(package, originalFRSEMappings);

                        //merge the CERS Geo data in XML into the object graph.
                        ServiceManager.Facilities.MergeCERSFacilityGeoPoint(package.Packet);

                        //commit the changes to the database.
                        CommitChanges(package);

                        //complete the transaction indicating everything went according to plan.
                        TransactionScope.Complete(EDTTransactionStatus.Accepted);
                    }
                }
            }

            //prepare our output response XML.
            XElement responseXml = responseSerializer.PreparePackage(TransactionScope.Transaction);

            responseSerializer.AddTransaction(responseXml, TransactionScope.Transaction);
            if (package != null)
            {
                responseSerializer.AddMessages(responseXml, package.Packet);
            }

            TransactionScope.SaveXml(responseXml, EDTTransactionXmlDirection.Outbound);
            return(responseXml);
        }