예제 #1
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);
        }
예제 #2
0
        /// <summary>
        /// Performs the main work of the CMESubmittalEDTProcessor.  Accepts an XDocument
        /// conforming to the CMESubmittal XML Schema Definition, and returns an XElement
        /// conforming to the CMESubmittalResponse XML Schema Definition.
        /// </summary>
        /// <param name="xDocument"></param>
        /// <returns></returns>
        public XElement Process(XDocument xDocument)
        {
            TransactionScope.SaveXml(xDocument, EDTTransactionXmlDirection.Inbound);

            XElement cmeSubmittalResponse = null;

            // Set up CMESubmittal XML Deserializer and initialize CMEPackage
            CMESubmittalXmlDeserializer cmeSubmittalXmlDeserializer = new CMESubmittalXmlDeserializer(Repository);
            CMEPackage cmePackage = new CMEPackage();

            // Retrieve CME Submittal Schema Definition
            IXmlSchemaMetadata schema = XmlSchemas.GetSchemaMetadata(XmlSchema.RegulatorCMESubmit);

            cmePackage.IsValidXMLAgainstSchema = false;             // Default to false, until validation proves otherwise
            cmeSubmittalXmlDeserializer.InitializeCMEPackage(cmePackage, accountID: Repository.ContextAccountID, edtTransaction: TransactionScope.Transaction, xDocument: xDocument);

            if (xDocument == null)
            {
                var entityGuidanceMessage = EntityGuidanceMessage.Create(GuidanceMessageCode.XMLSchemaValidationError, null, null, GuidanceLevel.Required, null, "XML Document Not Found");
                cmePackage.GuidanceMessages.Add(entityGuidanceMessage.ToGuidanceMessage());
            }
            else
            {
                // Validate XDocument:
                var validationGuidance = xDocument.ValidateCMESubmittal(schema);
                cmePackage.GuidanceMessages.AddRange(validationGuidance);
            }

            // Set CME Package's "IsValidAgainstXMLSchema" bool based on return Guidance Messages
            cmePackage.IsValidXMLAgainstSchema = !cmePackage.GuidanceMessages.Any(gm => gm.LevelID == (int)GuidanceLevel.Required && !gm.Voided);

            // If serialized document is valid, proceed with Deserializing and Validating the individual CME Entities:
            if (cmePackage.IsValidXMLAgainstSchema)
            {
                cmePackage = cmeSubmittalXmlDeserializer.DeserializeCMESubmittalPackage(xDocument, cmePackage, Repository.ContextAccountID, schema: schema);

                // Call PreSave Methods for all CME Entities (Insp, Vio, Enf, EnfVio):
                cmeSubmittalXmlDeserializer.CallPreSaveMethods(cmePackage, Repository);

                var permissionRoleMatrixCollection = ServiceManager.Security.GetRolesForAccount(Repository.ContextAccount);

                // Perform Standard Validation on the CMEPackage:
                cmePackage.Validate(Repository, callerContext: TransactionScope.CallerContext, permissions: permissionRoleMatrixCollection);
            }

            // Determine a list of Regulator IDs for the affected CME Data Entities:
            List <int> regulatorIDList = GenerateDistinctAffectedRegulatorIDs(cmePackage);

            // If CME Package is NOT valid (meaning one or more Required Guidance Messages were created,
            // we need to remove the CME Entities from the model:
            if (!cmePackage.IsValid)
            {
                cmeSubmittalXmlDeserializer.DetachEntitiesFromTransaction(cmePackage, Repository);
            }

            // Update GuidanceMessage Common fields, and link all to EDTTransaction Entity
            cmePackage.GuidanceMessages.SetCommonFields(Repository.ContextAccountID, creating: true);
            foreach (var gm in cmePackage.GuidanceMessages)
            {
                gm.EDTTransaction = cmePackage.EDTTransaction;
            }

            // Populate EDT Transaction Messages
            PopulateEDTTranactionMessages(cmePackage);
            PopulateCMEBatchMetaData(cmePackage);

            // Persist the changes to the DB by calling Complete on the EDTTransactionScope
            if (cmePackage.IsValid)
            {
                TransactionScope.Complete(EDTTransactionStatus.Accepted);
            }
            else
            {
                TransactionScope.Complete(EDTTransactionStatus.Rejected);
            }

            // Populate RegulatorEDTTransactions Based Upon CMEBatch CME Data Entities
            GenerateRegulatorEDTTransactions(regulatorIDList);

            // Retrieve the EDT Transaction Key:
            Guid edtTransactionKey = cmePackage.EDTTransaction.Key;

            // Build a CMEPackage Object from an EDT Transaction Key
            CMEPackage cmePackageResponse = EDTTransactionToCMEPackage.BuildCMEPackageFromEDTTransaction(Repository, edtTransactionKey: edtTransactionKey);

            // Generate a CMESubmittalResponse from an EDT Transaction Key
            CMESubmittalResponseXmlSerializer cmeSubmittalResponseXmlSerializer = new CMESubmittalResponseXmlSerializer(Repository);

            cmeSubmittalResponse = cmeSubmittalResponseXmlSerializer.GenerateCMESubmittalResponsePackage(cmePackageResponse);

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