Example #1
0
    public static void Main()
    {
        var e1 = false;
        var e2 = false;
        var e3 = false;

        var model = ProcessModel.Create()
                    .AddEventCatcher("start")
                    .AddActivity("a1", () => { })
                    .AddActivity("c1", () => e1 = true)
                    .AttachAsCompensationActivity("c1", "a1")
                    .AddActivity("a2", () => throw new Exception())
                    .AddActivity("c2", () => e2 = true)
                    .AttachAsCompensationActivity("c2", "a2")
                    .AddActivity("a3", () => { })
                    .AddActivity("c3", () => e3 = true)
                    .AttachAsCompensationActivity("c3", "a3")
                    .AddEventThrower("end")
                    .AddSequenceFlow("start", "a1", "a2", "a3", "end");

        var models    = new InMemoryProcessModelsStore(model);
        var instances = new InMemoryProcessInstancesStore();

        var sc = new ServiceCollection();

        sc.AddLogging(cfg => { cfg.AddConsole(); });

        var manager = new ProcessManager(models, instances, sc.BuildServiceProvider());
        var result  = manager.HandleEvent(null).First();

        var relatedInstance = manager.InstancesStore.GetById(result.ProcessInstanceId);
    }
        public void ReturnTwoTokensWhenThereAreEventHandlersInBothPaths()
        {
            var model = ProcessModel.Create()
                        .AddEventCatcher("start")
                        .AddActivity("msgBefore", () => { })
                        .AddParallelGateway("split")
                        .AddSequenceFlow("start", "msgBefore", "split")
                        .AddActivity("msgLeft", () => { })
                        .AddEventCatcher("evtLeft")
                        .AddActivity("msgRight", () => { })
                        .AddEventCatcher("evtRight")
                        .AddParallelGateway("join")
                        .AddSequenceFlow("split", "msgLeft", "evtLeft", "join")
                        .AddSequenceFlow("split", "msgRight", "evtRight", "join")
                        .AddActivity("msgAfter", () => { })
                        .AddEventThrower("end")
                        .AddSequenceFlow("join", "msgAfter", "end");

            var models    = new InMemoryProcessModelsStore(model);
            var instances = new InMemoryProcessInstancesStore();

            var manager = new ProcessManager(models, instances);

            var result = manager.HandleEvent(null);

            result.FirstOrDefault().AffectedTokens.Count().Should().Be(2);
        }
        public void StartMiddleEnd()
        {
            var models = new InMemoryProcessModelsStore();

            models.Store(ProcessModel.Create()
                         .AddEventCatcher("start", TypedEventCatcher <Start> .Create())
                         .AddEventCatcher("middle", CatchAnyEventCatcher.Create())
                         .AddEventThrower("end", SilentEventThrower.Instance)
                         .AddSequenceFlow("start", "middle", "end"));

            var instances = new InMemoryProcessInstancesStore();

            var manager = new ProcessManager(models, instances);

            var result = manager.HandleEvent(new Start()).First();

            manager.GetExecutionPoint(
                result.ProcessInstanceId,
                result.AffectedTokens.First()
                ).Should().Be("middle");

            result = manager.HandleEvent(result.ProcessInstanceId, result.AffectedTokens.First(), new object());
            manager.InstancesStore.GetById(result.ProcessInstanceId)
            .IsDone.Should().Be(true);
        }
Example #4
0
        public void WhenManualActivityFailsCompensationActivitiesRun()
        {
            var data  = 0;
            var model = ProcessModel.Create()
                        .AddAnyEventCatcher("start")
                        .AddActivity("regular", () => data       = 10)
                        .AddActivity("compensation", () => data -= 5)
                        .AttachAsCompensationActivity("compensation", "regular")
                        .AddActivity <ManualActivity>("failing")
                        .AddEventThrower("end")
                        .AddSequenceFlow("start", "regular", "failing", "end");

            var models    = new InMemoryProcessModelsStore(model);
            var instances = new InMemoryProcessInstancesStore();

            var manager = new ProcessManager(models, instances);

            var result = manager.HandleEvent(null).First();

            manager.HandleActivityFailure(
                result.ProcessInstanceId,
                result.AffectedTokens.First(),
                null);

            data.Should().Be(5);
        }
