Пример #1
0
 internal DynObject AddDefaultValues()
 {
     Add("EventDate", (ctx) => ctx.IncomingEvent.EventDate);
     Add("CreationDate", (ctx) => WorkflowClock.Now());
     Add("ExternalId", (ctx) => ctx.Workflow.ExternalId);
     return(this);
 }
Пример #2
0
        private static RunContext CreateContextForEvaluateArgument()
        {
            var factory = new WorkflowFactory <RunContext>(null, null)
            {
                Serializer = new PartialJsonWorkflowSerializer()
            };

            var ev = new IncomingEvent()
            {
                Name         = "evnt1",
                Uuid         = Guid.NewGuid(),
                ExternalId   = Guid.NewGuid().ToString(),
                EventDate    = WorkflowClock.Now(),
                CreationDate = WorkflowClock.Now(),
            };

            var wrk = factory.CreateNewWorkflow(
                "Test",
                1,
                ev.ExternalId,
                new DynObject()
                );

            RunContext ctx = new RunContext().Set(wrk, ev, factory);

            return(ctx);
        }
Пример #3
0
        public void Lock(uint crc)
        {
            var d = WorkflowClock.Now().AddSeconds(_timeout);

            while (true)
            {
                if (WorkflowClock.Now() > d)
                {
                    throw new Bb.Workflows.Exceptions.LockFailedException(crc);
                }

                try
                {
                    var result = _manager.Update($"INSERT INTO [Locks] ([Uuid], [InsertedDate]) VALUES (@uuid, CURRENT_TIMESTAMP)",
                                                 _manager.CreateParameter("uuid", System.Data.DbType.Int64, crc)

                                                 );
                    break;
                }
                catch (Exception)
                {
                }

                Thread.Yield();
            }
        }
Пример #4
0
        private Task Callback(IBrokerContext context)
        {
            if (context.Headers.TryGetValue(_domainHeader, out object header))
            {
                var domain         = System.Text.Encoding.ASCII.GetString((byte[])header);
                var workflowEngine = _provider.Get(domain);

                try
                {
                    workflowEngine.EvaluateEvent(context.Utf8Data);

                    context.Commit();
                }
                catch (System.Exception exception)
                {
                    if (context.CanBeRequeued())
                    {
                        context.RequeueLast();
                    }

                    else
                    {
                        Dictionary <string, object> _headers = new Dictionary <string, object>();
                        foreach (var item in context.Headers)
                        {
                            _headers.Add(item.Key, System.Text.Encoding.ASCII.GetString((byte[])item.Value));
                        }

                        _deadQueue.Publish(
                            new
                        {
                            RepushedAt       = WorkflowClock.Now(),
                            OriginExchange   = context.Exchange,
                            OriginRoutingKey = context.RoutingKey,
                            context.Utf8Data,
                            Exception = exception,
                        },
                            _headers
                            );

                        context.Commit();
                    }
                }

                return(Task.CompletedTask);
            }

            throw new System.Exception($"missing domain header {_domainHeader}");
        }
Пример #5
0
        public void TestFilter()
        {
            string txt;
            var    storage = new MemoryStorage();
            var    engine  = CreateEngine(storage, payload);

            // not integrated because no country specified
            txt = MessageText
                  .Text("Name", "Event1")
                  .Add("Uuid", Guid.NewGuid())
                  .Add("ExternalId", Guid.NewGuid())
                  .Add("CreationDate", WorkflowClock.Now())
                  .Add("EventDate", WorkflowClock.Now().AddMinutes(-5));
            engine.EvaluateEvent(txt);
            Assert.AreEqual(storage.GetAll <Workflow>().Count(), 0);

            // not integrated because country specified is wrong
            txt = MessageText
                  .Text("Name", "Event1")
                  .Add("Uuid", Guid.NewGuid())
                  .Add("ExternalId", Guid.NewGuid())
                  .Add("CreationDate", WorkflowClock.Now())
                  .Add("EventDate", WorkflowClock.Now().AddMinutes(-5))
                  .Add("Country", "Germany");
            engine.EvaluateEvent(txt);
            Assert.AreEqual(storage.GetAll <Workflow>().Count(), 0);

            // not integrated because event name is bypassed
            txt = MessageText
                  .Text("Name", "Event666")
                  .Add("Uuid", Guid.NewGuid())
                  .Add("ExternalId", Guid.NewGuid())
                  .Add("CreationDate", WorkflowClock.Now())
                  .Add("EventDate", WorkflowClock.Now().AddMinutes(-5))
                  .Add("Country", "Germany");
            engine.EvaluateEvent(txt);
            Assert.AreEqual(storage.GetAll <Workflow>().Count(), 0);

            // must be integrated
            txt = MessageText
                  .Text("Name", "Event1")
                  .Add("Uuid", Guid.NewGuid())
                  .Add("ExternalId", Guid.NewGuid())
                  .Add("CreationDate", WorkflowClock.Now())
                  .Add("EventDate", WorkflowClock.Now().AddMinutes(-5))
                  .Add("Country", "France");
            engine.EvaluateEvent(txt);
            Assert.AreEqual(storage.GetAll <Workflow>().Count(), 1);
        }
