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); }
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; } }
/// <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; } }
//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); } } }
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); }
/// <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; } }
//通过注入的规则(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); } }