Example #5
0
        public void SimpleDecisionMakingProcess(bool data)
        {
            var output = false;
            var model  = ProcessModel.Create()
                         .AddEventCatcher("start")
                         .AddExclusiveGateway("If")
                         .AddActivity("True", () => output  = true)
                         .AddActivity("False", () => output = false)
                         .AddExclusiveGateway("EndIf")
                         .AddEventThrower("end")
                         .AddSequenceFlow("start", "If")
                         .AddConditionalSequenceFlow("If", "True", true)
                         .AddConditionalSequenceFlow("If", "False", false)
                         .AddSequenceFlow("True", "EndIf")
                         .AddSequenceFlow("False", "EndIf")
                         .AddSequenceFlow("EndIf", "end");

            var models    = new InMemoryProcessModelsStore(model);
            var instances = new InMemoryProcessInstancesStore();

            var manager = new ProcessManager(models, instances);

            manager.HandleEvent(data);

            output.Should().Be(data);
        }
Example #6
0
        public void PauseTheExecutionOfTheProcess()
        {
            var model = ProcessModel.Create()
                        .AddEventCatcher("start")
                        .AddActivity("activity", new UserActivity())
                        .AddEventThrower("end")
                        .AddSequenceFlow("start", "activity", "end");

            var instances = new InMemoryProcessInstancesStore();
            var models    = new InMemoryProcessModelsStore(model);

            var manager = new ProcessManager(models, instances);

            var result   = manager.HandleEvent(null).FirstOrDefault();
            var instance = manager
                           .InstancesStore
                           .GetById(result.ProcessInstanceId);

            instance.IsDone.Should().BeFalse();


            result = manager.HandleActivityCompletion(
                result.ProcessInstanceId,
                result.AffectedTokens.First(),
                null
                );

            instance.IsDone.Should().BeTrue();
        }
Example #7
0
        public void ThrowInvalidOperationExceptionWhenNonExistentInstanceIdIsInformedToHandleActivityCompletion()
        {
            var models    = new InMemoryProcessModelsStore();
            var instances = new InMemoryProcessInstancesStore();

            var manager = new ProcessManager(models, instances);

            Action sut = () => manager.HandleActivityCompletion(Guid.NewGuid(), Guid.NewGuid(), null);

            sut.Should().Throw <InvalidOperationException>();
        }
Example #8
0
        public void ReturnTheProcessInstancesStoreWhenRequested()
        {
            var models    = new InMemoryProcessModelsStore();
            var instances = new InMemoryProcessInstancesStore();

            var manager = new ProcessManager(models, instances);

            manager.GetService <IProcessInstancesStore>()
            .Should().Be(instances);

            manager.GetService <IProcessInstanceProvider>()
            .Should().Be(instances);
        }
Example #9
0
        public void WhenTheProcessFailsCompensationActivitiesRun2()
        {
            var model = ProcessModel.Create()
                        .AddAnyEventCatcher("start")
                        .AddActivityWithCompensation <RegularActivity, CompensationActivity>()
                        .AddActivity("failing", () => throw new Exception())
                        .AddEventThrower("end")
                        .AddSequenceFlow("start", "Regular", "failing", "end");

            var models    = new InMemoryProcessModelsStore(model);
            var instances = new InMemoryProcessInstancesStore();

            var manager = new ProcessManager(models, instances);

            manager.HandleEvent(null);
            SharedState.Should().Be(5);
        }
