Esempio n. 1
0
        public ScheduledItem ProcessScheduledItem(string scheduleId, bool forceRun, out Activity activity)
        {
            activity = null;
            using (INodeProcessorMutex mutex = GetMutex(scheduleId))
            {
                if (!mutex.IsAcquired)
                {
                    LOG.Debug("Exiting ProcessScheduleItem(), could not acquire mutex");
                    return(null);        // Another thread is already working on this transaction, get out of here
                }
                bool          isRunNow;
                ScheduledItem scheduledItem = ScheduleManager.GetScheduledItem(scheduleId, out isRunNow);
                /*************************************/
                var isDebugging        = DebugUtils.IsDebugging;
                var computerPrefix     = "COMPUTER: ";
                var allowScheduleToRun = !isDebugging;
                var hasComputerPrefix  = scheduledItem.Name.StartsWith(computerPrefix, StringComparison.OrdinalIgnoreCase);
                if (hasComputerPrefix)
                {
                    var specialPrefix    = computerPrefix + Environment.MachineName;
                    var hasSpecialPrefix = scheduledItem.Name.StartsWith(specialPrefix, StringComparison.OrdinalIgnoreCase);
                    allowScheduleToRun = hasSpecialPrefix;
                }
                if (!allowScheduleToRun)
                {
                    return(null);
                }
                /*************************************/
                DateTime startTime = DateTime.Now;
                // Make sure the transaction has not been processed yet
                if (!forceRun && ((scheduledItem.NextRunOn > startTime) && !isRunNow))
                {
                    LOG.Debug("Exiting ProcessScheduledItem(), schedule {0} has already run",
                              scheduledItem);
                    return(null);
                }

                string flowName = _flowManager.GetDataFlowNameById(scheduledItem.FlowId);
                activity = new Activity(NodeMethod.Schedule, flowName, scheduledItem.Name, ActivityType.Info,
                                        null, NetworkUtils.GetLocalIp(), "Start processing schedule: \"{0}\"",
                                        scheduledItem.Name);
                string transactionId = null;
                try
                {
                    // Make sure the user that created the schedule is still active
                    UserAccount userAccount = _accountManager.GetById(scheduledItem.ModifiedById);
                    if ((userAccount == null) || !userAccount.IsActive)
                    {
                        activity.AppendFormat("The user account that created the scheduled item \"{0}\" is no longer active.  Scheduled item cannot execute.",
                                              scheduledItem.Name);
                        return(null);
                    }
                    activity.ModifiedById = userAccount.Id;

                    scheduledItem.ExecuteStatus = ScheduleExecuteStatus.Running;
                    ScheduleManager.UpdateScheduleStatus(scheduledItem.Id, scheduledItem.ExecuteStatus);

                    transactionId =
                        _transactionManager.CreateTransaction(NodeMethod.Schedule, EndpointVersionType.Undefined,
                                                              scheduledItem.FlowId, scheduledItem.Name, userAccount.Id,
                                                              CommonTransactionStatusCode.Processing,
                                                              null, null, null, false);
                    activity.TransactionId = transactionId;

                    SchedulePostProcessingAction postProcessingAction = SchedulePostProcessingAction.ContinueNormally;

                    switch (scheduledItem.SourceType)
                    {
                    case ScheduledItemSourceType.LocalService:
                        postProcessingAction = ProcessLocalServiceSource(scheduledItem, activity, transactionId);
                        break;

                    case ScheduledItemSourceType.File:
                        ProcessFileSource(scheduledItem, activity, transactionId);
                        break;

                    case ScheduledItemSourceType.WebServiceQuery:
                        ProcessWebServiceQuerySource(scheduledItem, activity, transactionId);
                        break;

                    case ScheduledItemSourceType.WebServiceSolicit:
                        ProcessWebServiceSolicitSource(scheduledItem, activity, transactionId);
                        break;

                    default:
                        throw new ArgumentException(string.Format("Unrecognized scheduledItem.SourceType: {0}",
                                                                  scheduledItem.SourceType));
                    }

                    TransactionStatus transactionStatus = null;
                    if (postProcessingAction != SchedulePostProcessingAction.None)
                    {
                        if (scheduledItem.TargetType != ScheduledItemTargetType.None)
                        {
                            transactionStatus =
                                _transactionManager.SetTransactionStatus(transactionId, CommonTransactionStatusCode.Processed,
                                                                         null, false);
                            switch (scheduledItem.TargetType)
                            {
                            case ScheduledItemTargetType.LocalService:
                                ProcessLocalServiceTarget(transactionStatus, scheduledItem, activity);
                                break;

                            case ScheduledItemTargetType.Email:
                                ProcessEmailTarget(transactionStatus, scheduledItem, activity);
                                break;

                            case ScheduledItemTargetType.File:
                                ProcessFileTarget(transactionStatus, scheduledItem, activity);
                                break;

                            case ScheduledItemTargetType.Partner:
                                ProcessPartnerTarget(transactionStatus, scheduledItem, activity);
                                break;

                            case ScheduledItemTargetType.Schematron:
                                ProcessSchematronTarget(transactionStatus, scheduledItem, activity);
                                break;

                            default:
                                throw new ArgumentException(string.Format("Unrecognized scheduledItem.TargetType: {0}",
                                                                          scheduledItem.TargetType));
                            }
                        }
                    }

                    transactionStatus =
                        _transactionManager.SetTransactionStatus(transactionId, CommonTransactionStatusCode.Completed,
                                                                 null, true);

                    activity.AppendFormat("End processing schedule: \"{0}\", processing duration: {1}",
                                          scheduledItem.Name, TimeSpan.FromTicks(DateTime.Now.Ticks - startTime.Ticks).ToString());
                    activity.AppendFormat("Transaction \"{0}\" status set to \"{1}\"", transactionStatus.Id.ToString(),
                                          transactionStatus.Status.ToString());
                    _notificationManager.DoScheduleNotifications(transactionStatus, scheduledItem.FlowId,
                                                                 scheduledItem.Name);
                    scheduledItem.ExecuteStatus = ScheduleExecuteStatus.CompletedSuccess;
                }
                catch (Exception e)
                {
                    activity.Type = ActivityType.Error;
                    TransactionStatus transactionStatus = null;
                    if (transactionId != null)
                    {
                        transactionStatus =
                            _transactionManager.SetTransactionStatus(transactionId, CommonTransactionStatusCode.Failed,
                                                                     e.Message, true);
                        activity.AppendFormat("Transaction \"{0}\" status set to \"{1}\"", transactionStatus.Id.ToString(),
                                              transactionStatus.Status.ToString());
                    }
                    LogActivityError(activity, ExceptionUtils.ToShortString(e));
                    LOG.Error("ProcessTransactionRequest() threw an exception.", e);
                    if (transactionId != null)
                    {
                        _notificationManager.DoScheduleNotifications(transactionStatus, scheduledItem.FlowId,
                                                                     scheduledItem.Name,
                                                                     "Error: " + ExceptionUtils.GetDeepExceptionMessageOnly(e));
                    }
                    scheduledItem.ExecuteStatus = ScheduleExecuteStatus.CompletedFailure;
                }
                finally
                {
                    ActivityManager.Log(activity);
                    UpdateScheduleRunInfo(scheduledItem, activity);
                }
                return(scheduledItem);
            }
        }
