public JObject GetPossiblePath(Guid id, string libID) //审批用户获取下一步可能的路径 { WorkFlowItem cwfi = bdb.WorkFlowItems.Where(i => i.WfInstanceId == id).FirstOrDefault(); ItServiceItem cisi = bdb.ItServiceItems.Where(i => i.ID == cwfi.WfBusinessId).FirstOrDefault(); WorkflowApplication wfApp = new WorkflowApplication(new ItService()) { InstanceStore = CreateInstanceStore(), PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e) { //var ex = e.GetInstanceExtensions<CustomTrackingParticipant>(); // Outputs = ex.First().Outputs.ToString(); return(PersistableIdleAction.Unload); }, Completed = delegate(WorkflowApplicationCompletedEventArgs e) { }, Aborted = delegate(WorkflowApplicationAbortedEventArgs e) { }, Unloaded = delegate(WorkflowApplicationEventArgs e) { }, OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e) { return(UnhandledExceptionAction.Terminate); }, Idle = delegate(WorkflowApplicationIdleEventArgs e) { } }; var trackerInstance = StateMachineStateTracker.LoadInstance(id, wfApp.WorkflowDefinition, ConfigurationManager.ConnectionStrings["ApacheConnection"].ConnectionString); //var Pt = trackerInstance.PossibleTransitions; var Pt = GetPossibleTransitions(libID, false, cisi.Status); //BookmarkResumptionResult result = wfApp.ResumeBookmark("Hello123", "ddd"); string[] strs = Pt.Split(','); JObject json = new JObject( new JProperty("rows", new JArray( from r in strs select new JObject( new JProperty("ID", r.ToString()), new JProperty("Name", r.ToString()))))); return(json); }
static void Main(string[] args) { Activity testing = new Process81(); WorkflowApplication app = new WorkflowApplication(testing); var tracker = new StateMachineStateTracker(app.WorkflowDefinition); app.Extensions.Add(tracker); //WorkflowInvoker.Invoke(app); app.Run(); Console.WriteLine(tracker.CurrentState); Console.ReadLine(); }
static AppWorkflow Create(IDbContext dbContext, Activity root, IDictionary <String, Object> args, WorkflowIdentity identity) { var aw = new AppWorkflow(); var store = aw.CreateInstanceStore(dbContext.ConnectionString(null)); if (args == null) { aw._application = new WorkflowApplication(root, identity); } else { aw._application = new WorkflowApplication(root, args, identity); } aw.SetApplicationHandlers(); aw._dbContext = dbContext; aw._tracker = StateMachineStateTracker.Attach(aw._application); aw._application.Extensions.Add(new WorkflowTracker(aw)); aw._application.InstanceStore = store; return(aw); }
private static InstanceStore CreateInstanceStore() { var conn = ConfigurationManager.ConnectionStrings["ApacheConnection"].ConnectionString; var store = new SqlWorkflowInstanceStore(conn) { InstanceLockedExceptionAction = InstanceLockedExceptionAction.AggressiveRetry, InstanceCompletionAction = InstanceCompletionAction.DeleteNothing, HostLockRenewalPeriod = TimeSpan.FromSeconds(20), RunnableInstancesDetectionPeriod = TimeSpan.FromSeconds(3) }; StateMachineStateTracker.Promote(store); var handle = store.CreateInstanceHandle(); var view = store.Execute(handle, new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(60)); store.DefaultInstanceOwner = view.InstanceOwner; handle.Free(); return(store); }
private void InitializeStateTracker(IExtensionEnabledWorkflowApplication workflow) { StateMachineStateTracker stateTracker = new StateMachineStateTracker(taskWorkflow); workflow.MyExtensions.Add(stateTracker); workflow.MyExtensions.Add(new StateTrackerPersistenceProvider(stateTracker)); this.stateTrackers.Add(workflow.Id, stateTracker); }
public JObject CreateWorkFlow(string libID) //起草者创建流程,并保存到微软持续化数据库中 { AutoResetEvent syncEvent = new AutoResetEvent(false); string currentUserId = User.Identity.GetUserId(); ApplicationUser user = db.Users.Include(i => i.Roles).FirstOrDefault(i => i.Id == currentUserId); //获取当前用户username WorkFlowInParameter WfInData = new WorkFlowInParameter(); WfInData.drafter = user.UserName; Dictionary <string, object> inputs = new Dictionary <string, object>(); inputs.Add("WfIn", WfInData); //var act = CreateActivityFrom(Server.MapPath("~") + "\\WorkFlow\\ItService.xaml"); WorkflowApplication wfApp = new WorkflowApplication(new ItService(), inputs) { InstanceStore = CreateInstanceStore(), PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e) { //var ex = e.GetInstanceExtensions<CustomTrackingParticipant>(); //Outputs = ex.First().Outputs.ToString(); return(PersistableIdleAction.Unload); }, Completed = delegate(WorkflowApplicationCompletedEventArgs e) { }, Aborted = delegate(WorkflowApplicationAbortedEventArgs e) { }, Unloaded = delegate(WorkflowApplicationEventArgs e) { syncEvent.Set(); }, OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e) { return(UnhandledExceptionAction.Terminate); }, Idle = delegate(WorkflowApplicationIdleEventArgs e) { } }; var StateTracker = new StateMachineStateTracker(wfApp.WorkflowDefinition); //当前状态追踪 wfApp.Extensions.Add(StateTracker); wfApp.Extensions.Add(new StateTrackerPersistenceProvider(StateTracker)); var cu = new CustomTrackingParticipant(); //获取Activity内部变量 wfApp.Extensions.Add(cu); //获取Activity内部变量需要的追踪器 Guid instanceId = wfApp.Id; //var trackerInstance = StateMachineStateTracker.LoadInstance(id, wfApp.WorkflowDefinition, ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString); wfApp.Run(); syncEvent.WaitOne(); //string CurrentUser = cu.Outputs["CurrentUser"].ToString(); //var Pt = StateTracker.PossibleTransitions; //var CurrentState = StateTracker.CurrentState; //BookmarkResumptionResult result = wfApp.ResumeBookmark("Hello123", "ddd"); var Pt = GetPossibleTransitions(libID, true, 1); string[] strs = Pt.Split(','); JObject json = new JObject( new JProperty("instanceId", instanceId), new JProperty("rows", new JArray( from r in strs select new JObject( new JProperty("ID", r.ToString()), new JProperty("Name", r.ToString()))))); return(json); }
public ActionResult ToNextState(ItServiceItem isi, Guid instanceId, string NextLink, string libid, string Opinion) //审批者到下一环节,思路:保存当前流程的数据,恢复bookmark到下一环节,并保存下一环节流程信息 { #region 判断是不是当前处理人 WorkFlowItem cwfi = bdb.WorkFlowItems.Where(i => i.WfInstanceId == instanceId).FirstOrDefault(); string currentUserId = User.Identity.GetUserId(); ApplicationUser user = db.Users.Include(i => i.Roles).FirstOrDefault(i => i.Id == currentUserId); if (cwfi.WfCurrentUser.ToString().Trim() != user.UserName.ToString().Trim()) { var json = new { errorMsg = "你不是当前处理人" }; return(Json(json, "text/html", JsonRequestBehavior.AllowGet)); } #endregion string[] strs = NextLink.Trim().Split('('); AutoResetEvent syncEvent = new AutoResetEvent(false); int isComplete = 0; WorkflowApplication wfApp = new WorkflowApplication(new ItService()) { InstanceStore = CreateInstanceStore(), PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e) { //var ex = e.GetInstanceExtensions<CustomTrackingParticipant>(); // Outputs = ex.First().Outputs.ToString(); return(PersistableIdleAction.Unload); }, Completed = delegate(WorkflowApplicationCompletedEventArgs e) { isComplete = 1; syncEvent.Set(); }, Aborted = delegate(WorkflowApplicationAbortedEventArgs e) { }, Unloaded = delegate(WorkflowApplicationEventArgs e) { syncEvent.Set(); }, OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e) { return(UnhandledExceptionAction.Terminate); }, Idle = delegate(WorkflowApplicationIdleEventArgs e) { } }; var StateTracker = new StateMachineStateTracker(wfApp.WorkflowDefinition); //当前状态追踪 wfApp.Extensions.Add(StateTracker); wfApp.Extensions.Add(new StateTrackerPersistenceProvider(StateTracker)); var cu = new CustomTrackingParticipant(); //获取Activity内部变量 wfApp.Extensions.Add(cu); //获取Activity内部变量需要的追踪器 //Guid instanceId = wfApp.Id; var trackerInstance = StateMachineStateTracker.LoadInstance(instanceId, wfApp.WorkflowDefinition, ConfigurationManager.ConnectionStrings["ApacheConnection"].ConnectionString); wfApp.Load(instanceId); BookmarkResumptionResult result = wfApp.ResumeBookmark(trackerInstance.CurrentState, strs[0]); //BookmarkResumptionResult result = wfApp.ResumeBookmark(trackerInstance.CurrentState, NextLink.Trim()); //恢复当前状态,并进入下一个bookmark,注意使用Trim,开始没使用,NextLInk无法取到,调试了大半夜 syncEvent.WaitOne(); string CurrentUser; string OpinionField = ""; string CurrentState; string completeStr = ""; if (isComplete == 0) { if (strs.Count() == 1) { CurrentUser = cu.Outputs["CurrentUser"].ToString(); } else { CurrentUser = db.LibraryApprovers.ToList().First(p => (p.LibID == libid) && (p.ApproverName == strs[1].Replace(")", ""))).Approver; } OpinionField = cu.Outputs["OpinionField"].ToString(); CurrentState = StateTracker.CurrentState; } else { CurrentUser = "******"; CurrentState = "已结束"; completeStr = "->结束"; } //string currentUserId = User.Identity.GetUserId(); //ApplicationUser user = db.Users.Include(i => i.Roles).FirstOrDefault(i => i.Id == currentUserId); //获取当前用户TrueName,为增加流转信息提供数据 WorkFlowItem wfi = bdb.WorkFlowItems.Where(i => i.WfInstanceId == instanceId).FirstOrDefault(); //获取当前流程信息 ItServiceItem cisi = bdb.ItServiceItems.Where(i => i.ID == isi.ID).FirstOrDefault(); //获取当前业务数据的信息 //业务数据更新开始 cisi.Title = isi.Title; cisi.applicant = isi.applicant; cisi.applicant_dept = isi.applicant_dept; //cisi.description = isi.description; cisi.isitype = isi.isitype; cisi.sub_isitype = isi.sub_isitype; cisi.end_isitype = isi.end_isitype; cisi.Object = isi.Object; cisi.Topic = isi.Topic; cisi.Purpose = isi.Purpose; cisi.Status = 1; if (NextLink == "驳回") { cisi.Status = 3; } if (isComplete == 1) { cisi.isiCompleteDate = DateTime.Now; if (NextLink == "撤销") { cisi.Status = 4; } else { cisi.Status = 2; } } #region 审批意见更新开始 if (Opinion != null) { if (Convert.ToString(Opinion) != "") { if (wfi.WfWriteField.Trim() == "FirstExamine") { cisi.FirstExamine = cisi.FirstExamine + "<br>" + Opinion + " (意见填写人:" + user.TrueName + " 时间:" + DateTime.Now + ")"; } if (wfi.WfWriteField.Trim() == "SecondExamine") { cisi.SecondExamine = cisi.SecondExamine + "<br>" + Opinion + " (意见填写人:" + user.TrueName + " 时间:" + DateTime.Now + ")"; } if (wfi.WfWriteField.Trim() == "LastExamine") { cisi.LastExamine = cisi.LastExamine + "<br>" + Opinion + " (意见填写人:" + user.TrueName + " 时间:" + DateTime.Now + ")"; } } } #endregion if (wfi != null) { wfi.WfCurrentUser = CurrentUser; wfi.Wfstatus = CurrentState; wfi.WfWriteField = OpinionField; if (isComplete == 1) { wfi.WfCompleteDate = DateTime.Now; } wfi.WfFlowChart = wfi.WfFlowChart + "->" + trackerInstance.CurrentState + "(" + user.TrueName + ")" + completeStr; //增加流转信息 try { bdb.SaveChanges(); var json = new { okMsg = "提交成功" }; return(Json(json, "text/html", JsonRequestBehavior.AllowGet)); } catch (Exception e) { var json = new { errorMsg = "提交失败" }; return(Json(json, "text/html", JsonRequestBehavior.AllowGet)); } } else { var json = new { errorMsg = "流程不存在" }; return(Json(json, "text/html", JsonRequestBehavior.AllowGet)); } }
public ActionResult DrafterToNextState(ItServiceItem isi, Guid instanceId, string NextLink, string libid) //起草者到下一环节 { string[] strs = NextLink.Trim().Split('('); AutoResetEvent syncEvent = new AutoResetEvent(false); WorkflowApplication wfApp = new WorkflowApplication(new ItService()) { InstanceStore = CreateInstanceStore(), PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e) { //var ex = e.GetInstanceExtensions<CustomTrackingParticipant>(); // Outputs = ex.First().Outputs.ToString();` return(PersistableIdleAction.Unload); }, Completed = delegate(WorkflowApplicationCompletedEventArgs e) { }, Aborted = delegate(WorkflowApplicationAbortedEventArgs e) { }, Unloaded = delegate(WorkflowApplicationEventArgs e) { syncEvent.Set(); }, OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e) { return(UnhandledExceptionAction.Terminate); }, Idle = delegate(WorkflowApplicationIdleEventArgs e) { } }; var StateTracker = new StateMachineStateTracker(wfApp.WorkflowDefinition); //当前状态追踪 wfApp.Extensions.Add(StateTracker); wfApp.Extensions.Add(new StateTrackerPersistenceProvider(StateTracker)); var cu = new CustomTrackingParticipant(); //获取Activity内部变量 wfApp.Extensions.Add(cu); //获取Activity内部变量需要的追踪器 //Guid instanceId = wfApp.Id; var trackerInstance = StateMachineStateTracker.LoadInstance(instanceId, wfApp.WorkflowDefinition, ConfigurationManager.ConnectionStrings["ApacheConnection"].ConnectionString); wfApp.Load(instanceId); //BookmarkResumptionResult result = wfApp.ResumeBookmark(trackerInstance.CurrentState, NextLink.Trim()); BookmarkResumptionResult result = wfApp.ResumeBookmark(trackerInstance.CurrentState, strs[0]); syncEvent.WaitOne(); //string CurrentUser = cu.Outputs["CurrentUser"].ToString(); string CurrentUser = db.LibraryApprovers.ToList().First(p => (p.LibID == libid) && (p.ApproverName == strs[1].Replace(")", ""))).Approver; //string CurrentRole = cu.Outputs["CurrentRole"].ToString(); string OpinionField = cu.Outputs["OpinionField"].ToString(); string Drafter = cu.Outputs["Drafter"].ToString(); var CurrentState = StateTracker.CurrentState; //var Pt = StateTracker.PossibleTransitions; ApplicationUser user = db.Users.Include(i => i.Roles).FirstOrDefault(i => i.UserName == Drafter); //获取当前用户username isi.drafter = Drafter; isi.isiCreateDate = DateTime.Now; isi.Status = 1; bdb.ItServiceItems.Add(isi); //添加业务数据 try { bdb.SaveChanges(); } catch { var json = new { errorMsg = "添加业务数据出错" }; return(Json(json, "text/html", JsonRequestBehavior.AllowGet)); } WorkFlowItem wf = new WorkFlowItem(); wf.WfInstanceId = instanceId; wf.WfType = "专病库IT服务申请"; wf.WfCurrentUser = CurrentUser; wf.WfDrafter = Drafter; wf.WfWriteField = OpinionField; wf.Wfstatus = CurrentState; wf.WfBussinessUrl = "/ItService/OpenWorkFlow?id=" + instanceId; wf.WfCreateDate = DateTime.Now; wf.WfBusinessId = isi.ID; //添加业务数据关联 wf.WfFlowChart = trackerInstance.CurrentState + "(" + user.TrueName + ")"; bdb.WorkFlowItems.Add(wf); bdb.SaveChanges(); try { bdb.SaveChanges(); var json = new { okMsg = "流程保存成功" }; return(Json(json, "text/html", JsonRequestBehavior.AllowGet)); } catch { var json = new { errorMsg = "流程保存出错" }; return(Json(json, "text/html", JsonRequestBehavior.AllowGet)); } }
public void TrackerShouldReportPreviousState() { var activity = new StateMachineExample(); var host = WorkflowApplicationTest.Create(activity); var tracker = new StateMachineStateTracker(activity); Debug.Assert(host != null, "host != null"); Debug.Assert(host.Extensions != null, "host.Extensions != null"); host.Extensions.Add(tracker); try { // Using Microsoft.Activities.Extensions run the workflow until a bookmark named "T1" Assert.IsInstanceOfType( host.TestWorkflowApplication.RunEpisode("T1", Constants.Timeout), typeof(WorkflowIdleEpisodeResult)); WorkflowTrace.Information("First Idle"); tracker.Trace(); Debug.Assert(tracker.TrackedStateMachines != null, "tracker.TrackedStateMachines != null"); Assert.AreEqual(1, tracker.TrackedStateMachines.Count); var stateTrackerInfo = tracker.TrackedStateMachines.Values.ElementAt(0); Debug.Assert(stateTrackerInfo != null, "stateTrackerInfo != null"); Assert.AreEqual(null, stateTrackerInfo.PreviousState); Assert.AreEqual(null, tracker.PreviousState); Assert.AreEqual(tracker.PreviousState, stateTrackerInfo.PreviousState); Debug.Assert(stateTrackerInfo.Transitions != null, "stateTrackerInfo.Transitions != null"); Assert.AreEqual(2, stateTrackerInfo.Transitions.Count); Assert.AreEqual("T1, T2", stateTrackerInfo.PossibleTransitions); // Run until bookmark "T3" Assert.IsInstanceOfType( host.TestWorkflowApplication.ResumeEpisodeBookmark("T1", null, "T3"), typeof(WorkflowIdleEpisodeResult)); WorkflowTrace.Information("Second Idle"); tracker.Trace(); // Use the tracker operations that are forwarded to the current state Debug.Assert(tracker.TrackedStateMachines != null, "tracker.TrackedStateMachines != null"); Assert.AreEqual(1, tracker.TrackedStateMachines.Count); Assert.AreEqual("State1", tracker.PreviousState); Debug.Assert(tracker.Transitions != null, "tracker.Transitions != null"); Assert.AreEqual(2, tracker.Transitions.Count); Assert.AreEqual("T3, T5", tracker.PossibleTransitions); // Resume bookmark T5 and run until complete Assert.IsInstanceOfType( host.TestWorkflowApplication.ResumeEpisodeBookmark("T5", null), typeof(WorkflowCompletedEpisodeResult)); Assert.AreEqual(1, tracker.TrackedStateMachines.Count); } finally { tracker.Trace(); Debug.Assert(host.Tracking != null, "host.Tracking != null"); host.Tracking.Trace(); } }
public void TrackerShouldConvertToAndFromXml() { var activity = new StateMachineExample(); var host = WorkflowApplicationTest.Create(activity); var tracker1 = new StateMachineStateTracker(activity); Debug.Assert(host != null, "host != null"); Debug.Assert(host.Extensions != null, "host.Extensions != null"); host.Extensions.Add(tracker1); try { host.TestWorkflowApplication.RunEpisode("T1", Constants.Timeout); host.TestWorkflowApplication.ResumeEpisodeBookmark("T1", null, "T3"); var xml = tracker1.ToXml(); WorkflowTrace.Information("*** Tracker1***"); WorkflowTrace.Information(xml); WorkflowTrace.Information(Environment.NewLine); var tracker2 = StateMachineStateTracker.Parse(activity, xml); WorkflowTrace.Information("*** Tracker2***"); WorkflowTrace.Information(tracker2.ToXml()); WorkflowTrace.Information(Environment.NewLine); Assert.AreEqual(tracker1.CurrentState, tracker2.CurrentState); Assert.AreEqual(tracker1.CurrentStateMachine, tracker2.CurrentStateMachine); Assert.AreEqual(tracker1.InstanceId, tracker2.InstanceId); Assert.AreEqual(tracker1.PossibleTransitions, tracker2.PossibleTransitions); Assert.AreEqual(tracker1.PreviousState, tracker2.PreviousState); Assert.AreEqual(tracker1.PreviousStateMachine, tracker2.PreviousStateMachine); Assert.AreEqual(tracker1.RootActivity, tracker2.RootActivity); AssertHelper.AreEqual(tracker1.StateHistory, tracker2.StateHistory); AssertHelper.AreEqual(tracker1.Transitions, tracker2.Transitions); } finally { host.Tracking.Trace(); } }
public void TrackedStateMachinesShouldBeEmptyOnCreate() { // Arrange var tracker = new StateMachineStateTracker(new StateMachine()); // Act var trackedMachines = tracker.TrackedStateMachines; // Assert Assert.IsNotNull(trackedMachines); }
public void PossibleTransitionsWithNoCurrentShouldReturnNull() { // Arrange var tracker = new StateMachineStateTracker(new Sequence()); // Act / Assert Assert.IsNull(tracker.PossibleTransitions); }
public void HistoryIsCircularBuffer() { // Arrange const int MaxHistory = 3; var activity = new StateMachineExample(); var host = WorkflowApplicationTest.Create(activity); var tracker = new StateMachineStateTracker(activity, MaxHistory); host.Extensions.Add(tracker); try { // Start the workflow - run to State1 with bookmark "T1" host.TestWorkflowApplication.RunEpisode("T1", Constants.Timeout); // History // State1 CollectionAssert.AreEqual(tracker.StateHistory.ToList(), new[] { "State1" }); // Run until State2 with bookmark "T3" host.TestWorkflowApplication.ResumeEpisodeBookmark("T1", null, "T3"); // History // State1 // State2 CollectionAssert.AreEqual(tracker.StateHistory.ToList(), new[] { "State1", "State2" }); // Run until State1 with bookmark "T1" host.TestWorkflowApplication.ResumeEpisodeBookmark("T3", null, "T1"); // History // State1 // State2 // State1 CollectionAssert.AreEqual(tracker.StateHistory.ToList(), new[] { "State1", "State2", "State1" }); // Run until State2 with bookmark "T3" host.TestWorkflowApplication.ResumeEpisodeBookmark("T1", null, "T3"); // History // State1 <- Dropped from buffer // State2 // State1 // State2 Assert.AreEqual(MaxHistory, tracker.StateHistory.Count()); CollectionAssert.AreEqual(tracker.StateHistory.ToList(), new[] { "State2", "State1", "State2" }); } finally { tracker.Trace(); Debug.Assert(host.Tracking != null, "host.Tracking != null"); host.Tracking.Trace(); } }
public void CurrentStateWithNoCurrentShouldReturnNull() { // Arrange var tracker = new StateMachineStateTracker(new Sequence()); // Act / Assert Assert.IsNull(tracker.CurrentState); }