Beispiel #1
0
        private List <ExecutionRequestParameters> FillExecutionRequestParameters(Guid processId, ProcessInstance processInstance, IEnumerable <TransitionDefinition> transitions)
        {
            var newExecutionParameters = new List <ExecutionRequestParameters>();

            foreach (var transition in transitions)
            {
                var parametersLocal = ExecutionRequestParameters.Create(processInstance.ProcessId,
                                                                        processInstance.ProcessParameters,
                                                                        transition, true);

                if (transition.Trigger.Type != TriggerType.Auto || transition.Restrictions.Count() > 0)
                {
                    var actors = GetActors(processId, transition);

                    parametersLocal.AddParameterInContainer(
                        ParameterDefinition.Create(DefaultDefinitions.ParameterIdentityIds,
                                                   actors));
                }

                if (transition.Trigger.Type == TriggerType.Command)
                {
                    parametersLocal.AddParameterInContainer(ParameterDefinition.Create(DefaultDefinitions.ParameterCurrentCommand, (object)transition.Trigger.Command.Name));
                }


                newExecutionParameters.Add(parametersLocal);
            }
            return(newExecutionParameters);
        }
Beispiel #2
0
        private void SetStateWithExecution(Guid identityId,
                                           Guid impersonatedIdentityId,
                                           IDictionary <string, object> parameters,
                                           ActivityDefinition activityToSet,
                                           ProcessInstance processInstance)
        {
            SetProcessNewStatus(processInstance, ProcessStatus.Running);

            IEnumerable <TransitionDefinition> transitions;


            try
            {
                PersistenceProvider.FillSystemProcessParameters(processInstance);
                PersistenceProvider.FillPersistedProcessParameters(processInstance);

                var parametersLocal = new List <ParameterDefinitionWithValue>();
                foreach (var commandParameter in parameters)
                {
                    var parameterDefinition = processInstance.ProcessScheme.GetParameterDefinition(commandParameter.Key);

                    if (parameterDefinition != null)
                    {
                        parametersLocal.Add(ParameterDefinition.Create(parameterDefinition, commandParameter.Value));
                    }
                }
                parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterCurrentCommand,
                                                               (object)DefaultDefinitions.CommandSetState.Name));
                parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterIdentityId, identityId));
                parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterImpersonatedIdentityId,
                                                               impersonatedIdentityId));
                parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterSchemeId, processInstance.SchemeId));

                parametersLocal.ForEach(processInstance.AddParameter);
            }
            catch (Exception)
            {
                SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                throw;
            }

            //TODO Убрать после обработки команд
            try
            {
                Bus.QueueExecution(ExecutionRequestParameters.Create(processInstance.ProcessId,
                                                                     processInstance.ProcessParameters,
                                                                     activityToSet,
                                                                     ConditionDefinition.Always));
            }
            catch (Exception ex)
            {
                Logger.Log.Error(string.Format("Workflow Id={0}", processInstance.ProcessId), ex);
                SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                throw;
            }
        }
Beispiel #3
0
        /// <summary>
        /// 执行流程起始节点出的初始化活动
        /// </summary>
        /// <param name="processInstance"></param>
        private void ExecuteRootActivity(ProcessInstance processInstance)
        {
            PersistenceProvider.FillProcessParameters(processInstance);
            processInstance.AddParameter(ParameterDefinition.Create(DefaultDefinitions.ParameterSchemeId, processInstance.SchemeId));

            //TODO Убрать после обработки команд
            try
            {
                Bus.QueueExecution(ExecutionRequestParameters.Create(processInstance.ProcessId,
                                                                     processInstance.ProcessParameters,
                                                                     processInstance.ProcessScheme.InitialActivity,
                                                                     ConditionDefinition.Always));
            }
            catch (Exception ex)
            {
                Logger.Log.Error(string.Format("Error Execute Root Workflow Id={0}", processInstance.ProcessId), ex);
                SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                throw;
            }
        }