Esempio n. 2
0
        protected void ProcessSubmitTransaction(string transactionId)
        {
            using (INodeProcessorMutex mutex = GetMutex(transactionId))
            {
                if (!mutex.IsAcquired)
                {
                    LOG.Debug("Exiting ProcessTransactionRequest(), could not acquire mutex for transaction {0}",
                              transactionId);
                    return;     // Another thread is already working on this transaction, get out of here
                }
                // Make sure the transaction has not been processed yet
                string transactionModifiedBy;
                if (!TransactionManager.IsUnprocessed(transactionId, out transactionModifiedBy))
                {
                    LOG.Debug("Exiting ProcessSubmitTransaction(), transaction {0} has already been processed",
                              transactionId);
                    return;
                }
                DateTime startTime = DateTime.Now;
                Activity activity  =
                    new Activity(NodeMethod.Submit, null, null, ActivityType.Info, transactionId, NetworkUtils.GetLocalIp(),
                                 "Start processing submit transaction: \"{0}\"", transactionId);
                activity.ModifiedById = transactionModifiedBy;

                try
                {
                    TransactionManager.SetTransactionStatus(transactionId, CommonTransactionStatusCode.Pending,
                                                            "Processing submit transaction", false);
                    // Get the document processing service
                    string      flowName, operation;
                    DataService submitService =
                        TransactionManager.GetSubmitDocumentServiceForTransaction(transactionId, out flowName,
                                                                                  out operation);
                    if (submitService == null)
                    {
                        if (!string.IsNullOrEmpty(operation))
                        {
                            throw new ArgumentException(string.Format("A valid Submit service was not found for the flow \"{0}\" and operation \"{1}\"",
                                                                      flowName, operation));
                        }
                        // Let empty operation pass through, even without a valid service, per Mark
                    }
                    else if (!submitService.IsActive)
                    {
                        throw new ArgumentException(string.Format("The Submit service is not active for the flow \"{0}\" and operation \"{1}\"",
                                                                  flowName, operation));
                    }
                    if (submitService == null)
                    {
                        activity.Append("No service found for Submit transaction");
                        TransactionStatus transactionStatus =
                            TransactionManager.SetTransactionStatusIfNotStatus(transactionId, CommonTransactionStatusCode.ReceivedUnprocessed,
                                                                               "Received unprocessed submit transaction",
                                                                               CommonTransactionStatusCode.Received, true);
                        activity.AppendFormat("Transaction status set to \"{0}\"", transactionStatus.Status.ToString());
                    }
                    else
                    {
                        CommonTransactionStatusCode submitTransactionStatus = CommonTransactionStatusCode.Processed;
                        string           submitTransactionStatusDetail      = "Finished processing submit transaction";
                        ISubmitProcessor submitProcessor;
                        using (IPluginDisposer disposer = PluginLoader.LoadSubmitProcessor(submitService, out submitProcessor))
                        {
                            TransactionManager.SetTransactionStatus(transactionId, CommonTransactionStatusCode.Processing,
                                                                    "Processing submit transaction", true);
                            activity.Append("Set transaction status to Processing");
                            activity.AppendFormat("Processing Submit transaction for flow \"{0}\" and operation \"{1}\" using plugin \"{2}\"",
                                                  flowName, operation, submitProcessor.GetType().FullName);

                            try
                            {
                                ISubmitProcessorEx submitProcessorEx = submitProcessor as ISubmitProcessorEx;
                                if (submitProcessorEx != null)
                                {
                                    submitTransactionStatus =
                                        submitProcessorEx.ProcessSubmitAndReturnStatus(transactionId,
                                                                                       out submitTransactionStatusDetail);
                                    activity.AppendFormat("Submit processing plugin returned status of \"{0}\"",
                                                          submitTransactionStatus.ToString());
                                }
                                else
                                {
                                    submitProcessor.ProcessSubmit(transactionId);
                                }
                            }
                            finally
                            {
                                activity.Append(submitProcessor.GetAuditLogEvents());
                            }

                            TimeSpan processLength = DateTime.Now - startTime;
                            activity.AppendFormat("Process time: {0}", processLength.ToString());
                        }
                        activity.Append("Finished processing submit transaction");
                        TransactionStatus transactionStatus =
                            TransactionManager.SetTransactionStatusIfNotStatus(transactionId, submitTransactionStatus,
                                                                               submitTransactionStatusDetail,
                                                                               CommonTransactionStatusCode.Received |
                                                                               CommonTransactionStatusCode.Completed |
                                                                               CommonTransactionStatusCode.Failed, true);
                        activity.AppendFormat("Transaction status set to \"{0}\"", transactionStatus.Status.ToString());
                        activity.AppendFormat(TransactionManager.DoTransactionNotifications(transactionId));
                    }
                }
                catch (Exception e)
                {
                    LOG.Error("ProcessSubmitTransaction() threw an exception.", e);
                    TransactionStatus transactionStatus =
                        TransactionManager.SetTransactionStatusIfNotStatus(transactionId, CommonTransactionStatusCode.Failed,
                                                                           e.Message, CommonTransactionStatusCode.Received, true);

                    activity.AppendFormat("Transaction status set to \"{0}\"", transactionStatus.Status.ToString());
                    activity.Append(ExceptionUtils.ToShortString(e));
                    activity.Type = ActivityType.Error;
                    activity.AppendFormat(TransactionManager.DoTransactionNotifications(transactionId));
                }
                finally
                {
                    ActivityManager.Log(activity);
                }
            }
        }
        protected void ProcessSolicitTransaction(string transactionId)
        {
            using (INodeProcessorMutex mutex = GetMutex(transactionId)) {
                if (!mutex.IsAcquired)
                {
                    LOG.Debug("Exiting ProcessSolicitTransaction(), could not acquire mutex");
                    return;                     // Another thread is already working on this transaction, get out of here
                }
                // Make sure the transaction has not been processed yet
                string transactionModifiedBy;
                if (!TransactionManager.IsUnprocessed(transactionId, out transactionModifiedBy))
                {
                    LOG.Debug("Exiting ProcessSolicitTransaction(), transaction {0} has already been processed",
                              transactionId);
                    return;
                }
                Activity activity = new Activity(NodeMethod.Solicit, null, null, ActivityType.Info, transactionId,
                                                 NetworkUtils.GetLocalIp(),
                                                 "Start processing solicit transaction: \"{0}\"", transactionId);
                activity.ModifiedById = transactionModifiedBy;
                try
                {
                    TransactionManager.SetTransactionStatus(transactionId, CommonTransactionStatusCode.Pending,
                                                            "Processing solicit transaction", false);

                    // Get the request processing service
                    string      requestId, flowName, operation;
                    DataService solicitService =
                        TransactionManager.GetSolicitServiceForTransaction(transactionId, out flowName, out operation, out requestId);
                    if ((solicitService == null) || !solicitService.IsActive)
                    {
                        throw new ArgumentException(string.Format("A valid solicit service was not found for the transaction \"{0}\"",
                                                                  transactionId));
                    }
                    TimeSpan          processLength;
                    ISolicitProcessor plugin;
                    using (IPluginDisposer disposer = PluginLoader.LoadSolicitProcessor(solicitService, out plugin))
                    {
                        TransactionManager.SetTransactionStatus(transactionId, CommonTransactionStatusCode.Processing,
                                                                string.Format("Processing request with transaction id \"{0}\"",
                                                                              transactionId), true);
                        DateTime startTime = DateTime.Now;
                        activity.Append("Set transaction status to Processing");
                        activity.AppendFormat("Processing Solicit transaction for flow \"{0}\" and operation \"{1}\" using plugin \"{2}\"",
                                              flowName, operation, plugin.GetType().FullName);

                        try
                        {
                            plugin.ProcessSolicit(requestId);
                        }
                        finally
                        {
                            activity.Append(plugin.GetAuditLogEvents());
                        }
                        processLength = DateTime.Now - startTime;
                    }

                    activity.AppendFormat("Process time: {0}", processLength.ToString());

                    TransactionStatus transactionStatus =
                        TransactionManager.SetTransactionStatus(transactionId, CommonTransactionStatusCode.Completed,
                                                                string.Format("Completed solicit request with transaction id \"{0}\"",
                                                                              transactionId), true);
                    activity.AppendFormat("Transaction status set to \"{0}\"", transactionStatus.Status.ToString());

                    activity.AppendFormat(TransactionManager.DoTransactionNotifications(transactionId));
                }
                catch (Exception e) {
                    TransactionStatus transactionStatus =
                        TransactionManager.SetTransactionStatusIfNotStatus(transactionId, CommonTransactionStatusCode.Failed,
                                                                           e.Message, CommonTransactionStatusCode.Received, true);

                    activity.AppendFormat("Transaction status set to \"{0}\"", transactionStatus.Status.ToString());
                    activity.Append(ExceptionUtils.ToShortString(e));
                    activity.Type = ActivityType.Error;
                    activity.AppendFormat(TransactionManager.DoTransactionNotifications(transactionId));
                    LOG.Error("ProcessSolicitTransaction() threw an exception.", e);
                }
                finally {
                    ActivityManager.Log(activity);
                }
            }
        }
        protected void ProcessNotifyTransaction(string transactionId)
        {
            using (INodeProcessorMutex mutex = GetMutex(transactionId))
            {
                if (!mutex.IsAcquired)
                {
                    LOG.Debug("Exiting ProcessNotifyTransaction(), could not acquire mutex");
                    return;                     // Another thread is already working on this transaction, get out of here
                }
                // Make sure the transaction has not been processed yet
                string transactionModifiedBy;
                if (!TransactionManager.IsUnprocessed(transactionId, out transactionModifiedBy))
                {
                    if (!TransactionManager.IsUnprocessed(transactionId))
                    {
                        LOG.Debug("Exiting ProcessNotifyTransaction(), transaction {0} has already been processed",
                                  transactionId);
                        return;
                    }
                }
                Activity activity =
                    new Activity(NodeMethod.Notify, null, null, ActivityType.Info, transactionId, NetworkUtils.GetLocalIp(),
                                 "Start processing notify transaction: \"{0}\"", transactionId);
                activity.ModifiedById = transactionModifiedBy;
                try
                {
                    TransactionManager.SetTransactionStatus(transactionId, CommonTransactionStatusCode.Pending,
                                                            "Processing notify transaction", false);
                    // Get the document processing service
                    // TODO: No documentService means failure?
                    string      flowName, operation;
                    DataService notifyService =
                        TransactionManager.GetNotifyDocumentServiceForTransaction(transactionId, out flowName, out operation);
                    if (notifyService == null)
                    {
                        // Let notify pass through, even without a valid service, per Mark
                    }
                    else if (!notifyService.IsActive)
                    {
                        throw new ArgumentException(string.Format("The Notify service is not active for the flow \"{0}\"",
                                                                  flowName));
                    }

                    if (notifyService == null)
                    {
                        activity.Append("No service found for Notify transaction");
                        TransactionStatus transactionStatus =
                            TransactionManager.SetTransactionStatusIfNotStatus(transactionId, CommonTransactionStatusCode.ReceivedUnprocessed,
                                                                               "Received unprocessed notify transaction",
                                                                               CommonTransactionStatusCode.Received, true);
                        activity.AppendFormat("Transaction status set to \"{0}\"", transactionStatus.Status.ToString());
                    }
                    else
                    {
                        INotifyProcessor plugin;
                        using (IPluginDisposer disposer = PluginLoader.LoadNotifyProcessor(notifyService, out plugin))
                        {
                            TransactionManager.SetTransactionStatus(transactionId, CommonTransactionStatusCode.Processing,
                                                                    "Processing notify transaction", true);
                            activity.Append("Set transaction status to Processing");
                            DateTime startTime = DateTime.Now;
                            activity.AppendFormat("Processing Notify transaction for flow \"{0}\" and operation \"{1}\" using plugin \"{2}\"",
                                                  flowName, operation, plugin.GetType().FullName);

                            try
                            {
                                plugin.ProcessNotify(transactionId);
                            }
                            finally
                            {
                                activity.Append(plugin.GetAuditLogEvents());
                            }

                            TimeSpan processLength = DateTime.Now - startTime;
                            activity.AppendFormat("Process time: {0}", processLength.ToString());
                        }
                        activity.Append("Finished processing notify transaction");
                        TransactionStatus transactionStatus =
                            TransactionManager.SetTransactionStatusIfNotStatus(transactionId, CommonTransactionStatusCode.Processed,
                                                                               "Finished processing notify transaction",
                                                                               CommonTransactionStatusCode.Received, true);
                        activity.AppendFormat("Transaction status set to \"{0}\"", transactionStatus.Status.ToString());
                    }
                }
                catch (Exception e)
                {
                    TransactionStatus transactionStatus =
                        TransactionManager.SetTransactionStatusIfNotStatus(transactionId, CommonTransactionStatusCode.Failed,
                                                                           e.Message, CommonTransactionStatusCode.Received, true);

                    activity.AppendFormat("Transaction status set to \"{0}\"", transactionStatus.Status.ToString());
                    activity.Append(ExceptionUtils.ToShortString(e));
                    activity.Type = ActivityType.Error;
                    LOG.Error("ProcessNotifyTransaction() threw an exception.", e);
                }
                finally
                {
                    ActivityManager.Log(activity);
                }
            }
        }