public void WaitNotifiesExecutionPlanOfWaitState() { var executionPlan = new Mock<IExecutionPlan>(); var execution = new Execution("id", "instanceId", Mock.Of<IWorkflowDefinition>(), executionPlan.Object); execution.Wait(); executionPlan.Verify(p => p.OnExecutionReachesWaitState(execution)); }
public void SignalResumesExecution() { var executionPlan = new Mock<IExecutionPlan>(); var execution = new Execution("id", "instanceId", Mock.Of<IWorkflowDefinition>(), executionPlan.Object); execution.Wait(); execution.Signal(); executionPlan.Verify(p => p.OnExecutionSignaled(execution)); }
private void FillChildren(IExecution parent, List<IExecution> children, IExecutionPlan executionPlan, IWorkflowDefinition workflowDefinition) { var result = graphClient.Cypher .Match("(root:Execution {Identifier: {id}})") .Match("(root)-[:PARENT_OF]->(child:Execution)") .OptionalMatch("(child)-[:EXECUTES]->(currentNode:Node)") .WithParam("id", parent.Identifier) .Return((child, currentNode) => new { Child = child.As<ExecutionModel>(), CurrentNode = currentNode.As<NodeModel>() }); foreach (var r in result.Results) { Dictionary<string, object> data = (Dictionary<string, object>) objectSerializer.Deserialize(r.Child.Data, typeof (Dictionary<string, object>)); var childExecutions = new List<IExecution>(); var e = new Execution(parent, r.CurrentNode == null ? null : workflowDefinition.Nodes.First(n => n.Identifier == r.CurrentNode.Identifier), r.Child.IsActive, r.Child.IsFinished, data, r.Child.IncomingTransition, r.Child.Identifier, r.Child.WorkflowInstanceIdentifier, executionPlan, childExecutions, workflowDefinition); children.Add(e); FillChildren(e, childExecutions, executionPlan, workflowDefinition); } }
public IExecution LoadExecution(string executionIdentifier, IExecutionPlan executionPlan) { var rootQuery = graphClient.Cypher .Match("(e:Execution {Identifier: {id}})") .OptionalMatch("(r:Execution)-[:PARENT_OF*]->(e)") .OptionalMatch("(r)-[:EXECUTES]->(currentNode:Node)") .Where("NOT (:Execution)-[:PARENT_OF*]->(r)") .WithParam("id", executionIdentifier) .Return((r, e, currentNode) => new { Root = r.As<ExecutionModel>(), Current = e.As<ExecutionModel>(), CurrentNode = currentNode.As<NodeModel>() }); var executionModel = rootQuery.Results.Last(); var root = executionModel.Root ?? executionModel.Current; var wfQuery = graphClient.Cypher .Match("(e:Execution {Identifier: {id}})-[*]->(n:Node)") .Match("(wf:WorkflowDefinition)-[*]->(n)") .OptionalMatch( "(e:Execution {Identifier: {id}})-[:REFERENCES]->(wf:WorkflowDefinition)") .WithParam("id", root.Identifier) .Return(wf => wf.As<WorkflowDefinitionModel>()); var workflowDefinition = LoadWorkflowDefinition(wfQuery.Results.First().Identifier); Dictionary<string, object> data = (Dictionary<string, object>) objectSerializer.Deserialize(root.Data, typeof (Dictionary<string, object>)); var children = new List<IExecution>(); var rootExecution = new Execution(null, executionModel.CurrentNode == null ? null : workflowDefinition.Nodes.First(n => n.Identifier == executionModel.CurrentNode.Identifier), root.IsActive, root.IsFinished, data, root.IncomingTransition, root.Identifier, root.WorkflowInstanceIdentifier, executionPlan, children, workflowDefinition); FillChildren(rootExecution, children, executionPlan, workflowDefinition); var collector = new ExecutionCollector(e => e.Identifier == executionIdentifier); rootExecution.Accept(collector); return collector.Result.First(); }
public IExecution StartNewInstance(string workflowDefinitionIdentifier, [CanBeNull] object data) { IWorkflowDefinition workflowDefinition = persistenceProvider.LoadWorkflowDefinition(workflowDefinitionIdentifier); if (workflowDefinition == null) { throw new InvalidOperationException(string.Format("Workflow definition with identifier '{0}' not found", workflowDefinitionIdentifier)); } var executionPlan = serviceLocator.GetInstance<IExecutionPlan>(); var identifier = workflowDefinitionIdentifier + "_" + Guid.NewGuid(); var execution = new Execution(identifier, identifier, workflowDefinition, executionPlan); persistenceProvider.Persist(execution); execution.Start(workflowDefinition, DataMapper.ExtractData(data)); return execution; }
protected bool Equals(Execution other) { return string.Equals(Identifier, other.Identifier); }
public void Split(INode node) { Stop(); if (node.OutgoingTransitions.Count() == 1) { Resume(node); return; } Children.ForEach(c => c.Kill()); var children = new List<IExecution>(); foreach (var outgoingTransition in node.OutgoingTransitions) { var outgoingNode = outgoingTransition.Destination; var child = new Execution(this, outgoingNode, true, false, Data, outgoingTransition.Identifier, Guid.NewGuid() + "_" + outgoingNode.Identifier, WorkflowInstanceIdentifier, executionPlan, new List<IExecution>(), workflowDefinition); Children.Add(child); children.Add(child); } foreach (var outgoing in children) { Logger.InfoFormat("Child-Execution '{0}' started.", outgoing.Identifier); executionPlan.OnExecutionStarting(outgoing); outgoing.CurrentNode.Execute(outgoing, executionPlan); } }
private IExecution TransformBack(ExecutionModel model, IExecutionPlan plan, IWorkflowDefinition workflowDefinition, IExecution parent) { IDictionary<string, object> data = new Dictionary<string, object>(); foreach (var variable in model.Variables) { data.Add(variable.VariableKey, serializer.Deserialize(variable.SerializedValue, Type.GetType(variable.ValueType))); } IList<IExecution> children = new List<IExecution>(); var execution = new Execution(parent, workflowDefinition.Nodes.FirstOrDefault(n => n.Identifier == model.CurrentNodeIdentifier), model.IsActive, model.IsFinished, data, model.IncomingTransition, model.Identifier, model.WorkflowInstanceIdentifier, plan, children, workflowDefinition); foreach (var child in model.Children) { children.Add(TransformBack(child, plan, workflowDefinition, execution)); } return execution; }