Beispiel #4
0
        //private object _timerSaveLock = new object();

        //void _runtimeTimer_NeedSave(object sender, EventArgs e)
        //{
        //    lock (_timerSaveLock)
        //    {
        //        _runtimePersistence.SaveTimer(Id, _runtimeTimer);
        //    }
        //}

        private void TimerComplete(object sender, RuntimeTimerEventArgs e)
        {
            TransitionDefinition currentTimerTransition;
            ProcessInstance      processInstance;

            try
            {
                processInstance = Builder.GetProcessInstance(e.ProcessId);
                PersistenceProvider.FillProcessParameters(processInstance);

                currentTimerTransition =
                    processInstance.ProcessScheme.GetTimerTransitionForActivity(processInstance.CurrentActivity).
                    FirstOrDefault(p => p.Trigger.Timer.Name == e.TimerName);
            }
            catch (Exception ex)
            {
                Logger.Log.Error("Error Timer Complete Workflow UNKNOWN", ex);
                throw;
            }

            if (currentTimerTransition != null)
            {
                try
                {
                    SetProcessNewStatus(processInstance, ProcessStatus.Running);
                    var parametersLocal = new List <ParameterDefinitionWithValue>();
                    parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterIdentityId, Guid.Empty));
                    parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterImpersonatedIdentityId, Guid.Empty));
                    parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterSchemeId, processInstance.SchemeId));
                    var newExecutionParameters = new List <ExecutionRequestParameters>();
                    newExecutionParameters.Add(ExecutionRequestParameters.Create(processInstance.ProcessId, processInstance.ProcessParameters, currentTimerTransition));
                    Bus.QueueExecution(newExecutionParameters);
                }
                catch (Exception ex)
                {
                    Logger.Log.Error(string.Format("Error Timer Complete Workflow Id={0}", processInstance.ProcessId), ex);
                    SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                }
            }
        }
Beispiel #5
0
        public void PreExecute(Guid processId)
        {
            var processInstance = Builder.GetProcessInstance(processId);

            //从这里分析什么是SystemProcessParameters,系统参数
            PersistenceProvider.FillSystemProcessParameters(processInstance);

            var activity        = processInstance.ProcessScheme.FindActivity(processInstance.CurrentActivityName);
            var currentActivity = processInstance.ProcessScheme.InitialActivity;

            if (activity.State != currentActivity.State)
            {
                return; //TODO Workflow Temporary
            }
            var executor = new ActivityExecutor(true);


            processInstance.AddParameter(ParameterDefinition.Create(DefaultDefinitions.ParameterProcessId, processId));
            processInstance.AddParameter(ParameterDefinition.Create(DefaultDefinitions.ParameterSchemeId, processInstance.SchemeId));

            if (currentActivity.HavePreExecutionImplementation)
            {
                var response = executor.Execute(new List <ExecutionRequestParameters>
                {
                    ExecutionRequestParameters.Create(processInstance.ProcessId,
                                                      processInstance.ProcessParameters,
                                                      processInstance.ProcessScheme.InitialActivity,
                                                      ConditionDefinition.Always,
                                                      true)
                });

                if (PreExecuteProcessResponse(processInstance, response))
                {
                    return;
                }
            }

            do
            {
                if (!string.IsNullOrEmpty(currentActivity.State))
                {
                    processInstance.AddParameter(ParameterDefinition.Create(DefaultDefinitions.ParameterCurrentState, (object)currentActivity.State));
                }

                var transitions =
                    processInstance.ProcessScheme.GetPossibleTransitionsForActivity(currentActivity).Where(t => t.Classifier == TransitionClassifier.Direct);

                currentActivity = null;

                var autotransitions = transitions.Where(t => t.Trigger.Type == TriggerType.Auto);

                var newExecutionParameters = FillExecutionRequestParameters(processId, processInstance, autotransitions);

                if (newExecutionParameters.Count > 0)
                {
                    var response = executor.Execute(newExecutionParameters);

                    if (!PreExecuteProcessResponse(processInstance, response))
                    {
                        currentActivity =
                            processInstance.ProcessScheme.FindTransition(response.ExecutedTransitionName).To;
                    }
                }

                if (currentActivity == null)
                {
                    var commandTransitions = transitions.Where(t => t.Trigger.Type == TriggerType.Command);

                    if (commandTransitions.Count(t => t.Condition.Type == ConditionType.Always && !t.Condition.ResultOnPreExecution.HasValue) < 2) //Это не является ошибкой валидациии при разных командах
                    {
                        newExecutionParameters = FillExecutionRequestParameters(processId, processInstance,
                                                                                commandTransitions);

                        if (newExecutionParameters.Count > 0)
                        {
                            var response = executor.Execute(newExecutionParameters);

                            if (!PreExecuteProcessResponse(processInstance, response))
                            {
                                currentActivity =
                                    processInstance.ProcessScheme.FindTransition(response.ExecutedTransitionName).To;
                            }
                        }
                    }
                }
            } while (currentActivity != null && !currentActivity.IsFinal);
        }