Пример #6
0
        public void SerializeOutputAction()
        {
            string uuid = Guid.NewGuid().ToString();

            DynObject.Create("Name", Constants.PushReminder)
            .Add("delay", WorkflowClock.Now().AddMinutes(10).ToString())
            .Add("canal", (ctx) => "IncomingEvent") // --read configuration where canal can be found
            .Add("Message",
                 DynObject.Create("Uuid", uuid)
                 .Add("Name", Constants.Events.ExpiredEventName)
                 .Add("EventDate", (ctx) => WorkflowClock.Now().AddMinutes(10).ToString())
                 .Add("CreationDate", (ctx) => WorkflowClock.Now().ToString())
                 .Add("ExternalId", (ctx) => ctx.Workflow.ExternalId)
                 .Add("CurrentState", (ctx) => ctx.Workflow.CurrentState))

            ;
        }
Пример #7
0
        public void Lock(uint crc)
        {
            var d = WorkflowClock.Now().AddSeconds(_timeout);

            while (true)
            {
                if (WorkflowClock.Now() > d)
                {
                    throw new Exceptions.LockFailedException(crc);
                }

                if (_crc.TryAdd(crc, WorkflowClock.Now()))
                {
                    break;
                }

                Thread.Yield();
            }
        }
        public ResultAction Map(RunContext ctx)
        {
            var result = new ResultAction()
            {
                Uuid      = Guid.NewGuid(),
                Name      = this.Name,
                Label     = this.Name,
                Delay     = this.Delay,
                Kind      = Kind,
                EventDate = WorkflowClock.Now(),
                Event     = ctx.Event,
            };

            foreach (var item in this.Arguments.Items)
            {
                result.Arguments.Add(item.Key, item.Value);
            }

            return(result);
        }
Пример #9
0
        public void TestInitializeWithJumpState()
        {
            string txt;
            var    storage = new MemoryStorage();
            var    engine  = CreateEngine(storage, payload2);

            // must be integrated
            txt = MessageText
                  .Text("Name", "Event1")
                  .Add("Uuid", Guid.NewGuid())
                  .Add("ExternalId", Guid.NewGuid())
                  .Add("CreationDate", WorkflowClock.Now())
                  .Add("EventDate", WorkflowClock.Now().AddMinutes(-5))
                  .Add("Country", "France")
                  .Add("Age", 25);
            engine.EvaluateEvent(txt);

            var workF = storage.GetAll <Workflow>().FirstOrDefault();

            Assert.AreEqual(workF.CurrentState, "State2");
        }
Пример #10
0
        public void TestExpire()
        {
            string txt;
            string uuid    = Guid.NewGuid().ToString();
            var    storage = new MemoryStorage();
            var    engine  = CreateEngine(storage, payload);

            txt = MessageText
                  .Text("Name", "Event1")
                  .Add("Uuid", Guid.NewGuid())
                  .Add("ExternalId", uuid)
                  .Add("CreationDate", WorkflowClock.Now())
                  .Add("EventDate", WorkflowClock.Now().AddMinutes(-5))
                  .Add("Country", "France")
                  .Add("age", 25)
            ;
            engine.EvaluateEvent(txt);

            var wor = storage.GetAll <Workflow>().FirstOrDefault();
            var bus = storage.GetAll <PushedAction>().ToList();

            Assert.AreEqual(wor.CurrentState, "State1");


            // must be integrated
            txt = MessageText
                  .Text("Name", Constants.Events.ExpiredEventName)
                  .Add("Uuid", uuid)
                  .Add("ExternalId", uuid)
                  .Add("WorkflowId", wor.Uuid)
                  .Add("CreationDate", WorkflowClock.Now())
                  .Add("EventDate", WorkflowClock.Now().AddMinutes(-5))
                  .Add("CurrentState", "State1");
            engine.EvaluateEvent(txt);
            wor = storage.GetAll <Workflow>().FirstOrDefault();

            Assert.AreEqual(wor.CurrentState, "State3");
        }