Example #10
0
        public void ThrowInvalidOperationExceptionWhenNonExistentModelIdIsInformedToHandleActivityCompletion()
        {
            var model = ProcessModel.CreateWithSingleActivity(
                new UserActivity()
                );

            var models    = new InMemoryProcessModelsStore(model);
            var instances = new InMemoryProcessInstancesStore();
            var manager   = new ProcessManager(models, instances);
            var result    = manager.HandleEvent(null).First();

            var manager2 = new ProcessManager(
                new InMemoryProcessModelsStore(),
                instances
                );

            Action sut = () => manager2.HandleActivityCompletion(result.ProcessInstanceId, Guid.NewGuid(), null);

            sut.Should().Throw <InvalidOperationException>();
        }
Example #11
0
        public void WhenTheProcessFailsCompensationActivitiesRun()
        {
            var data  = 0;
            var model = ProcessModel.Create()
                        .AddAnyEventCatcher("start")
                        .AddActivity("regular", () => data       = 10)
                        .AddActivity("compensation", () => data -= 5)
                        .AttachAsCompensationActivity("compensation", "regular")
                        .AddActivity("failing", () => throw new Exception())
                        .AddEventThrower("end")
                        .AddSequenceFlow("start", "regular", "failing", "end");

            var models    = new InMemoryProcessModelsStore(model);
            var instances = new InMemoryProcessInstancesStore();

            var manager = new ProcessManager(models, instances);

            manager.HandleEvent(null);
            data.Should().Be(5);
        }
        public void ReturnOneTokenWhenThereIsAnEventHandlerInOneOfThePaths()
        {
            var model = ProcessModel.Create()
                        .AddEventCatcher("start")
                        .AddActivity("msgBefore", () => { })
                        .AddParallelGateway("split")
                        .AddSequenceFlow("start", "msgBefore", "split")
                        .AddActivity("msgLeft", () => { })
                        .AddEventCatcher("evtLeft")
                        .AddActivity("msgRight", () => { })
                        .AddParallelGateway("join")
                        .AddSequenceFlow("split", "msgLeft", "evtLeft", "join")
                        .AddSequenceFlow("split", "msgRight", "join")
                        .AddActivity("msgAfter", () => { })
                        .AddEventThrower("end")
                        .AddSequenceFlow("join", "msgAfter", "end");

            var models    = new InMemoryProcessModelsStore(model);
            var instances = new InMemoryProcessInstancesStore();

            var manager = new ProcessManager(models, instances);

            var results = manager.HandleEvent(null).ToArray();

            results.Length.Should().Be(1);

            var result         = results[0];
            var affectedTokens = result.AffectedTokens.ToArray();

            affectedTokens.Length.Should().Be(1);

            result = manager
                     .HandleEvent(result.ProcessInstanceId, affectedTokens[0], null);
            //.AffectedTokens.

            var instance = manager.InstancesStore.GetById(result.ProcessInstanceId);

            instance.IsDone.Should().BeTrue();
        }
