Example #1
0
        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));
        }
Example #2
0
        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();
        }
Example #5
0
        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;
        }
Example #6
0
 protected bool Equals(Execution other)
 {
     return string.Equals(Identifier, other.Identifier);
 }
Example #7
0
        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;
        }