Пример #11
0
        public void InitializeWorkflowWithRule()
        {
            var config  = new WorkflowsConfig();
            var storage = new MemoryStorage();

            config.AddDocument(
                new WorkflowConfig()
            {
                Name = "wrk1", Label = "wrk1 config", Version = 1,
            }
                .AddInitializer(new InitializationOnEventConfig()
            {
                EventName = "evnt1",
            }.AddSwitch("State1"))
                .AddState(new StateConfig()
            {
                Name = "State1", Label = "State1",
            }
                          .AddEvent(new IncomingEventConfig()
            {
                Name = "evnt2"
            }
                                    .AddTransition(new TransitionConfig()
            {
                TargetStateName = "State2", WhenRule = (c) => c.IncomingEvent.Name == "evnt2"
            })
                                    )
                          )
                .AddState(new StateConfig()
            {
                Name = "State2", Label = "State2"
            }
                          )
                );

            var template = new TemplateRepository(typeof(TemplateModels))
            {
                DefaultAction = TemplateModels.DefaultAction,
            };
            var metadatas = new MetadatRepository(typeof(MetadataModels))
            {
                DefaultAction = MetadataModels.DefaultAction.ToDictionary(c => c.Key, c => c.Value),
            };

            var factory = new WorkflowFactory <RunContext>(null, null)
            {
                Serializer = new PartialJsonWorkflowSerializer()
            };

            var processor = new WorkflowProcessor <RunContext>(config, factory)
            {
                LoadExistingWorkflowsByExternalId = (key) => storage.GetBy <Workflow, string>(key, c => c.ExternalId).ToList(),
                OutputActions = () => CreateOutput(new PartialJsonWorkflowSerializer(), storage),
                Templates     = template,
                Metadatas     = metadatas,
            };


            var ev = new IncomingEvent()
            {
                Name         = "evnt1",
                Uuid         = Guid.NewGuid(),
                ExternalId   = Guid.NewGuid().ToString(),
                EventDate    = WorkflowClock.Now(),
                CreationDate = WorkflowClock.Now(),
            };

            processor.EvaluateEvent(ev);
            var wrk = storage.GetAll <Workflow>().FirstOrDefault(c => c.ExternalId == ev.ExternalId);

            Assert.AreEqual(wrk.CurrentState, "State1");


            ev = new IncomingEvent()
            {
                Name         = "evnt2",
                Uuid         = Guid.NewGuid(),
                ExternalId   = Guid.NewGuid().ToString(),
                EventDate    = WorkflowClock.Now(),
                CreationDate = WorkflowClock.Now(),
            };
            processor.EvaluateEvent(ev);
            wrk = storage.GetAll <Workflow>().FirstOrDefault(c => c.ExternalId == ev.ExternalId);
            Assert.AreEqual(wrk, null);
        }
Пример #12
0
        public void InitializeWorkflowWithPushedAction()
        {
            var config  = new WorkflowsConfig();
            var storage = new MemoryStorage();

            config.AddDocument(
                new WorkflowConfig()
            {
                Name = "wrk1", Label = "wrk1 config", Version = 1,
            }

                .AddInitializer(new InitializationOnEventConfig()
            {
                EventName = "evnt1", Recursive = true
            }.AddSwitch("State1"))

                .AddState(new StateConfig()
            {
                Name = "State1", Label = "State1",
            }
                          .AddIncomingActions(null, new ResultActionConfig()
            {
                Name = "act_on_state_in_1"
            })
                          .AddOutcomingActions(null, new ResultActionConfig()
            {
                Name = "act_on_state_out"
            })
                          .AddEvent(new IncomingEventConfig()
            {
                Name = "evnt1"
            }
                                    .AddAction(null, new ResultActionConfig()
            {
                Name = "act_on_event"
            })
                                    .AddTransition(new TransitionConfig()
            {
                TargetStateName = "State2"
            }
                                                   .AddAction(null, new ResultActionConfig()
            {
                Name = "act_on_transition"
            })
                                                   )

                                    )
                          )
                .AddState(new StateConfig()
            {
                Name = "State2", Label = "State2"
            }
                          .AddIncomingActions(null, new ResultActionConfig()
            {
                Name = "act_on_state_in_2"
            }
                                              .AddArgument("name", "@Event.Name")
                                              )

                          )
                );

            var template = new TemplateRepository(typeof(TemplateModels))
            {
                DefaultAction = TemplateModels.DefaultAction,
            };
            var metadatas = new MetadatRepository(typeof(MetadataModels))
            {
                DefaultAction = MetadataModels.DefaultAction.ToDictionary(c => c.Key, c => c.Value),
            };
            var factory = new WorkflowFactory <RunContext>(null, null)
            {
                Serializer = new PartialJsonWorkflowSerializer()
            };
            var processor = new WorkflowProcessor <RunContext>(config, factory)
            {
                LoadExistingWorkflowsByExternalId = (key) => storage.GetBy <Workflow, string>(key, c => c.ExternalId).ToList(),
                OutputActions = () => CreateOutput(new PartialJsonWorkflowSerializer(), storage),
                Templates     = template,
                Metadatas     = metadatas,
            };

            var ev = new IncomingEvent()
            {
                Name         = "evnt1",
                Uuid         = Guid.NewGuid(),
                ExternalId   = Guid.NewGuid().ToString(),
                EventDate    = WorkflowClock.Now(),
                CreationDate = WorkflowClock.Now(),
            };

            processor.EvaluateEvent(ev);
            var wrk = storage.GetAll <Workflow>().FirstOrDefault(c => c.ExternalId == ev.ExternalId);

            var act = wrk.LastEvent.Actions;

            act.First(c => c.Name == "act_on_state_in_1");
            act.First(c => c.Name == "act_on_state_out");
            act.First(c => c.Name == "act_on_event");
            act.First(c => c.Name == "act_on_transition");
        }