Example #13
0
        public void CreateInstancesOnlyWhenApplicable()
        {
            var model = ProcessModel.Create()
                        .AddEventCatcher("start", TypedEventCatcher <Start> .Create())
                        .AddEventCatcher("middle", CatchAnyEventCatcher.Create())
                        .AddEventThrower("end", SilentEventThrower.Instance)
                        .AddSequenceFlow("start", "middle", "end");

            var models = new InMemoryProcessModelsStore();

            models.Store(model);

            var instances = new InMemoryProcessInstancesStore();

            var manager = new ProcessManager(models, instances);

            manager.HandleEvent(new object());
            manager.InstancesStore.GetRunningInstancesCount().Should().Be(0);

            manager.HandleEvent(new Start());
            manager.InstancesStore.GetRunningInstancesCount().Should().Be(1);
        }
        public void ActivitiesRanInTheRightSequence()
        {
            var op = 1;
            var e0 = 0;
            var e1 = 0;
            var e2 = 0;
            var e3 = 0;

            var lockObject = new object();

            var model = ProcessModel.Create()
                        .AddEventCatcher("start")
                        .AddActivity("msgBefore", () => { e0 = op++; }) // 0+1
                        .AddParallelGateway("split")
                        .AddSequenceFlow("start", "msgBefore", "split")
                        .AddActivity("msgLeft", () => { lock (lockObject) { e1 = op++; } })  // 1+2
                        .AddActivity("msgRight", () => { lock (lockObject) { e2 = op++; } }) // 3+3
                        .AddParallelGateway("join")
                        .AddSequenceFlow("split", "msgLeft", "join")
                        .AddSequenceFlow("split", "msgRight", "join")
                        .AddActivity("msgAfter", () => { e3 = op++; }) // 6+4
                        .AddEventThrower("end")
                        .AddSequenceFlow("join", "msgAfter", "end");

            var models    = new InMemoryProcessModelsStore(model);
            var instances = new InMemoryProcessInstancesStore();

            var sc = new ServiceCollection();

            sc.AddLogging();
            sc.AddSingleton <IProcessMonitor, InMemoryProcessMonitor>();
            var sp      = sc.BuildServiceProvider();
            var manager = new ProcessManager(models, instances, sp);

            manager.HandleEvent(null);

            (e0 + e1 + e2 + e3).Should().Be(10);
        }
Example #15
0
        public void UsingDataReceivedInStartEventInTheFollowingAction()
        {
            var    input  = "Hello World";
            string output = null;

            var start = CatchAnyEventCatcher.Create();

            start.SetEventDataOutput("o");

            var activity = LambdaActivity.Create((la, ctx) =>
            {
                var i  = la.GetDataInputByName("i");
                output = (string)i.GetCurrentValue(ctx, "middle");
            });

            activity.Inputs.Add("i");

            var model = ProcessModel.Create()
                        .AddEventCatcher("start", start)
                        .AddActivity("middle", activity)
                        .AddEventThrower("end", SilentEventThrower.Instance)
                        .AddSequenceFlow("start", "middle", "end")
                        .AddDataAssociation("startToMiddle",
                                            DataAssociation.Create("start", "o", "middle", "i"));

            var models = new InMemoryProcessModelsStore();

            models.Store(model);

            var instances = new InMemoryProcessInstancesStore();

            var pm = new ProcessManager(models, instances);

            pm.HandleEvent(input);

            output.Should().Be(input);
        }
Example #16
0
        public void WhenProcessFailCompensationsAreExecutedOnlyForActivitiesThatWerePerformed()
        {
            var e1 = false;
            var e2 = false;
            var e3 = false;

            var model = ProcessModel.Create()
                        .AddAnyEventCatcher("start")
                        .AddActivity("a1", () => { })
                        .AddActivity("c1", () => e1 = true)
                        .AttachAsCompensationActivity("c1", "a1")
                        .AddActivity("a2", () => throw new Exception())
                        .AddActivity("c2", () => e2 = true)
                        .AttachAsCompensationActivity("c2", "a2")
                        .AddActivity("a3", () => { })
                        .AddActivity("c3", () => e3 = true)
                        .AttachAsCompensationActivity("c3", "a3")
                        .AddEventThrower("end")
                        .AddSequenceFlow("start", "a1", "a2", "a3", "end");

            var models    = new InMemoryProcessModelsStore(model);
            var instances = new InMemoryProcessInstancesStore();

            var manager = new ProcessManager(models, instances);

            var result          = manager.HandleEvent(null).First();
            var relatedInstance = manager.InstancesStore.GetById(result.ProcessInstanceId);

            relatedInstance.WasActivityCompleted("a1").Should().BeTrue();
            relatedInstance.WasActivityCompleted("a2").Should().BeFalse();
            relatedInstance.WasActivityCompleted("a3").Should().BeFalse();

            e1.Should().BeTrue();
            e2.Should().BeFalse();
            e3.Should().BeFalse();
        }