public void Throwing_an_exception_from_an_event_handler() { _workflow = StateMachineWorkflow.New<SubjectWorkflow, Subject>(x => { x.AccessCurrentState(y => y.CurrentState); x.Initially() .When(e => e.Create) .Then(i => i.Create) .TransitionTo(s => s.Created) .InCaseOf() .Exception<SubjectException>() .Then(i => { _instanceHandlerCalled = true; }) .Then(() => _handlerCalled = true) .TransitionTo(s => s.Failed); }); _subject = new Subject(); _instance = _workflow.GetInstance(_subject); _instance.RaiseEvent(x => x.Create); }
/// <summary> /// 创建工作流实例 /// </summary> /// <param name="p"></param> /// <returns></returns> public static WorkflowInstance CreateInstance(Process p, IWorkflowParser parser) { var workflow = parser.Parse(GetCacheKey(p.ProcessType) , p.ProcessType.Workflow.Serialized , p.ProcessType.ActivitySettings); var instance = new WorkflowInstance(workflow, p.ID, p.GetInputs()); //HACK:【重要】强制让Core调度使用同步上下文进行调度而不使用Threaded模式,使得事务与resumption嵌套,便于事务控制和错误处理 20120507 instance.SynchronizationContext = new WorkflowInstance.DefaultSynchronizationContext(); //标记为可持久化 instance.IsPersistable = true; //数据字段扩展 instance.Extensions.Add<DataFieldExtension>(WorkflowBuilder.CreateDataFieldExtension(p)); //自定义节点扩展 instance.Extensions.Add<CustomExtension>(new CustomExtension(p.ProcessType.ActivitySettings .Where(o => o is CustomSetting) .Select(o => o as CustomSetting) .ToList())); //人工节点扩展 instance.Extensions.Add<HumanExtension>(new HumanExtension()); //服务端节点扩展 instance.Extensions.Add<ServerExtension>(new ServerExtension()); //并行节点扩展 instance.Extensions.Add<ParallelExtension>(new ParallelExtension()); //子流程节点扩展 instance.Extensions.Add<SubProcessExtension>(new SubProcessExtension()); return instance; }
internal DebugManager(Activity root, string moduleNamePrefix, string typeNamePrefix, string auxiliaryThreadName, bool breakOnStartup, WorkflowInstance host, bool debugStartedAtRoot, bool resetDynamicModule) { if (resetDynamicModule) { dynamicModuleManager = null; } if (dynamicModuleManager == null) { dynamicModuleManager = new StateManager.DynamicModuleManager(moduleNamePrefix); } this.stateManager = new StateManager( new StateManager.Properties { ModuleNamePrefix = moduleNamePrefix, TypeNamePrefix = typeNamePrefix, AuxiliaryThreadName = auxiliaryThreadName, BreakOnStartup = breakOnStartup }, debugStartedAtRoot, dynamicModuleManager); this.states = new Dictionary<object, State>(); this.runningThreads = new Dictionary<int, Stack<Activity>>(); this.instrumentationTracker = new InstrumentationTracker(root); this.host = host; }
/// <summary> /// 实例化审批页面选择对象 /// </summary> /// <param name="instance"></param> public ApproveSelector(WorkflowInstance instance) : this() { var currentActi = instance.GetCurrentActi(); foreach (var choice in currentActi.Transitions.Keys) { var nextActi = currentActi.Transitions[choice]; if (nextActi == null) { throw new NextActivityNotFoundException(instance.InstanceNo, instance.CurrentActivity, choice); } var actor = nextActi.Actor; this.m_NextChoice.Add(choice); this.m_Activities.Add(choice, nextActi.Name); IEnumerable<IUser> users = new List<IUser>(); if (actor != null) { if (choice.Contains("退回")) { actor.RefActivityName = nextActi.Name; users = actor.Resolve(instance); } else { users = actor.Resolve(instance); } } foreach (var user in users) { var organization = SecurityContext.Provider.GetOrganization(user.DeptId); this[choice].Add(new SelectorUser() { id = user.Id, name = user.Name, deptName = organization.FullName }); } } }
/// <summary>Creates an workflow instance based on this workflow definition. </summary> /// <returns>The <see cref="WorkflowInstance"/>. </returns> /// <exception cref="WorkflowException">A workflow validation exception occurred. </exception> public WorkflowInstance CreateInstance() { ValidateRoutes(); var instance = new WorkflowInstance(this, new List<ActivityData>()); instance.CurrentActivityIds.Add(StartActivityId); return instance; }
public void Creating_a_new_workflow() { _workflow = StateMachineWorkflow.New<TestWorkflow, TestInstance>(x => { x.AccessCurrentState(y => y.CurrentState); }); _instance = _workflow.GetInstance(new TestInstance()); }
public void Human() { Taobao.Activities.Hosting.WorkflowInstance.IsEnableDebug = true; var app = new WorkflowInstance(new HumanWorkflow(), null); app.Extensions.Add<HumanExtension>(new HumanExtension()); app.Extensions.Add<CustomExtension>(new CustomExtension(new List<CustomSetting>() { new ServerSetting(0, "节点1", "", "", null, null, false) })); app.Extensions.Add<DataFieldExtension>(new DataFieldExtension("", 0, null)); app.Run(); Thread.Sleep(1000); }
public DebugManager(Activity root, string moduleNamePrefix, string typeNamePrefix, string auxiliaryThreadName, bool breakOnStartup, WorkflowInstance host, bool debugStartedAtRoot) { StateManager.Properties properties = new StateManager.Properties { ModuleNamePrefix = moduleNamePrefix, TypeNamePrefix = typeNamePrefix, AuxiliaryThreadName = auxiliaryThreadName, BreakOnStartup = breakOnStartup }; this.stateManager = new StateManager(properties, debugStartedAtRoot); this.states = new Dictionary<object, System.Activities.Debugger.State>(); this.runningThreads = new Dictionary<int, Stack<Activity>>(); this.instrumentationTracker = new InstrumentationTracker(root); this.host = host; }
public void An_event_causing_a_state_transition() { _workflow = StateMachineWorkflow.New<TestWorkflow, TestInstance>(x => { x.AccessCurrentState(y => y.CurrentState); x.During(y => y.Initial) .When(y => y.Finish) .TransitionTo(y => y.Completed); }); _instance = _workflow.GetInstance(new TestInstance()); _instance.RaiseEvent(x => x.Finish); }
public void CtorShouldCreateTracker() { // Arrange using (var testdb = new SqlWorkflowInstanceStoreTest()) { var view = new TestWorkflowView(testdb.CreateInstanceStore()); var model = new WorkflowModel(view); // Act var wi = new WorkflowInstance(model); // Assert Assert.IsNotNull(wi.StateTracker); } }
public void HostIsNotNull() { // Arrange using (var testdb = new SqlWorkflowInstanceStoreTest()) { var view = new TestWorkflowView(testdb.CreateInstanceStore()); var model = new WorkflowModel(view); var wi = new WorkflowInstance(model); // Act wi.New(); // Assert Assert.IsNotNull(wi.Host); } }
/// <summary> /// 传阅流程 /// </summary> /// <param name="instance">流程实例.</param> /// <param name="toUsers">传阅用户.</param> public override bool PassAround(WorkflowInstance instance, IList<IUser> toUsers) { var tobeReadWorkItems = new List<K2WorkflowItem>(); var currentWorkItem = instance.CurrentWorkItem; #region 添加下一环节待阅流程 var lastTaskId = this.GetWorkItemLastTaskId(instance.InstanceNo); foreach (var user in toUsers) { var workItem = WorkflowItemFactory.Create<K2WorkflowItem>(); lastTaskId += 1; workItem.TaskId = lastTaskId; workItem.InstanceNo = instance.InstanceNo; workItem.PartId = user.Id; workItem.PartName = user.Name; workItem.PartDeptId = user.DeptId; var dept = SecurityContext.Provider.GetOrganization(user.DeptId); workItem.PartDeptName = (dept == null ? "" : dept.FullName); workItem.ReceTime = DateTime.Now; workItem.TaskStatus = TaskStatus.ToRead; workItem.CurrentActi = currentWorkItem.CurrentActi; // 传阅人 workItem.Mandatary = CurrentUser.Name; workItem.MandataryId = CurrentUser.Id; tobeReadWorkItems.Add(workItem); } #endregion using (var transactionScope = new TransactionScope(TransactionScopeOption.Required)) { // 新增传阅环节 foreach (var workitem in tobeReadWorkItems) { _dao.Insert<K2WorkflowItem>(workitem); } transactionScope.Complete(); } return true; }
public void A_message_event_is_raised() { _workflow = StateMachineWorkflow.New<TestWorkflow, TestInstance>(x => { x.AccessCurrentState(y => y.CurrentState); x.During(y => y.Initial) .When(y => y.Finish) .Then(() => _nonInstanceValue = true) .Then(instance => instance.MessageValue = "Success") .Then((instance, message) => instance.MessageValue = message.Value) .TransitionTo(y => y.Completed); }); _testInstance = new TestInstance(); _instance = _workflow.GetInstance(_testInstance); _instance.RaiseEvent(x => x.Finish, new Result { Value = "Success" }); }
/// <summary> /// 初始化流程表单对象 /// </summary> /// <param name="instance">流程实例</param> /// <returns></returns> public static WorkflowForm Init(WorkflowInstance instance) { var currentUser = SecurityContext.User; var form = new WorkflowForm(); form.Instance = instance; form.AppCode = instance.AppCode; form.AppName = instance.AppName; form.Description = instance.Description; form.VersionStr = instance.Version.ToString(CultureInfo.InvariantCulture); form.InstanceNo = instance.InstanceNo; #region FormStatus switch (instance.Status) { case InstanceStatus.Draft: { form.Status = FormStatus.Draft; break; } case InstanceStatus.Running: { var currentWorkItem = instance.CurrentWorkItem; // 待办条件:当前环节的审批人为当前登录用户 && 当前环节未结束 if ((currentWorkItem.PartId.Equals(currentUser.Id, StringComparison.OrdinalIgnoreCase) || (!string.IsNullOrEmpty(currentWorkItem.MandataryId) && currentWorkItem.MandataryId.Equals(currentUser.Id, StringComparison.OrdinalIgnoreCase)) || DelegateWork.IsDelegate(instance.AppCode, currentWorkItem.PartId, currentUser.Id)) && currentWorkItem.TaskStatus == TaskStatus.Waiting) { form.Status = FormStatus.Todo; } else { form.Status = FormStatus.Done; } break; } case InstanceStatus.Cancel: case InstanceStatus.Deleted: case InstanceStatus.Finished: { form.Status = FormStatus.Done; break; } } #endregion form.Creator = SecurityContext.Provider.Get(instance.CreatorId); form.CreatorDept = SecurityContext.Provider.GetOrganization(form.Creator.DeptId); form.CurrentUser = SecurityContext.User; form.TaskId = instance.CurrentWorkItem == null ? 1 : instance.CurrentWorkItem.TaskId; form.CurrentActi = instance.CurrentWorkItem == null ? instance.CurrentActivity : instance.CurrentWorkItem.CurrentActi; form.Controller = FlowFactory.GetWorklfowControllerName(form.AppCode); form.Instance = instance; // 根据WorkItem中的环节信息计算出历史环节(Distinct) // 获取并添加到List中,用于渲染 var workItems = instance.GetWorkItems(); if (workItems != null && workItems.Any()) { var lastTaskId = workItems.First(p => p.CurrentActi.Equals(form.CurrentActi, StringComparison.OrdinalIgnoreCase)).TaskId; var activities = workItems.Where(p => p.TaskId <= lastTaskId).OrderBy(p => p.TaskId); foreach (var activity in activities) { if (form.HistoryActivities.Contains(activity.CurrentActi)) { continue; } form.HistoryActivities.Add(activity.CurrentActi); } } if (form.HistoryActivities.Count == 0) { form.HistoryActivities.Add(form.CurrentActi); } return form; }
public void IdIsNotEmptyGuid() { // Arrange using (var testdb = new SqlWorkflowInstanceStoreTest()) { var view = new TestWorkflowView(testdb.CreateInstanceStore()); var model = new WorkflowModel(view); var wi = new WorkflowInstance(model); // Act var id = wi.Id; // Assert Assert.AreEqual(Guid.Empty, id); } }
private async Task ExecuteStep(WorkflowInstance workflow, WorkflowStep step, ExecutionPointer pointer, WorkflowExecutorResult wfResult, WorkflowDefinition def, CancellationToken cancellationToken = default) { IStepExecutionContext context = new StepExecutionContext { Workflow = workflow, Step = step, PersistenceData = pointer.PersistenceData, ExecutionPointer = pointer, Item = pointer.ContextItem, CancellationToken = cancellationToken }; using (var scope = _scopeProvider.CreateScope(context)) { _logger.LogDebug("Starting step {0} on workflow {1}", step.Name, workflow.Id); IStepBody body = step.ConstructBody(scope.ServiceProvider); var stepExecutor = scope.ServiceProvider.GetRequiredService <IStepExecutor>(); if (body == null) { _logger.LogError("Unable to construct step body {0}", step.BodyType.ToString()); pointer.SleepUntil = _datetimeProvider.UtcNow.Add(_options.ErrorRetryInterval); wfResult.Errors.Add(new ExecutionError { WorkflowId = workflow.Id, ExecutionPointerId = pointer.Id, ErrorTime = _datetimeProvider.UtcNow, Message = $"Unable to construct step body {step.BodyType}" }); return; } foreach (var input in step.Inputs) { input.AssignInput(workflow.Data, body, context); } switch (step.BeforeExecute(wfResult, context, pointer, body)) { case ExecutionPipelineDirective.Defer: return; case ExecutionPipelineDirective.EndWorkflow: workflow.Status = WorkflowStatus.Complete; workflow.CompleteTime = _datetimeProvider.UtcNow; return; } var result = await stepExecutor.ExecuteStep(context, body); if (result.Proceed) { foreach (var output in step.Outputs) { output.AssignOutput(workflow.Data, body, context); } } _executionResultProcessor.ProcessExecutionResult(workflow, def, pointer, step, result, wfResult); step.AfterExecute(wfResult, context, result, pointer); } }
public WorkflowInstancePipeBind(WorkflowInstance instance) { _instance = instance; }
internal static WorkflowInstance ToWorkflowInstance(this PersistedWorkflow instance) { WorkflowInstance result = new WorkflowInstance(); result.Data = JsonConvert.DeserializeObject(instance.Data, SerializerSettings); result.Description = instance.Description; result.Reference = instance.Reference; result.Id = instance.InstanceId.ToString(); result.NextExecution = instance.NextExecution; result.Version = instance.Version; result.WorkflowDefinitionId = instance.WorkflowDefinitionId; result.Status = instance.Status; result.CreateTime = DateTime.SpecifyKind(instance.CreateTime, DateTimeKind.Utc); if (instance.CompleteTime.HasValue) { result.CompleteTime = DateTime.SpecifyKind(instance.CompleteTime.Value, DateTimeKind.Utc); } foreach (var ep in instance.ExecutionPointers) { var pointer = new ExecutionPointer(); result.ExecutionPointers.Add(pointer); pointer.Id = ep.Id; pointer.StepId = ep.StepId; pointer.Active = ep.Active; if (ep.SleepUntil.HasValue) { pointer.SleepUntil = DateTime.SpecifyKind(ep.SleepUntil.Value, DateTimeKind.Utc); } pointer.PersistenceData = JsonConvert.DeserializeObject(ep.PersistenceData ?? string.Empty, SerializerSettings); if (ep.StartTime.HasValue) { pointer.StartTime = DateTime.SpecifyKind(ep.StartTime.Value, DateTimeKind.Utc); } if (ep.EndTime.HasValue) { pointer.EndTime = DateTime.SpecifyKind(ep.EndTime.Value, DateTimeKind.Utc); } pointer.StepName = ep.StepName; pointer.RetryCount = ep.RetryCount; pointer.PredecessorId = ep.PredecessorId; pointer.ContextItem = JsonConvert.DeserializeObject(ep.ContextItem ?? string.Empty, SerializerSettings); if (!string.IsNullOrEmpty(ep.Children)) { pointer.Children = ep.Children.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList(); } pointer.EventName = ep.EventName; pointer.EventKey = ep.EventKey; pointer.EventPublished = ep.EventPublished; pointer.EventData = JsonConvert.DeserializeObject(ep.EventData ?? string.Empty, SerializerSettings); pointer.Outcome = JsonConvert.DeserializeObject(ep.Outcome ?? string.Empty, SerializerSettings); pointer.Status = ep.Status; if (!string.IsNullOrEmpty(ep.Scope)) { pointer.Scope = new Stack <string>(ep.Scope.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)); } foreach (var attr in ep.ExtensionAttributes) { pointer.ExtensionAttributes[attr.AttributeKey] = JsonConvert.DeserializeObject(attr.AttributeValue, SerializerSettings); } } return(result); }
public async Task <WorkflowExecutorResult> Execute(WorkflowInstance workflow, CancellationToken cancellationToken = default) { var wfResult = new WorkflowExecutorResult(); var exePointers = new List <ExecutionPointer>(workflow.ExecutionPointers.Where(x => x.Active && (!x.SleepUntil.HasValue || x.SleepUntil < _datetimeProvider.UtcNow))); var def = _registry.GetDefinition(workflow.WorkflowDefinitionId, workflow.Version); if (def == null) { _logger.LogError("Workflow {0} version {1} is not registered", workflow.WorkflowDefinitionId, workflow.Version); return(wfResult); } _cancellationProcessor.ProcessCancellations(workflow, def, wfResult); foreach (var pointer in exePointers) { if (!pointer.Active) { continue; } var step = def.Steps.FindById(pointer.StepId); if (step == null) { _logger.LogError("Unable to find step {0} in workflow definition", pointer.StepId); pointer.SleepUntil = _datetimeProvider.UtcNow.Add(_options.ErrorRetryInterval); wfResult.Errors.Add(new ExecutionError { WorkflowId = workflow.Id, ExecutionPointerId = pointer.Id, ErrorTime = _datetimeProvider.UtcNow, Message = $"Unable to find step {pointer.StepId} in workflow definition" }); continue; } WorkflowActivity.Enrich(step); try { if (!InitializeStep(workflow, step, wfResult, def, pointer)) { continue; } await ExecuteStep(workflow, step, pointer, wfResult, def, cancellationToken); } catch (Exception ex) { _logger.LogError(ex, "Workflow {0} raised error on step {1} Message: {2}", workflow.Id, pointer.StepId, ex.Message); wfResult.Errors.Add(new ExecutionError { WorkflowId = workflow.Id, ExecutionPointerId = pointer.Id, ErrorTime = _datetimeProvider.UtcNow, Message = ex.Message }); _executionResultProcessor.HandleStepException(workflow, def, pointer, step, ex); Host.ReportStepError(workflow, step, ex); } _cancellationProcessor.ProcessCancellations(workflow, def, wfResult); } ProcessAfterExecutionIteration(workflow, def, wfResult); await DetermineNextExecutionTime(workflow, def); using (var scope = _serviceProvider.CreateScope()) { var middlewareRunner = scope.ServiceProvider.GetRequiredService <IWorkflowMiddlewareRunner>(); await middlewareRunner.RunExecuteMiddleware(workflow, def); } return(wfResult); }
/// <summary> /// يك فرآيند جديد را آغاز ميكند /// </summary> /// <param name="InstanceID">شناسه فرآيند جديد</param> /// <param name="WorkflowCode">كدفرآيند</param> /// <param name="EntityID">شناسه موجوديت</param> /// <param name="ExtraInfo">اطلاعات اضافه</param> /// <param name="UserName">نام كاربري ايجاد كننده</param> /// <param name="ds">ديتاست</param> public void CreateWorkflowInstance(WorkflowInstance wfInstance, string userName, string firstPerformer, string extraInfo, int priorityNo, bool isAuthoforward = false) { try { //if (wfs.IsWorkflowCreatedBefore(this.WorkflowID, wfInstance.EntityID)) // throw new WFUserException("براي اين موجوديت قبلا ورك فلو ثبت شده است."); Workflow wf = wfs.GetWorkflowByID(this.WorkflowID); wfInstance.InsertUser = userName; wfInstance.InsertDate = DateTime.Now; wfInstance.WorkflowID = this.WorkflowID; wfInstance.WorkflowInstanceStatusID = (int)WorkflowInstanceStatusEnum.Waiting; wfInstance.ExtraInfo = extraInfo; if (string.IsNullOrEmpty(wfInstance.WorkflowInstanceTitle)) { wfInstance.WorkflowInstanceTitle = wf.WorkflowTitle; } if (string.IsNullOrEmpty(wfInstance.EntityName)) { wfInstance.EntityName = wf.EntityName; } if (string.IsNullOrEmpty(wfInstance.EntityTitle)) { wfInstance.EntityTitle = wf.EntityTitle; } if (string.IsNullOrEmpty(wfInstance.EntityUrl)) { wfInstance.EntityUrl = wf.EntityUrl; } // inserting to database var ObjectContext = wfs.ObjectContext; var task = (from o in ObjectContext.Task where (o.TaskTypeID == 0 && o.WorkflowID == this.WorkflowID) // فعاليت آغازين select o).First(); TaskInstance ti = new TaskInstance(); ti.TaskInstanceID = Guid.NewGuid(); ti.PriorityID = priorityNo; ti.WorkflowInstanceID = wfInstance.WorkflowInstanceID; ti.TaskID = task.TaskID; ti.TaskCode = task.TaskCode; ti.TaskTitle = task.TaskTitle; if (string.IsNullOrEmpty(firstPerformer) == false) { ti.PerformerID = firstPerformer; } else if (string.IsNullOrEmpty(task.PerformerID) == false) { ti.PerformerID = task.PerformerID; } //else // throw new Exception("PerformerID is not selected"); ti.EntityName = wfInstance.EntityName; ti.EntityID = wfInstance.EntityID; ti.EntityTitle = wfInstance.EntityTitle; ti.EntityUrl = wfInstance.EntityUrl; //ti.EntityDateTime = wfInstance.entitydat ti.InsertUser = userName; ti.InsertDate = DateTime.Now; ti.TaskInstanceStatusID = (int)TaskInstanceStatusEnum.Waiting; // در حال انتظار ti.NotificationStatusID = (int)NotificationStatusEnum.Waiting; // در حال انتظار //ti.ExtraInt = isauthoforward; ti.ExtraInt2 = isAuthoforward ? 1 : 0; CreateWorkflowEventArgs WorkflowEventArg = new CreateWorkflowEventArgs(wfInstance, ti, userName); OnBeforeCreateWorkflow(WorkflowEventArg); ObjectContext.WorkflowInstance.AddObject(wfInstance); ObjectContext.TaskInstance.AddObject(ti); OnAfterCreateWorkflow(WorkflowEventArg); ObjectContext.SaveChanges(); } catch (Exception) { throw; } }
public void IdIsHostId() { // Arrange using (var testdb = new SqlWorkflowInstanceStoreTest()) { var view = new TestWorkflowView(testdb.CreateInstanceStore()); var model = new WorkflowModel(view); var wi = new WorkflowInstance(model); // Act wi.New(); var hostid = wi.Host.Id; var id = wi.Id; // Assert Assert.AreEqual(hostid, id); } }
public async Task <string> CreateNewWorkflow(WorkflowInstance workflow) { await WorkflowInstances.InsertOneAsync(workflow); return(workflow.Id); }
private WorkflowInstanceDocument Map(WorkflowInstance source) => mapper.Map <WorkflowInstanceDocument>(source);
public async Task PersistWorkflow(WorkflowInstance workflow) { await WorkflowInstances.ReplaceOneAsync(x => x.Id == workflow.Id, workflow); }
/// <summary> /// 用途:创建流程实例并返回首个流程活动工作项 /// 约定: /// 1、一个流程有且仅有一个根活动 /// 2、代理人不能发起委托人的新流程,只能处理委托日期后正在流转的流程数据 /// 3、有发起流程模型权限方可以操作 /// </summary> /// <param name="workflowGuid">流程模型guid</param> /// <returns>首个流程活动工作项</returns> public ResponseByWorkitem CreateWorkflowInstance(string workflowGuid, string name = null) { ///创建流程实例 WorkflowInstance wfi = new WorkflowInstance(workflowGuid, name); //wfi.Guid ... //wfi.Name ... //wfi.WorkflowGuid ... wfi.Author = this.Context.CurUser; //wfi.WorkflowState ... //wfi.Participator ... //wfi.Locker ... //wfi.BeginTime ...; //wfi.EndTime ...; //wfi.DataEntity ... wfi.SetContext(this.Context); ///加入权限控制 if (!(this.Context.CurUser.IsAdministrator() ||//是否大管理员 wfi.GetWorkflow().IsAdministrators(this.Context.CurUser) ||//是否流程模型管理员 wfi.GetWorkflow().IsLegalAuthor(this.Context.CurUser) //流程的合法发起用户 )) { return(new ResponseByWorkitem() { CallBackMessage = new ResultMessage() { State = false, Message = "不能发起流程!" } }); } ///开启流程实例服务 wfi.Start(); wfi.Save(); //创建活动实例 WorkitemInstance wii = new WorkitemInstance(wfi.Guid, wfi.GetWorkflow().GetStartNode()); //wii.Guid ... //wii.Name ... //wii.ActivityGuid ... //wii.WorkflowInstanceGuid ... //wii.AduitContent = ""; //wii.AduitSign = ""; //wii.ReadTime = null; //wii.NextActivities = null; wii.User = this.Context.CurUser; //wii.ProxyUser = null; //wii.IsProxy = false; //wii.WorkitemInstanceState ... //wii.FromWorkitemInstanceGuid = ""; //wii.AttachmentTrainsitions = null; //wii.SelectVoteItem = ""; //wii.OtherVoteItemContent = ""; //wii.BeginTime ...; //wii.EndTime ...; //wii.DataEntity ... wii.SetContext(this.Context); ///开启活动实例 wii.Start(); wii.Save(); ///活动前事件处理 var rm = wii.BeforeTrigger(); ResponseByWorkitem response; ///如果不满足 if (!rm.State) { response = new ResponseByWorkitem() { ActivityInstance = wii, //NextMaybeActivities=null, UIRight = this.Context.Config.RightByReadOnly, CallBackMessage = rm, }; } else { response = new ResponseByWorkitem() { ActivityInstance = wii, NextMaybeActivities = wii.GetNextEffectiveActivities(), UIRight = wii.GetActivity().UIRight, CallBackMessage = new ResultMessage() { State = true, Message = "" }, }; } return(response); }
internal static PersistedWorkflow ToPersistable(this WorkflowInstance instance, PersistedWorkflow persistable = null) { if (persistable == null) { persistable = new PersistedWorkflow(); } persistable.Data = JsonConvert.SerializeObject(instance.Data, SerializerSettings); persistable.Description = instance.Description; persistable.Reference = instance.Reference; persistable.InstanceId = new Guid(instance.Id); persistable.NextExecution = instance.NextExecution; persistable.Version = instance.Version; persistable.WorkflowDefinitionId = instance.WorkflowDefinitionId; persistable.Status = instance.Status; persistable.CreateTime = instance.CreateTime; persistable.CompleteTime = instance.CompleteTime; foreach (var ep in instance.ExecutionPointers) { var persistedEP = persistable.ExecutionPointers.FirstOrDefault(x => x.Id == ep.Id); if (persistedEP == null) { persistedEP = new PersistedExecutionPointer(); persistable.ExecutionPointers.Add(persistedEP); } persistedEP.Id = ep.Id ?? Guid.NewGuid().ToString(); persistedEP.StepId = ep.StepId; persistedEP.Active = ep.Active; persistedEP.SleepUntil = ep.SleepUntil; persistedEP.PersistenceData = JsonConvert.SerializeObject(ep.PersistenceData, SerializerSettings); persistedEP.StartTime = ep.StartTime; persistedEP.EndTime = ep.EndTime; persistedEP.StepName = ep.StepName; persistedEP.RetryCount = ep.RetryCount; persistedEP.PredecessorId = ep.PredecessorId; persistedEP.ContextItem = JsonConvert.SerializeObject(ep.ContextItem, SerializerSettings); persistedEP.Children = string.Empty; foreach (var child in ep.Children) { persistedEP.Children += child + ";"; } persistedEP.EventName = ep.EventName; persistedEP.EventKey = ep.EventKey; persistedEP.EventPublished = ep.EventPublished; persistedEP.EventData = JsonConvert.SerializeObject(ep.EventData, SerializerSettings); persistedEP.Outcome = JsonConvert.SerializeObject(ep.Outcome, SerializerSettings); persistedEP.Status = ep.Status; persistedEP.Scope = string.Empty; foreach (var item in ep.Scope) { persistedEP.Scope += item + ";"; } foreach (var attr in ep.ExtensionAttributes) { var persistedAttr = persistedEP.ExtensionAttributes.FirstOrDefault(x => x.AttributeKey == attr.Key); if (persistedAttr == null) { persistedAttr = new PersistedExtensionAttribute(); persistedEP.ExtensionAttributes.Add(persistedAttr); } persistedAttr.AttributeKey = attr.Key; persistedAttr.AttributeValue = JsonConvert.SerializeObject(attr.Value, SerializerSettings); } } return(persistable); }
public void IsLoadedReturnsTrueOnNew() { // Arrange using (var testdb = new SqlWorkflowInstanceStoreTest()) { var view = new TestWorkflowView(testdb.CreateInstanceStore()); var model = new WorkflowModel(view); var wi = new WorkflowInstance(model); wi.New(); // Act var actual = wi.IsLoaded; // Assert Assert.IsTrue(actual); } }
public Task <string> CreateNewWorkflow(WorkflowInstance workflow, CancellationToken _ = default) => _innerService.CreateNewWorkflow(workflow);
public override void AfterWorkflowIteration(WorkflowExecutorResult executorResult, WorkflowDefinition defintion, WorkflowInstance workflow, ExecutionPointer executionPointer) { base.AfterWorkflowIteration(executorResult, defintion, workflow, executionPointer); var func = _cancelCondition.Compile(); if (func((TData)workflow.Data)) { executionPointer.EndTime = DateTime.Now.ToUniversalTime(); executionPointer.Active = false; } }
public Task PersistWorkflow(WorkflowInstance workflow, CancellationToken _ = default) => _innerService.PersistWorkflow(workflow);
/// <summary> /// 流程传阅 /// </summary> /// <param name="instance">流程实例.</param> /// <param name="toUsersId">传阅目标用户.</param> public abstract bool PassAround(WorkflowInstance instance, params string[] toUsersId);
public WorkflowNode GetCurrentNode(string instanceID) { return(WorkflowInstance.GetInstance(instanceID).Current); }
public override ExecutionPipelineDirective InitForExecution(WorkflowExecutorResult executorResult, WorkflowDefinition defintion, WorkflowInstance workflow, ExecutionPointer executionPointer) { if (!executionPointer.EventPublished) { //resolve principal to be assigned var resolvedUser = Principal.Compile().DynamicInvoke(workflow.Data); executionPointer.ExtensionAttributes["AssignedPrincipal"] = resolvedUser; executionPointer.ExtensionAttributes["Prompt"] = UserPrompt; Dictionary <string, object> userOptions = new Dictionary <string, object>(); foreach (var outcome in Outcomes) { userOptions[outcome.Label ?? Convert.ToString(outcome.GetValue(workflow.Data) ?? "Proceed")] = outcome.GetValue(workflow.Data); } executionPointer.ExtensionAttributes["UserOptions"] = userOptions; executionPointer.EventKey = workflow.Id + "." + executionPointer.Id; executionPointer.EventName = "UserAction"; executionPointer.Active = false; executorResult.Subscriptions.Add(new EventSubscription() { WorkflowId = workflow.Id, StepId = executionPointer.StepId, EventName = executionPointer.EventName, EventKey = executionPointer.EventKey, SubscribeAsOf = DateTime.Now.ToUniversalTime() }); return(ExecutionPipelineDirective.Defer); } return(ExecutionPipelineDirective.Next); }
public static Dictionary <string, AttributeValue> ToDynamoMap(this WorkflowInstance source) { var result = new Dictionary <string, AttributeValue>(); result["id"] = new AttributeValue(source.Id); result["workflow_definition_id"] = new AttributeValue(source.WorkflowDefinitionId); result["version"] = new AttributeValue(source.Version.ToString()); result["next_execution"] = new AttributeValue() { N = (source.NextExecution ?? 0).ToString() }; result["create_time"] = new AttributeValue() { N = source.CreateTime.Ticks.ToString() }; result["data"] = new AttributeValue(JsonConvert.SerializeObject(source.Data, SerializerSettings)); result["workflow_status"] = new AttributeValue() { N = Convert.ToInt32(source.Status).ToString() }; if (!string.IsNullOrEmpty(source.Description)) { result["description"] = new AttributeValue(source.Description); } if (!string.IsNullOrEmpty(source.Reference)) { result["reference"] = new AttributeValue(source.Reference); } if (source.CompleteTime.HasValue) { result["complete_time"] = new AttributeValue() { N = source.CompleteTime.Value.Ticks.ToString() } } ; var pointers = new List <AttributeValue>(); foreach (var pointer in source.ExecutionPointers) { pointers.Add(new AttributeValue(JsonConvert.SerializeObject(pointer, SerializerSettings))); } result["pointers"] = new AttributeValue() { L = pointers }; if (source.Status == WorkflowStatus.Runnable) { result["runnable"] = new AttributeValue() { N = 1.ToString() } } ; return(result); }
private async Task DetermineNextExecutionTime(WorkflowInstance workflow, WorkflowDefinition def) { //TODO: move to own class workflow.NextExecution = null; if (workflow.Status == WorkflowStatus.Complete) { return; } foreach (var pointer in workflow.ExecutionPointers.Where(x => x.Active && (x.Children ?? new List <string>()).Count == 0)) { if (!pointer.SleepUntil.HasValue) { workflow.NextExecution = 0; return; } var pointerSleep = pointer.SleepUntil.Value.ToUniversalTime().Ticks; workflow.NextExecution = Math.Min(pointerSleep, workflow.NextExecution ?? pointerSleep); } foreach (var pointer in workflow.ExecutionPointers.Where(x => x.Active && (x.Children ?? new List <string>()).Count > 0)) { if (!workflow.ExecutionPointers.FindByScope(pointer.Id).All(x => x.EndTime.HasValue)) { continue; } if (!pointer.SleepUntil.HasValue) { workflow.NextExecution = 0; return; } var pointerSleep = pointer.SleepUntil.Value.ToUniversalTime().Ticks; workflow.NextExecution = Math.Min(pointerSleep, workflow.NextExecution ?? pointerSleep); } if ((workflow.NextExecution != null) || (workflow.ExecutionPointers.Any(x => x.EndTime == null))) { return; } workflow.Status = WorkflowStatus.Complete; workflow.CompleteTime = _datetimeProvider.UtcNow; using (var scope = _serviceProvider.CreateScope()) { var middlewareRunner = scope.ServiceProvider.GetRequiredService <IWorkflowMiddlewareRunner>(); await middlewareRunner.RunPostMiddleware(workflow, def); } _publisher.PublishNotification(new WorkflowCompleted { EventTimeUtc = _datetimeProvider.UtcNow, Reference = workflow.Reference, WorkflowInstanceId = workflow.Id, WorkflowDefinitionId = workflow.WorkflowDefinitionId, Version = workflow.Version }); }
public async Task <string> CreateNewWorkflow(WorkflowInstance workflow) { workflow.Id = Guid.NewGuid().ToString(); _instances.Add(workflow); return(workflow.Id); }
private void saveCodeActivity_ExecuteCode(object sender, EventArgs e) { var updateTreeRefresher = CreateUpdateTreeRefresher(EntityToken); var selectedPage = GetBinding <IPage>("SelectedPage"); var originalPage = DataFacade.GetData <IPage>(f => f.Id == selectedPage.Id).SingleOrDefault(); var viewLabelUpdated = originalPage == null || selectedPage.MenuTitle != originalPage.MenuTitle || selectedPage.Title != originalPage.Title; var treeviewRequiresRefreshing = false; var dataToAdd = new Dictionary <string, IData>(); var dataToUpdate = new Dictionary <string, IData>(); var dataValidated = true; WorkflowInstance publishWorkflowInstance = null; WorkflowInstance unpublishWorkflowInstance = null; try { using (var transactionScope = TransactionsFacade.CreateNewScope()) { dataValidated = PrepareAddUpdateMetaData(selectedPage, dataToAdd, dataToUpdate); if (dataValidated) { PublishControlledHelper.HandlePublishUnpublishWorkflows(selectedPage, UserSettings.ActiveLocaleCultureInfo.Name, PublishDate, UnpublishDate, ref publishWorkflowInstance, ref unpublishWorkflowInstance); if (selectedPage.PageTypeId != originalPage.PageTypeId) { // Adding metadata fields var oldPageMetaDataDefinitions = originalPage.GetAllowedMetaDataDefinitions().Except(selectedPage.GetAllowedMetaDataDefinitions(), new PageMetaDataDefinitionEqualityComparer()); foreach (var pageMetaDataDefinition in oldPageMetaDataDefinitions) { var oldMetaData = selectedPage.GetMetaData(pageMetaDataDefinition.Name, pageMetaDataDefinition.MetaDataTypeId); if (oldMetaData != null) { ProcessControllerFacade.FullDelete(oldMetaData); } } // Adding page folders var pageTypeDataFolderTypeLinks = DataFacade.GetData <IPageTypeDataFolderTypeLink>(). Where(f => f.PageTypeId == selectedPage.PageTypeId). Evaluate(). RemoveDeadLinks(); foreach (var pageTypeDataFolderTypeLink in pageTypeDataFolderTypeLinks) { if (selectedPage.GetFolderDefinitionId(pageTypeDataFolderTypeLink.DataTypeId) != Guid.Empty) { continue; } selectedPage.AddFolderDefinition(pageTypeDataFolderTypeLink.DataTypeId); treeviewRequiresRefreshing = true; } // Adding applications var pageTypeTreeLinks = DataFacade.GetData <IPageTypeTreeLink>(). Where(f => f.PageTypeId == selectedPage.PageTypeId). Evaluate(). RemoveDeadLinks(); foreach (var pageTypeTreeLink in pageTypeTreeLinks) { var tree = TreeFacade.GetTree(pageTypeTreeLink.TreeId); if (tree.HasAttachmentPoints(selectedPage.GetDataEntityToken())) { continue; } TreeFacade.AddPersistedAttachmentPoint(pageTypeTreeLink.TreeId, typeof(IPage), selectedPage.Id); treeviewRequiresRefreshing = true; } } foreach (var data in dataToAdd.Values) { DataFacade.AddNew(data); } foreach (var data in dataToUpdate.Values) { var publishControlled = data as IPublishControlled; publishControlled.PublicationStatus = GenericPublishProcessController.Draft; DataFacade.Update(data); } treeviewRequiresRefreshing |= (originalPage.Title != selectedPage.Title) || (originalPage.Description != selectedPage.Description) || (originalPage.PublicationStatus != selectedPage.PublicationStatus); // NOTE: updating originalPage object, in order to make XML & SQL provider work in the same way originalPage.TemplateId = selectedPage.TemplateId; originalPage.PageTypeId = selectedPage.PageTypeId; originalPage.Title = selectedPage.Title; originalPage.MenuTitle = selectedPage.MenuTitle; originalPage.UrlTitle = selectedPage.UrlTitle; originalPage.FriendlyUrl = selectedPage.FriendlyUrl; originalPage.Description = selectedPage.Description; originalPage.PublicationStatus = selectedPage.PublicationStatus; originalPage.SourceCultureName = selectedPage.SourceCultureName; DataFacade.Update(originalPage); var contentDictionary = GetBinding <Dictionary <string, string> >("NamedXhtmlFragments"); var existingContents = DataFacade.GetData <IPagePlaceholderContent>(f => f.PageId == selectedPage.Id).ToList(); foreach (var existingContent in existingContents) { if (contentDictionary.ContainsKey(existingContent.PlaceHolderId)) { existingContent.Content = contentDictionary[existingContent.PlaceHolderId]; existingContent.PublicationStatus = GenericPublishProcessController.Draft; DataFacade.Update(existingContent); } else { DataFacade.Delete(existingContent); } } foreach (var contentDictionaryElement in contentDictionary.Where(f => existingContents.Any(existing => existing.PlaceHolderId == f.Key) == false)) { var newContent = DataFacade.BuildNew <IPagePlaceholderContent>(); newContent.PageId = selectedPage.Id; newContent.PlaceHolderId = contentDictionaryElement.Key; newContent.Content = contentDictionaryElement.Value; newContent.SourceCultureName = UserSettings.ActiveLocaleCultureInfo.Name; newContent.PublicationStatus = GenericPublishProcessController.Draft; DataFacade.AddNew(newContent); } } transactionScope.Complete(); } if (publishWorkflowInstance != null) { publishWorkflowInstance.Start(); WorkflowFacade.RunWorkflow(publishWorkflowInstance); } if (unpublishWorkflowInstance != null) { unpublishWorkflowInstance.Start(); WorkflowFacade.RunWorkflow(unpublishWorkflowInstance); } if (_doPublish) { if (publishWorkflowInstance == null || PublishDate < DateTime.Now) { var actionToken = new GenericPublishProcessController.PublishActionToken(); var serviceContainer = WorkflowFacade.GetFlowControllerServicesContainer(WorkflowEnvironment.WorkflowInstanceId); ActionExecutorFacade.Execute(EntityToken, actionToken, serviceContainer); treeviewRequiresRefreshing = false; } else { var title = StringResourceSystemFacade.GetString("Composite.Management", "Website.Forms.Administrative.EditPage.PublishDatePreventPublishTitle"); var message = StringResourceSystemFacade.GetString("Composite.Management", "Website.Forms.Administrative.EditPage.PublishDatePreventPublish"); ShowMessage(DialogType.Warning, title, message); } } if (treeviewRequiresRefreshing) { updateTreeRefresher.PostRefreshMesseges(selectedPage.GetDataEntityToken()); } UpdateBinding("OldPublicationStatus", selectedPage.PublicationStatus); if (viewLabelUpdated) { RerenderView(); } } catch (Exception ex) { var mostSpecificException = ex; while (mostSpecificException.InnerException != null) { mostSpecificException = mostSpecificException.InnerException; } ShowMessage(DialogType.Error, "Save failed", string.Format("Save failed: {0}", mostSpecificException.Message)); Log.LogError("Page save", ex); } finally { SetSaveStatus(dataValidated); } }
public void GetWorkflowInstances_should_retrieve_workflows() { var workflow01 = new WorkflowInstance() { Data = new TestData() { Value1 = 7 }, Description = "My Description", Status = WorkflowStatus.Runnable, NextExecution = 0, Version = 1, WorkflowDefinitionId = "My Workflow", Reference = "My Reference" }; var executionPointerId1 = Guid.NewGuid().ToString(); workflow01.ExecutionPointers.Add(new ExecutionPointer() { Id = executionPointerId1, Active = true, StepId = 0, SleepUntil = new DateTime(2000, 1, 1).ToUniversalTime(), Scope = new List <string>() { "4", "3", "2", "1" } }); var workflowId01 = Subject.CreateNewWorkflow(workflow01).Result; var workflow02 = new WorkflowInstance() { Data = new TestData() { Value1 = 7 }, Description = "My Description", Status = WorkflowStatus.Runnable, NextExecution = 0, Version = 1, WorkflowDefinitionId = "My Workflow", Reference = "My Reference" }; var executionPointerId2 = Guid.NewGuid().ToString(); workflow02.ExecutionPointers.Add(new ExecutionPointer() { Id = executionPointerId2, Active = true, StepId = 0, SleepUntil = new DateTime(2000, 1, 1).ToUniversalTime(), Scope = new List <string>() { "4", "3", "2", "1" } }); var workflowId02 = Subject.CreateNewWorkflow(workflow02).Result; var workflow03 = new WorkflowInstance() { Data = new TestData() { Value1 = 7 }, Description = "My Description", Status = WorkflowStatus.Runnable, NextExecution = 0, Version = 1, WorkflowDefinitionId = "My Workflow", Reference = "My Reference" }; var executionPointerId3 = Guid.NewGuid().ToString(); workflow03.ExecutionPointers.Add(new ExecutionPointer() { Id = executionPointerId3, Active = true, StepId = 0, SleepUntil = new DateTime(2000, 1, 1).ToUniversalTime(), Scope = new List <string>() { "4", "3", "2", "1" } }); var workflowId03 = Subject.CreateNewWorkflow(workflow03).Result; var retrievedWorkflows = Subject.GetWorkflowInstances(new[] { workflowId01, workflowId02, workflowId03 }).Result; retrievedWorkflows.Count().ShouldBeEquivalentTo(3); var retrievedWorkflow01 = retrievedWorkflows.Single(o => o.Id == workflowId01); retrievedWorkflow01.ShouldBeEquivalentTo(workflow01); retrievedWorkflow01.ExecutionPointers.FindById(executionPointerId1) .Scope.Should().ContainInOrder(workflow01.ExecutionPointers.FindById(executionPointerId1).Scope); var retrievedWorkflow02 = retrievedWorkflows.Single(o => o.Id == workflowId02); retrievedWorkflow02.ShouldBeEquivalentTo(workflow02); retrievedWorkflow02.ExecutionPointers.FindById(executionPointerId2) .Scope.Should().ContainInOrder(workflow02.ExecutionPointers.FindById(executionPointerId2).Scope); var retrievedWorkflow03 = retrievedWorkflows.Single(o => o.Id == workflowId03); retrievedWorkflow03.ShouldBeEquivalentTo(workflow03); retrievedWorkflow03.ExecutionPointers.FindById(executionPointerId3) .Scope.Should().ContainInOrder(workflow03.ExecutionPointers.FindById(executionPointerId3).Scope); }
internal WorkflowInstanceProxy(WorkflowInstance instance) { this.instance = instance; }
private void RunWorkflow(WorkflowInstance workflow) { _scheduler.RunWorkflow(workflow.InstanceId); }
/// <summary> /// 计算环节参与人 /// </summary> public override IEnumerable<IUser> Resolve(WorkflowInstance instance) { // 已当前环节的原处理人为计算基准 var currentUser = SecurityContext.Provider.Get(instance.CurrentWorkItem.PartId); var actorUsers = new List<IUser>(); // 优先级顺序 // 1、指定环节处理人 // 2、固定角色处理人(建单用户、系统) // 3、流程角色处理人(根据角色名称查询) // 4、基于场景(RoleBase:当前用户、建单用户)的角色处理人 // 5、基于场景的指定部门的角色处理人 // 指定环节处理人(获取该环节最后一次非AutoFinished的处理人) if (!string.IsNullOrEmpty(this.RefActivityName)) { var lastUser = GetLastActivityApprover(instance.InstanceNo, this.RefActivityName); if (lastUser != null) { actorUsers.Add(lastUser); } return actorUsers; } // 固定角色 if (string.IsNullOrEmpty(this.RoleName)) { throw new NullReferenceException("当前环节未配置有效的参与者计算规则"); } if (this.RoleName == "建单用户") { actorUsers.Add(SecurityContext.Provider.Get(instance.CreatorId)); return actorUsers; } else if (this.RoleName == "系统") { actorUsers.Add(SecurityContext.Provider.GetUser("system")); return actorUsers; } else { // 配置角色 // 全局角色 if (string.IsNullOrEmpty(this.RoleBase)) { var roleUsers = _dao.QueryEntities<User>("k2client.actor.getroleusers", new { RoleName = this.RoleName }); actorUsers.AddRange(roleUsers.Select(roleUser => SecurityContext.Provider.Get(roleUser.Id))); return actorUsers; } else if (this.RoleBase == "当前用户" || this.RoleBase == "建单用户") { IList<User> listUser; #region 逐层遍历 var tempOrgId = ""; switch (this.RoleBase) { case "当前用户": tempOrgId = currentUser.DeptId; break; case "建单用户": tempOrgId = instance.CreatorDeptId; break; } do { listUser = _dao.QueryEntities<User>("K2Client.User.GetListByRoleOrg", new { OrgId = tempOrgId, RoleName = this.RoleName }); if (listUser == null || listUser.Count == 0) { tempOrgId = _dao.QueryScalar<string>("K2Client.Organization.GetParentId", new { OrgId = tempOrgId }); } } while ((listUser == null || listUser.Count == 0) && !string.IsNullOrEmpty(tempOrgId)); //这个遍历是逐部门往上的 #endregion return listUser; } else if(this.RoleBase == "指定部门" && !string.IsNullOrEmpty(this.DeptId)) { var listUser = _dao.QueryEntities<User>("K2Client.User.GetListByRoleOrg" , new { OrgId = this.DeptId, RoleName = this.RoleName }); return listUser; } } return actorUsers; }
/// <summary> /// 是否可以查看流程 /// </summary> public abstract bool CanViewWorkflow(WorkflowInstance instance);
public void IsLoadedFiresPropertyChanged() { // Arrange using (var testdb = new SqlWorkflowInstanceStoreTest()) { var view = new TestWorkflowView(testdb.CreateInstanceStore()); var model = new WorkflowModel(view); var wi = new WorkflowInstance(model); var propChanged = false; wi.PropertyChanged += (sender, args) => { if (!propChanged) { propChanged = args.PropertyName == "IsLoaded"; } }; // Act wi.New(); // Assert Assert.IsTrue(propChanged); } }
internal void SetWorkflowInstance(WorkflowInstance workflowInstance) { CodeContract.Requires(workflowInstance != null); _workflowInstance = workflowInstance; }
public void ResumeShouldResume() { // Arrange using (var testdb = new SqlWorkflowInstanceStoreTest()) { var view = new TestWorkflowView(testdb.CreateInstanceStore()); var model = new WorkflowModel(view); var wi = new WorkflowInstance(model); wi.New(); // Act wi.Resume(StateTrigger.T1); // Assert Assert.AreEqual(StateMachineExample.State2, wi.StateTracker.CurrentState); } }
protected void Page_Load(object sender, EventArgs e) { switch (this.RequestActionString.ToLower()) { case "getusers": GetNextUsers(this.RequestData["TemplateId"].ToString(), this.RequestData["FlowInstanceId"].ToString(), this.RequestData["Name"].ToString(), this.RequestData["CurrentName"].ToString()); break; case "getbackusers": Aim.WorkFlow.Task[] tks = Aim.WorkFlow.Task.FindAllByProperties(Aim.WorkFlow.Task.Prop_WorkflowInstanceID, this.RequestData["FlowInstanceId"].ToString(), Aim.WorkFlow.Task.Prop_ApprovalNodeName, this.RequestData["TaskName"].ToString()); if (tks != null && tks.Length == 1) //打回情况一个人的时候有效,多人的话,还是从之前配置里取 { this.PageState.Add("NextUserIds", tks[0].OwnerId); this.PageState.Add("NextUserNames", tks[0].Owner); } break; default: Aim.WorkFlow.Task fTask = null; if (this.RequestData["FormId"] != null) { Aim.WorkFlow.WorkflowInstance wf = WorkflowInstance.FindAllByProperties(WorkflowInstance.Prop_RelateId, this.RequestData["FormId"].ToString())[0]; fTask = Aim.WorkFlow.Task.FindAllByProperties(Aim.WorkFlow.Task.Prop_WorkflowInstanceID, wf.ID).Where(Ent => Ent.Ext1 != "Branch").ToArray()[0]; } else { fTask = Aim.WorkFlow.Task.Find(this.RequestData["TaskId"].ToString()); } /*if (fTask.Ext1 == "Branch") * { * Response.Redirect("FreeTask.aspx?op=r&Type=Branch&TaskId=" + this.RequestData["TaskId"].ToString()); * }*/ /*if (!fTask.UpdatedTime.HasValue) * { * try * { * DataTable dt = DataHelper.QueryDataTable("select FactDeptName,FactDeptId from View_SysUserGroupFact where UserId='" + this.UserInfo.UserID + "' and FactDeptName is not null "); * if (dt.Rows.Count > 0) * { * fTask.DeptId = dt.Rows[0]["FactDeptId"].ToString(); * fTask.DeptName = dt.Rows[0]["FactDeptName"].ToString(); * } * } * catch { } * fTask.UpdatedTime = DateTime.Now; * fTask.Save(); * }*/ Aim.WorkFlow.WorkflowInstance instance = WorkflowInstance.Find(fTask.WorkflowInstanceID); this.PageState.Add("InstanceId", fTask.WorkflowInstanceID); this.PageState.Add("TemplateId", instance.WorkflowTemplateID); FlowInstanceId = instance.ID; FormUrl = instance.RelateUrl; FlowDefineId = instance.WorkflowTemplateID; Title = fTask.WorkFlowName;//+ "->" + fTask.ApprovalNodeName; XmlSerializer xs = new XmlSerializer(typeof(TaskContext)); if (!string.IsNullOrEmpty(fTask.Context)) { StringReader sr = new StringReader(fTask.Context); TaskContext content = xs.Deserialize(sr) as TaskContext; if (content.SwitchRules.Length > 0) { TaskContextSwitchRuleNextAction[] arrs = content.SwitchRules[0].NextActions; string comboxdataText = "['{0}','{1}'],"; if (arrs.Length > 0) { int first = 0; foreach (TaskContextSwitchRuleNextAction ar in arrs) { //GetNextRoute(currentNode, nsmgr, ar.Name) NextStep += string.Format(comboxdataText, ar.Name, ar.Name); if (first == 0) { GetNextUsers(instance.WorkflowTemplateID, fTask.WorkflowInstanceID, ar.Name, fTask.ApprovalNodeName); } first++; } } else { NextStep += string.Format("['','{0}'],", "结束"); } } else { NextStep += string.Format("['','{0}'],", "结束"); } } else { NextStep += string.Format("['','{0}'],", "结束"); } NextStep = NextStep.TrimEnd(','); Aim.WorkFlow.Task[] tasks = Aim.WorkFlow.Task.FindAll(Expression.Eq("WorkflowInstanceID", fTask.WorkflowInstanceID)).OrderBy(ens => !ens.FinishTime.HasValue ? DateTime.Now : ens.FinishTime).OrderBy(ens => ens.CreatedTime).ToArray(); this.PageState.Add("Tasks", JsonHelper.GetJsonString(tasks)); this.PageState.Add("Task", fTask); break; } }
private async Task ExecuteAsync(WorkflowInstance wfi, CancellationToken stoppingToken) { using var scope = _serviceProvider.CreateScope(); var context = new StepExecutionContext() { StoppingToken = stoppingToken, ServiceProvider = _serviceProvider, Logger = _logger, ContextData = wfi.Data }; var executionResult = new ExecutionResult(); var sw = new Stopwatch(); try { _options?.Start?.Invoke(scope.ServiceProvider, wfi); var steps = scope.ServiceProvider.GetServices <IStepBodyAsync>().ToList(); _logger.LogInformation($"{wfi.Id} Begin"); sw.Start(); if (!steps.Any()) { throw new WorkflowStepNotRegisteredException(wfi.WorkflowId, wfi.Version); } foreach (var workFlowStep in wfi.Steps) { var retryCnt = 0; context.CurrentStep = workFlowStep; var stepBody = steps.FirstOrDefault(m => m.GetType() == workFlowStep.StepType); if (stepBody == null) { throw new NullReferenceException(workFlowStep?.StepType?.FullName); } _logger.LogInformation($"{workFlowStep.Id}, Begin"); var inComeData = context.ContextData; // retry step when fail while (retryCnt++ <= Math.Abs(context.CurrentStep.FailedRetryCount)) { executionResult = await stepBody.RunAsync(context, stoppingToken); if (executionResult.Proceed) { break; } } var outComeData = context.ContextData; // persistent current step data & status await _persistenceProvider.PersistWorkflowStepAsync(wfi.Id, wfi.WorkflowId, workFlowStep, inComeData, outComeData, executionResult, stoppingToken); if (!executionResult.Proceed) { _logger.LogError( $"{workFlowStep.Id}, retryCount: {retryCnt - 1}, error:{executionResult.InnerException.Message}"); break; } _logger.LogInformation($"{workFlowStep.Id}, End"); _logger.LogInformation( $"{workFlowStep.Id}, {executionResult.ConsumeElapsedMilliseconds} ms"); } sw.Stop(); if (!executionResult.Proceed) { _logger.LogError($"{wfi.Id}, End With Exception: {executionResult.InnerException}"); } _logger.LogInformation($"{wfi.Id}, End and Execute: {sw.ElapsedMilliseconds} ms"); } catch (System.Exception e) { _logger.LogError(e.Message, e); executionResult.Proceed = false; executionResult.InnerException = e; } finally { await _persistenceProvider.PersistWorkflowInstanceAsync(wfi, context, executionResult, sw.ElapsedMilliseconds, stoppingToken); _options?.End?.Invoke(scope.ServiceProvider, wfi, context, executionResult); } }
public async Task <RunWorkflowResult> ReviveAndRunAsync(WorkflowInstance workflowInstance, CancellationToken cancellationToken) { workflowInstance = await ReviveAsync(workflowInstance, cancellationToken); return(await _resumesWorkflow.ResumeWorkflowAsync(workflowInstance, null, null, cancellationToken)); }
/// <summary> /// 删除流程 /// </summary> /// <param name="instance"></param> /// <returns></returns> public abstract bool DeleteWorkflow(WorkflowInstance instance);
/// <summary> /// Constructor to initialize base class ProcessUow /// </summary> /// <param name="workflowInstance">WorkFlowInstance</param> /// <param name="unitOfWorkInstance">UnitOfWorkInstance</param> /// <param name="queue">Azure Queue</param> /// <param name="keepAlive">KeepAlive</param> /// <param name="container">Unity Container</param> public ClearStatisticsUow( WorkflowInstance workflowInstance, UnitOfWorkInstance unitOfWorkInstance, IQueue queue, Action keepAlive, IUnityContainer container) : base(workflowInstance, unitOfWorkInstance, queue, keepAlive, container) { }
/// <summary> /// 运行流程 /// </summary> /// <param name="instance">流程编号</param> /// <param name="result">审批结果</param> /// <returns></returns> /// <remarks> /// 根据用户选择的下一步骤,计算出下一环节的参与者并持久化到数据库 /// 1、检查流程数据的合法性(及权限) /// 2、根据Choice获取下一环节的定义(名称) /// 3、结束当前WorkflowItem /// 4、添加下一环节处理人的WorkItem(s)数据 /// ========================================================= /// 调用K2接口 /// </remarks> public abstract bool RunWorkflow(WorkflowInstance instance, ApproveResult result);
/// <summary> /// 克隆一个实例 /// </summary> /// <param name="WfRuntimeClone"></param> /// <param name="instanceClone"></param> /// <param name="WfRuntime"></param> /// <returns></returns> public static WorkflowInstance CloneWorkflowInstance(WorkflowRuntime WfRuntimeClone, WorkflowInstance instanceClone, WorkflowRuntime WfRuntime) { try { if (!WfRuntimeClone.IsStarted) { WfRuntimeClone.StartRuntime(); } StateMachineWorkflowInstance workflowinstance = new StateMachineWorkflowInstance(WfRuntimeClone, instanceClone.InstanceId); System.Workflow.Activities.StateMachineWorkflowActivity smworkflow = new StateMachineWorkflowActivity(); smworkflow = workflowinstance.StateMachineWorkflow; RuleDefinitions ruleDefinitions = smworkflow.GetValue(RuleDefinitions.RuleDefinitionsProperty) as RuleDefinitions; WorkflowMarkupSerializer markupSerializer = new WorkflowMarkupSerializer(); StringBuilder xoml = new StringBuilder(); StringBuilder rule = new StringBuilder(); XmlWriter xmlWriter = XmlWriter.Create(xoml); XmlWriter ruleWriter = XmlWriter.Create(rule); markupSerializer.Serialize(xmlWriter, smworkflow); if (ruleDefinitions != null) { markupSerializer.Serialize(ruleWriter, ruleDefinitions); } xmlWriter.Close(); ruleWriter.Close(); StringReader readxoml = new StringReader(xoml.ToString()); XmlReader readerxoml = XmlReader.Create(readxoml); WorkflowInstance instance; if (ruleDefinitions == null) { instance = WfRuntime.CreateWorkflow(readerxoml); } else { StringReader readrule = new StringReader(rule.ToString()); XmlReader readerrule = XmlReader.Create(readrule); instance = WfRuntime.CreateWorkflow(readerxoml, readerrule, null); } instance.Start(); return(instance); } catch (Exception ex) { LogHelper.WriteLog("CloneWorkflowInstance异常信息 :" + ex.ToString()); throw new Exception(ex.Message); } }
public DebugManager(Activity root, string moduleNamePrefix, string typeNamePrefix, string auxiliaryThreadName, bool breakOnStartup, WorkflowInstance host, bool debugStartedAtRoot) : this(root, moduleNamePrefix, typeNamePrefix, auxiliaryThreadName, breakOnStartup, host, debugStartedAtRoot, false) { }
/// <summary> /// 办理流程 /// </summary> /// <param name="instance">流程实例</param> /// <param name="result">处理结果</param> /// <param name="listNextUsers">分配办理人员列表</param> /// <param name="tobeReadUsers">待阅人员</param> /// <remarks></remarks> /// <returns></returns> public abstract bool RunWorkflow(WorkflowInstance instance, ApproveResult result, IList<IUser> listNextUsers, IList<IUser> tobeReadUsers);
public WorkflowInstancePipeBind() { _instance = null; _id = Guid.Empty; }
public void UpgradeWorkflow(WorkflowRuntime runtime, Guid instanceId) { WorkflowInstance workflowInstance = runtime.GetWorkflow(instanceId); var definition = workflowInstance.GetWorkflowDefinition(); if (!OldAssemblyNames.Contains(definition.GetType().Assembly.FullName)) { return; } lock (GetLockForWorkflow(instanceId)) { workflowInstance.Unload(); var are = new AutoResetEvent(false); var parameters = new Dictionary <string, object>(); //Получаем перзистанс и извлекаем состояние var persistance = runtime.GetService <NotTerminatingSqlWorkflowPersistenceService>(); persistance.OnArgsAllowed += delegate(object sender, NotTerminatingSqlWorkflowPersistenceService.WorkflowSavedParametersArgs e) { if (e.InstanceId == instanceId) { parameters = e.Parameters; are.Set(); } }; workflowInstance = runtime.GetWorkflow(instanceId); definition = workflowInstance.GetWorkflowDefinition(); if (!OldAssemblyNames.Contains(definition.GetType().Assembly.FullName)) { //Если версия изменилась то дальнейшие манипуляции не нужны return; } are.WaitOne(10000); workflowInstance.Unload(); using (var context = this.CreateContext()) { context.DeleteWorkflowInPesistenceStore(instanceId); context.SubmitChanges(); } var workflowState = WorkflowStateService.GetWorkflowState(instanceId); parameters.Add(StateMachineWithSimpleContainer.DontWriteToWorkflowHistoryPersistenceKey, true); using (var sync = new WorkflowSync(runtime, instanceId)) { if (!CreateWorkflowIfNotExists(runtime, instanceId, workflowState.Type, parameters)) //Это ожидание создания воркфлоу { sync.WaitHandle.WaitOne(600000); } } var wfinstance = new StateMachineWorkflowInstance(runtime, instanceId); using (var sync = new WorkflowSync(runtime, instanceId)) //Это ожидание завершения установки состояния воркфлоу { wfinstance.SetState(workflowState.WorkflowStateName); sync.WaitHandle.WaitOne(600000); } var args = new SetWorkflowInternalParametersEventArgs(instanceId, new Dictionary <string, object>() { { StateMachineWithSimpleContainer. DontWriteToWorkflowHistoryPersistenceKey , false } }); SetInternalParameters(null, args); } }
/// <summary> /// 传阅流程 /// </summary> /// <returns><c>true</c>, if around was passed, <c>false</c> otherwise.</returns> /// <param name="instance">流程实例.</param> /// <param name="toUsers">传阅用户.</param> public abstract bool PassAround(WorkflowInstance instance, IList<IUser> toUsers);
/// <summary> /// 启动流程实例 /// </summary> /// <param name="instance">流程实例对象</param> /// <remarks>同时新增流程办理历史</remarks> /// <returns></returns> public abstract bool SaveWorkflow(WorkflowInstance instance);
public static async ValueTask UpdateInputAsync(this IWorkflowStorageService service, WorkflowInstance workflowInstance, WorkflowInput?workflowInput, CancellationToken cancellationToken = default) { if (workflowInput != null) { workflowInstance !.Input = await service.SaveAsync(workflowInput, workflowInstance, cancellationToken); } }