Beispiel #6
0
        /// <summary>
        /// 执行审批流程中的命令WorkflowCommand
        /// </summary>
        /// <param name="processId"></param>
        /// <param name="identityId">执行该命令的用户ID</param>
        /// <param name="impersonatedIdentityId">针对谁执行的,对方的用户ID,因为审批流程中的活动总是在两个或者多个人之间流转的
        /// 如果一个人执行活动,并同时向多个人分发,怎么办,例如 会签的情况
        /// </param>
        /// <param name="command"></param>
        public void ExecuteCommand(Guid processId, Guid identityId, Guid impersonatedIdentityId, WorkflowCommand command)
        {
            //TODO Workflow Temporary
            //if (!command.Validate())
            //    throw new CommandNotValidException();

            var processInstance = Builder.GetProcessInstance(processId);

            SetProcessNewStatus(processInstance, ProcessStatus.Running);

            IEnumerable <TransitionDefinition> transitions;


            try
            {
                //根据当前的流程实例填写系统定义的流程参数及参数值,系统要统一维护该参数值,
                //以保证状态和流程的运转
                PersistenceProvider.FillSystemProcessParameters(processInstance);

                if (processInstance.CurrentActivityName != command.ValidForActivityName)
                {
                    throw new CommandNotValidForStateException();
                }

                transitions =
                    processInstance.ProcessScheme.GetCommandTransitionForActivity(
                        processInstance.ProcessScheme.FindActivity(processInstance.CurrentActivityName),
                        command.CommandName);

                if (!transitions.Any())
                {
                    throw new InvalidOperationException();
                }
            }
            catch (Exception ex)
            {
                SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                throw;
            }

            //命令需要的参数及参数值
            var parametersLocal = new List <ParameterDefinitionWithValue>();

            try
            {
                foreach (var commandParameter in command.Parameters)
                {
                    //从processInstance获取命令需要的参数值
                    var parameterDefinition = processInstance.ProcessScheme.GetParameterDefinition(commandParameter.Name);

                    if (parameterDefinition != null)
                    {
                        parametersLocal.Add(ParameterDefinition.Create(parameterDefinition, commandParameter.Value));
                    }
                }

                parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterCurrentCommand,
                                                               (object)command.CommandName));
                parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterIdentityId, identityId));
                parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterImpersonatedIdentityId,
                                                               impersonatedIdentityId));
                parametersLocal.Add(ParameterDefinition.Create(DefaultDefinitions.ParameterSchemeId,
                                                               processInstance.SchemeId));

                parametersLocal.ForEach(processInstance.AddParameter);
                //保存运行前的状态
                PersistenceProvider.SavePersistenceParameters(processInstance);
                PersistenceProvider.FillPersistedProcessParameters(processInstance);
            }
            catch (Exception)
            {
                SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                throw;
            }

            var newExecutionParameters = new List <ExecutionRequestParameters>();

            newExecutionParameters.AddRange(
                transitions.Select(
                    at =>
                    ExecutionRequestParameters.Create(processInstance.ProcessId, processInstance.ProcessParameters, at)));

            try
            {
                Bus.QueueExecution(newExecutionParameters);
            }
            catch (Exception ex)
            {
                Logger.Log.Error(string.Format("Error Execute Command Workflow Id={0}", processInstance.ProcessId), ex);
                SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                throw;
            }
        }
