protected virtual bool DoExtract()
        {
            if (!_submissionTrackingDataType.ETLCompletionDateTimeSpecified || !_submissionTrackingDataType.DETChangeCompletionDateTimeSpecified)
            {
                // Attempt to run the ETL to populate staging tables
                if (_submissionTrackingDataType.ETLCompletionDateTimeSpecified || _submissionTrackingDataType.DETChangeCompletionDateTimeSpecified)
                {
                    // Both must be specified, or neither must be specified
                    throw new ArgException("Both ETL completion dates have not been set for row {0} in the submission tracking table",
                                           _submissionTrackingDataTypePK);
                }
                if (string.IsNullOrEmpty(_storedProcName))
                {
                    AppendAuditLogEvent("The \"{0}\" config param has not been specified for the service and the ETL stored procedure has not executed, so the service cannot continue, exiting plugin ...",
                                        CONFIG_PARAM_ETL_NAME);
                    return(false);
                }
                _submissionTrackingDataTypePK = DoExtract(this, _etlDao, _storedProcName, _commandTimeout);
                if (_submissionTrackingDataTypePK == null)
                {
                    AppendAuditLogEvent("The ETL stored procedure indicated that this service should not continue, exiting plugin ...");
                    return(false);
                }

                _submissionTrackingDataType = SubmissionTrackingTableHelper.GetActiveSubmissionTrackingElement(_stagingDao, _submissionTrackingDataTypePK);
            }
            else
            {
                AppendAuditLogEvent("The ETL stored procedure has already run as referenced by row {0} in the submission tracking table with status \"{1}\" ...",
                                    _submissionTrackingDataTypePK, _submissionTrackingDataType.WorkflowStatus.ToString());
            }
            return(true);
        }
        protected virtual bool DoSubmission(string submitFilePath, out string submitTransactionId)
        {
            submitTransactionId = null;

            if (_submissionPartner == null)
            {
                AppendAuditLogEvent("The \"{0}\" config param was not specified. Plugin will not submit.", CONFIG_PARAM_SUBMISSION_PARTNER_NAME);
                _submissionTrackingDataType.WorkflowStatus        = TransactionStatusCode.Completed;
                _submissionTrackingDataType.WorkflowStatusMessage = "A submission partner was not specified";
                SubmissionTrackingTableHelper.Update(_stagingDao, _submissionTrackingDataTypePK, _submissionTrackingDataType);
                return(false);
            }
            try
            {
                AppendAuditLogEvent("Submitting ICIS document to partner \"{0}\"", _submissionPartner.Name);

                submitTransactionId =
                    SubmitFileToPartner(_dataRequest.TransactionId, _submissionPartner, _flowName, null, submitFilePath);
            }
            finally
            {
                FileUtils.SafeDeleteFile(submitFilePath);
            }

            return(true);
        }
        protected virtual bool DoGetStatusAndDownloadDocuments(out string localTransactionId, out IList <string> documentNames)
        {
            documentNames      = null;
            localTransactionId = null;

            AppendAuditLogEvent("Checking status of the ICIS submission with transaction id \"{0}\"", _submissionTrackingDataType.SubmissionTransactionId);

            CommonTransactionStatusCode statusCode = UpdateStatusOfNetworkTransaction(_submissionTrackingDataType.SubmissionTransactionId,
                                                                                      out localTransactionId);

            _submissionTrackingDataType.SubmissionStatusDateTimeSpecified    = true;
            _submissionTrackingDataType.SubmissionStatusDateTime             = DateTime.Now;
            _submissionTrackingDataType.SubmissionTransactionStatusSpecified = true;
            _submissionTrackingDataType.SubmissionTransactionStatus          = EnumUtils.ParseEnum <TransactionStatusCode>(statusCode.ToString());

            if (statusCode == CommonTransactionStatusCode.Failed)
            {
                _submissionTrackingDataType.WorkflowStatus = TransactionStatusCode.Failed;
            }
            else
            {
                _submissionTrackingDataType.WorkflowStatus = TransactionStatusCode.Pending;
            }

            SubmissionTrackingTableHelper.Update(_baseDao, _submissionTrackingDataTypePK, _submissionTrackingDataType);

            if ((statusCode != CommonTransactionStatusCode.Completed) && (statusCode != CommonTransactionStatusCode.Failed))
            {
                AppendAuditLogEvent("Another attempt to process the ICIS submission with transaction id \"{0}\" will be made when the service runs again.",
                                    _submissionTrackingDataType.SubmissionTransactionId);
                return(false);
            }
            else if (statusCode == CommonTransactionStatusCode.Failed)
            {
                return(false);
            }

            AppendAuditLogEvent("Attempting to download response documents for ICIS submission with transaction id \"{0}\"",
                                _submissionTrackingDataType.SubmissionTransactionId);

            try
            {
                _transactionManager.DownloadNetworkDocumentsAndAddToTransaction(localTransactionId, out statusCode);
            }
            catch (Exception ex)
            {
                AppendAuditLogEvent("Failed to download response documents for ICIS submission with transaction id \"{0}\" with error: {1}",
                                    _submissionTrackingDataType.SubmissionTransactionId, ExceptionUtils.GetDeepExceptionMessage(ex));
                AppendAuditLogEvent("Another attempt to process the ICIS submission with transaction id \"{0}\" will be made when the service runs again.",
                                    _submissionTrackingDataType.SubmissionTransactionId);
                return(false);
            }

            documentNames = _documentManager.GetAllDocumentNames(localTransactionId);

            return(true);
        }
        public virtual void ProcessTask(string requestId)
        {
            ProcessTaskInit(requestId);

            _submissionTrackingDataType = SubmissionTrackingTableHelper.GetActiveSubmissionTrackingElement(_baseDao, out _submissionTrackingDataTypePK);
            if (_submissionTrackingDataType == null)
            {
                AppendAuditLogEvent("There are no pending submissions in the submission tracking table, existing plugin ...");
                return;
            }
            DebugUtils.AssertDebuggerBreak(_submissionTrackingDataTypePK != null);
            if (!_submissionTrackingDataType.SubmissionDateTimeSpecified)
            {
                AppendAuditLogEvent("There is a pending row in the submission tracking table, \"{0},\" but it does not have a submission date/time yet, existing plugin ...",
                                    _submissionTrackingDataTypePK);
                return;
            }
            try
            {
                if (string.IsNullOrEmpty(_submissionTrackingDataType.SubmissionTransactionId))
                {
                    throw new ArgumentException("There is a pending row in the submission tracking table, \"{0},\" with a submission date/time, but the submission transaction id is missing",
                                                _submissionTrackingDataTypePK);
                }

                // Attempt to get status of the active submission and download the response documents
                IList <string> documentNames;
                string         localTransactionId;

                if (!DoGetStatusAndDownloadDocuments(out localTransactionId, out documentNames))
                {
                    return;
                }

                Windsor.Node2008.WNOSDomain.Document zipResponseFile;
                if (!DoProcessResponseDocuments(localTransactionId, documentNames, out zipResponseFile))
                {
                    return;
                }

                _submissionTrackingDataType.WorkflowStatus        = TransactionStatusCode.Completed;
                _submissionTrackingDataType.WorkflowStatusMessage = string.Format("Successfully downloaded response data and inserted into database");
                SubmissionTrackingTableHelper.Update(_baseDao, _submissionTrackingDataTypePK, _submissionTrackingDataType);

                DoEmailNotifications(zipResponseFile, localTransactionId);
            }
            catch (WorkflowStatusFailedException workflowStatusFailedException)
            {
                string errorMessage =
                    string.Format("An error occurred during processing: {0}",
                                  ExceptionUtils.GetDeepExceptionMessage(workflowStatusFailedException));
                if (_submissionTrackingDataTypePK != null)
                {
                    _submissionTrackingDataType.WorkflowStatus        = TransactionStatusCode.Failed;
                    _submissionTrackingDataType.WorkflowStatusMessage = errorMessage;
                    SubmissionTrackingTableHelper.Update(_baseDao, _submissionTrackingDataTypePK, _submissionTrackingDataType);
                }
                throw new ArgException(errorMessage);
            }
            catch (Exception)
            {
                // Continue on, do not set workflow status to failed, per Bill
                throw;
            }
        }
        protected virtual bool DoXmlLoad(out string submitFilePath)
        {
            submitFilePath = null;
            Type mappingAttributesType = typeof(Windsor.Node2008.WNOSPlugin.ICISNPDES_58.MappingAttributes);
            IDictionary <string, DbAppendSelectWhereClause>             selectClauses = Windsor.Node2008.WNOSPlugin.ICISNPDES_58.PayloadData.GetDefaultSelectClauses(_stagingDao);
            List <Windsor.Node2008.WNOSPlugin.ICISNPDES_58.PayloadData> payloads      =
                _objectsFromDatabase.LoadFromDatabase <Windsor.Node2008.WNOSPlugin.ICISNPDES_58.PayloadData>(_stagingDao, selectClauses, mappingAttributesType);

            // Remove payloads that don't contain any data
            if (payloads != null)
            {
                for (int i = payloads.Count - 1; i >= 0; i--)
                {
                    if (CollectionUtils.IsNullOrEmpty(payloads[i].Items))
                    {
                        // TSM: Is this log really necessary?
                        //AppendAuditLogEvent(string.Format("The payload with operation \"{0}\" will not be included in the submission because it does not contain any data", payloads[i].Operation.ToString()));
                        payloads.RemoveAt(i);
                    }
                }
            }

            if (CollectionUtils.IsNullOrEmpty(payloads))
            {
                if (_isDebugMode)
                {
                    AppendAuditLogEvent("The staging database does not contain any payloads, exiting plugin ...");
                }
                else
                {
                    _submissionTrackingDataType.WorkflowStatus        = TransactionStatusCode.Completed;
                    _submissionTrackingDataType.WorkflowStatusMessage = "The staging database does not contain any payloads to submit";
                    AppendAuditLogEvent(_submissionTrackingDataType.WorkflowStatusMessage + ", exiting plugin ...");
                    SubmissionTrackingTableHelper.Update(_stagingDao, _submissionTrackingDataTypePK, _submissionTrackingDataType);
                }
                return(false);
            }

            AppendAuditLogEvent("The following ICIS payload(s) were loaded from the database: {0}", GetPayloadsDescription(payloads));

            Windsor.Node2008.WNOSPlugin.ICISNPDES_58.Document document = new Document();

            document.Payload = payloads.ToArray();
            document.Header  = CreateHeader();

            string tempFolder  = _settingsProvider.CreateNewTempFolderPath();
            string tempXmlPath = Path.Combine(tempFolder, ICIS_SUBMISSION_XML_FILENAME);
            string tempZipPath = Path.Combine(tempFolder, ICIS_SUBMISSION_ZIP_FILENAME);

            try
            {
                AppendAuditLogEvent("Serializing ICIS payload(s) to xml ...");

                _serializationHelper.Serialize(document, tempXmlPath);

                if (_validateXml)
                {
                    ValidateXmlFileAndAttachErrorsAndFileToTransaction(tempXmlPath, "xml_schema.xml_schema.zip",
                                                                       null, _dataRequest.TransactionId);
                }

                _compressionHelper.CompressFile(tempXmlPath, tempZipPath);

                _documentManager.AddDocument(_dataRequest.TransactionId, CommonTransactionStatusCode.Completed, null, tempZipPath);
            }
            catch (Exception)
            {
                FileUtils.SafeDeleteFile(tempZipPath);
                throw;
            }
            finally
            {
                FileUtils.SafeDeleteFile(tempXmlPath);
            }

            submitFilePath = tempZipPath;

            return(true);
        }
        public override void ProcessTask(string requestId)
        {
            ProcessTaskInit(requestId);

            if (_isDebugMode)
            {
                string submitFilePath;
                DoXmlLoad(out submitFilePath);
                return;
            }

            _submissionTrackingDataType = SubmissionTrackingTableHelper.GetActiveSubmissionTrackingElement(_stagingDao, out _submissionTrackingDataTypePK);

            if (_submissionTrackingDataType == null)
            {
                _submissionTrackingDataType = new SubmissionTrackingDataType();
            }

            if (_submissionTrackingDataType.WorkflowStatus == TransactionStatusCode.Pending && _submissionTrackingDataType.ETLCompletionDateTimeSpecified == false)
            {
                AppendAuditLogEvent("Previous ETL execution in the tracking table with primary key \"{0}\" did not complete due to unrecoverable database error. Setting transaction to Failed."
                                    , _submissionTrackingDataTypePK);
                // Update submission status in tracking table
                _submissionTrackingDataType.WorkflowStatus        = TransactionStatusCode.Failed;
                _submissionTrackingDataType.WorkflowStatusMessage = "ETL did not complete due to unrecoverable database error";
                SubmissionTrackingTableHelper.Update(_stagingDao, _submissionTrackingDataTypePK, _submissionTrackingDataType);

                //create a new submission tracking record for the current workflow execution
                _submissionTrackingDataType   = new SubmissionTrackingDataType();
                _submissionTrackingDataTypePK = null;
            }
            else if (_submissionTrackingDataType.SubmissionDateTimeSpecified)
            {
                DebugUtils.AssertDebuggerBreak(_submissionTrackingDataTypePK != null);
                AppendAuditLogEvent("There is a pending partner submission in the tracking table with primary key \"{0}\", exiting plugin ...",
                                    _submissionTrackingDataTypePK);
                return;
            }

            try
            {
                // Attempt to run the ETL to populate staging tables
                if (!DoExtract())
                {
                    return;
                }
                DebugUtils.AssertDebuggerBreak(_submissionTrackingDataTypePK != null);

                // Attempt to load the submission file from staging
                string submitFilePath;
                if (!DoXmlLoad(out submitFilePath))
                {
                    return;
                }

                // Attempt to submit file
                string submitTransactionId;
                if (!DoSubmission(submitFilePath, out submitTransactionId))
                {
                    return;
                }

                // Update submission status in tracking table
                _submissionTrackingDataType.WorkflowStatus              = TransactionStatusCode.Pending;
                _submissionTrackingDataType.WorkflowStatusMessage       = "The ICIS data has been submitted";
                _submissionTrackingDataType.SubmissionDateTime          = DateTime.Now;
                _submissionTrackingDataType.SubmissionDateTimeSpecified = true;
                _submissionTrackingDataType.SubmissionTransactionId     = submitTransactionId;
                SubmissionTrackingTableHelper.Update(_stagingDao, _submissionTrackingDataTypePK, _submissionTrackingDataType);
            }
            catch (Exception ex)
            {
                var errorMessage = string.Format("An error occurred during processing inside PerformICISSubmission.ProcessTask(): {0}", ExceptionUtils.GetDeepExceptionMessage(ex));
                AppendAuditLogEvent(errorMessage);
                if (_submissionTrackingDataTypePK != null)
                {
                    _submissionTrackingDataType.WorkflowStatus        = TransactionStatusCode.Failed;
                    _submissionTrackingDataType.WorkflowStatusMessage = errorMessage;
                    SubmissionTrackingTableHelper.Update(_stagingDao, _submissionTrackingDataTypePK, _submissionTrackingDataType);
                }
                throw;
            }
        }