Beispiel #7
0
        //通过注入的规则(IWorkflowBus),方法执行完成后调用本方法。
        internal void BusExecutionComplete(object sender, ExecutionResponseEventArgs e)
        {
            var executionResponseParameters = e.Parameters;
            var processInstance             = Builder.GetProcessInstance(executionResponseParameters.ProcessId);

            PersistenceProvider.FillSystemProcessParameters(processInstance);
            //TODO Сделать метод филл CurrentActivity
            if (executionResponseParameters.IsEmplty)
            {
                SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                //var timerTransitions =
                //    processInstance.ProcessScheme.GetTimerTransitionForActivity(processInstance.CurrentActivity).ToList();

                //timerTransitions.ForEach(p=>_runtimeTimer.UpdateTimer(processInstance.ProcessId,p.Trigger.Timer));

                return;
            }
            if (executionResponseParameters.IsError)
            {
                var executionErrorParameters = executionResponseParameters as ExecutionResponseParametersError;

                Logger.Log.Error(string.Format("Error Execution Complete Workflow Id={0}", processInstance.ProcessId), executionErrorParameters.Exception);

                if (string.IsNullOrEmpty(executionErrorParameters.ExecutedTransitionName))
                {
                    SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                    throw executionErrorParameters.Exception;
                }

                var transition = processInstance.ProcessScheme.FindTransition(executionErrorParameters.ExecutedTransitionName);

                var onErrorDefinition = transition.OnErrors.Where(
                    oe => executionErrorParameters.Exception.GetType().Equals(oe.ExceptionType)).
                                        OrderBy(oe => oe.Priority).FirstOrDefault() ??
                                        transition.OnErrors.Where(
                    oe => oe.ExceptionType.IsAssignableFrom(executionErrorParameters.Exception.GetType())).
                                        OrderBy(oe => oe.Priority).FirstOrDefault();
                if (onErrorDefinition == null)
                {
                    SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                    throw executionErrorParameters.Exception;
                }

                if (onErrorDefinition.ActionType == OnErrorActionType.SetActivity)
                {
                    var from = processInstance.CurrentActivity;
                    var to   = processInstance.ProcessScheme.FindActivity((onErrorDefinition as SetActivityOnErrorDefinition).NameRef);
                    PersistenceProvider.UpdatePersistenceState(processInstance, TransitionDefinition.Create(from, to));
                    SetProcessNewStatus(processInstance, ProcessStatus.Idled);
                }

                throw executionErrorParameters.Exception;

                //return;
            }


            try
            {
                ActivityDefinition newCurrentActivity;
                if (string.IsNullOrEmpty(executionResponseParameters.ExecutedTransitionName))
                {
                    if (executionResponseParameters.ExecutedActivityName == processInstance.ProcessScheme.InitialActivity.Name)
                    {
                        newCurrentActivity = processInstance.ProcessScheme.InitialActivity;
                    }
                    else
                    {
                        var from = processInstance.CurrentActivity;
                        var to   = processInstance.ProcessScheme.FindActivity(executionResponseParameters.ExecutedActivityName);
                        newCurrentActivity = to;
                        PersistenceProvider.UpdatePersistenceState(processInstance, TransitionDefinition.Create(from, to));
                    }
                }
                else
                {
                    var executedTransition =
                        processInstance.ProcessScheme.FindTransition(executionResponseParameters.ExecutedTransitionName);
                    newCurrentActivity = executedTransition.To;
                    PersistenceProvider.UpdatePersistenceState(processInstance, executedTransition);
                }

                FillParameters(processInstance, (executionResponseParameters as ExecutionResponseParametersComplete));
                PersistenceProvider.SavePersistenceParameters(processInstance);

                var autoTransitions =
                    processInstance.ProcessScheme.GetAutoTransitionForActivity(newCurrentActivity).ToList();
                if (autoTransitions.Count() < 1)
                {
                    SetProcessNewStatus(processInstance,
                                        newCurrentActivity.IsFinal ? ProcessStatus.Finalized : ProcessStatus.Idled);

                    //var timerTransitions =
                    //processInstance.ProcessScheme.GetTimerTransitionForActivity(newCurrentActivity).ToList();

                    //timerTransitions.ForEach(p => _runtimeTimer.SetTimer(processInstance.ProcessId, p.Trigger.Timer));

                    return;
                }

                PersistenceProvider.FillProcessParameters(processInstance);

                var newExecutionParameters = new List <ExecutionRequestParameters>();
                newExecutionParameters.AddRange(
                    autoTransitions.Select(
                        at =>
                        ExecutionRequestParameters.Create(processInstance.ProcessId, processInstance.ProcessParameters,
                                                          at)));
                Bus.QueueExecution(newExecutionParameters);
            }
            catch (ActivityNotFoundException)
            {
                SetProcessNewStatus(processInstance, ProcessStatus.Terminated);
            }
            //TODO Обработка ошибок
            catch (Exception ex)
            {
                Logger.Log.Error(string.Format("Error Execution Complete Workflow Id={0}", processInstance.ProcessId), ex);
                SetProcessNewStatus(processInstance, ProcessStatus.Idled);
            }
        }