示例#1
0
        public async Task ExecuteRule_SpecialCharInWorkflowName_RunsSuccessfully()
        {
            var workflow = new WorkflowRules {
                WorkflowName = "Exámple",
                Rules        = new Rule[] {
                    new Rule {
                        RuleName = "RuleWithLocalParam",

                        RuleExpressionType = RuleExpressionType.LambdaExpression,
                        Expression         = "input1 == null || input1.hello.world = \"wow\""
                    }
                }
            };

            var workflowStr = "{\"WorkflowName\":\"Exámple\",\"WorkflowRulesToInject\":null,\"GlobalParams\":null,\"Rules\":[{\"RuleName\":\"RuleWithLocalParam\",\"Properties\":null,\"Operator\":null,\"ErrorMessage\":null,\"Enabled\":true,\"ErrorType\":\"Warning\",\"RuleExpressionType\":\"LambdaExpression\",\"WorkflowRulesToInject\":null,\"Rules\":null,\"LocalParams\":null,\"Expression\":\"input1 == null || input1.hello.world = \\\"wow\\\"\",\"Actions\":null,\"SuccessEvent\":null}]}";

            var re = new RulesEngine(new string[] { workflowStr }, null, null);
            // re.AddWorkflow(workflowStr);

            dynamic input1 = new ExpandoObject();

            input1.hello       = new ExpandoObject();
            input1.hello.world = "wow";

            List <RuleResultTree> result3 = await re.ExecuteAllRulesAsync("Exámple", input1);

            Assert.True(result3.All(c => c.IsSuccess));
        }
示例#2
0
        public async Task ExecuteRule_RuntimeError_IgnoreException_DoesNotReturnException()
        {
            var workflow = new WorkflowRules {
                WorkflowName = "TestWorkflow",
                Rules        = new[] {
                    new Rule {
                        RuleName   = "ruleWithRuntimeError",
                        Expression = "input1.Country.ToLower() == \"india\""
                    }
                }
            };

            var re = new RulesEngine(new[] { workflow }, null, new ReSettings {
                IgnoreException = true
            });
            var input = new RuleTestClass {
                Country = null
            };

            var result = await re.ExecuteAllRulesAsync("TestWorkflow", input);

            Assert.NotNull(result);
            Assert.All(result, rule => Assert.False(rule.IsSuccess));
            Assert.All(result, rule => Assert.Empty(rule.ExceptionMessage));
        }
示例#3
0
        public static RulesEngine.RulesEngine GetRulesEngine(List <ConfigRulesModel> list)
        {
            var data = new
            {
                WorkflowName = "inputWorkflow",
                Rules        = list.Select((t, i) => new
                {
                    RuleName           = (t.RuleName + i.ToString()),
                    Expression         = t.ShallowExpression,
                    SuccessEvent       = (t.Node + $"_{t.RuleType}"),
                    RuleExpressionType = t.RuleExpressionType,
                })
            }.ToJson();
            var injectWorkflow = new WorkflowRules
            {
                WorkflowName          = "inputWorkflowReference",
                WorkflowRulesToInject = new List <string> {
                    "inputWorkflow"
                }
            };
            var injectWorkflowStr = JsonConvert.SerializeObject(injectWorkflow);
            var mockLogger        = new Mock <ILogger>();

            return(new RulesEngine.RulesEngine(new string[] { data, injectWorkflowStr }, mockLogger.Object));
        }
示例#4
0
        public async Task ExecuteRule_AddOrUpdateWorkflow_ExecutesUpdatedRules(string previousWorkflowFile, string newWorkflowFile)
        {
            var re = GetRulesEngine(previousWorkflowFile);

            dynamic input1 = GetInput1();
            dynamic input2 = GetInput2();
            dynamic input3 = GetInput3();

            // Run previous rules.
            List <RuleResultTree> result1 = await re.ExecuteAllRulesAsync("inputWorkflow", input1, input2, input3);

            Assert.NotNull(result1);
            Assert.IsType <List <RuleResultTree> >(result1);
            Assert.Contains(result1, c => c.IsSuccess);

            // Fetch and update new rules.
            WorkflowRules newWorkflowRules = ParseAsWorkflowRules(newWorkflowFile);

            re.AddOrUpdateWorkflow(newWorkflowRules);

            // Run new rules.
            List <RuleResultTree> result2 = await re.ExecuteAllRulesAsync("inputWorkflow", input1, input2, input3);

            Assert.NotNull(result2);
            Assert.IsType <List <RuleResultTree> >(result2);
            Assert.DoesNotContain(result2, c => c.IsSuccess);

            // New execution should have different result than previous execution.
            var previousResults = result1.Select(c => new { c.Rule.RuleName, c.IsSuccess });
            var newResults      = result2.Select(c => new { c.Rule.RuleName, c.IsSuccess });

            Assert.NotEqual(previousResults, newResults);
        }
示例#5
0
        public async Task ClearWorkFlow_ShouldRemoveAllCompiledCache()
        {
            var workflow = new WorkflowRules {
                WorkflowName = "Test",
                Rules        = new Rule[] {
                    new Rule {
                        RuleName    = "RuleWithLocalParam",
                        LocalParams = new LocalParam[] {
                            new LocalParam {
                                Name       = "lp1",
                                Expression = "true"
                            }
                        },
                        RuleExpressionType = RuleExpressionType.LambdaExpression,
                        Expression         = "lp1 ==  true"
                    }
                }
            };

            var re = new RulesEngine();

            re.AddWorkflow(workflow);

            var result1 = await re.ExecuteAllRulesAsync("Test", "hello");

            Assert.True(result1.All(c => c.IsSuccess));

            re.ClearWorkflows();
            workflow.Rules.First().LocalParams.First().Expression = "false";

            re.AddWorkflow(workflow);
            var result2 = await re.ExecuteAllRulesAsync("Test", "hello");

            Assert.True(result2.All(c => c.IsSuccess == false));
        }
        public void RulesEngine_New_IncorrectJSON_ThrowsException()
        {
            Assert.Throws<RuleValidationException>(() =>
            {
                var workflow = new WorkflowRules();
                var re = CreateRulesEngine(workflow);
            });

            Assert.Throws<RuleValidationException>(() =>
            {
                var workflow = new WorkflowRules() { WorkflowName = "test" };
                var re = CreateRulesEngine(workflow);
            });
        }
示例#7
0
        private WorkflowRules[] GetWorkflowRulesWithoutActions()
        {
            var workflow1 = new WorkflowRules {
                WorkflowName = "NoActionWorkflow",
                Rules        = new List <Rule> {
                    new Rule {
                        RuleName           = "NoActionTest",
                        RuleExpressionType = RuleExpressionType.LambdaExpression,
                        Expression         = "1 == 1",
                    }
                }
            };

            return(new [] { workflow1 });
        }
        private RulesEngine GetRulesEngine(string filename, ReSettings reSettings = null)
        {
            var filePath = Path.Combine(Directory.GetCurrentDirectory() as string, "TestData", filename);
            var data = File.ReadAllText(filePath);

            var injectWorkflow = new WorkflowRules
            {
                WorkflowName = "inputWorkflowReference",
                WorkflowRulesToInject = new List<string> { "inputWorkflow" }
            };

            var injectWorkflowStr = JsonConvert.SerializeObject(injectWorkflow);
            var mockLogger = new Mock<ILogger>();
            return new RulesEngine(new string[] { data, injectWorkflowStr }, mockLogger.Object, reSettings);
        }
示例#9
0
        private RulesEngine GetRulesEngine(string filename, ReSettings reSettings = null)
        {
            var data = GetFileContent(filename);

            var injectWorkflow = new WorkflowRules {
                WorkflowName          = "inputWorkflowReference",
                WorkflowRulesToInject = new List <string> {
                    "inputWorkflow"
                }
            };

            var injectWorkflowStr = JsonConvert.SerializeObject(injectWorkflow);
            var mockLogger        = new Mock <ILogger>();

            return(new RulesEngine(new string[] { data, injectWorkflowStr }, mockLogger.Object, reSettings));
        }
示例#10
0
        /// <summary>
        /// 批量执行工作集
        /// </summary>
        /// <param name="workflowRules"></param>
        /// <returns></returns>
        public IList <RuleResult> Execute(WorkflowRules workflowRules)
        {
            if (workflowRules.Rules == null || workflowRules.RuleInputs == null)
            {
                throw new ArgumentNullException("规则集或数据集不能为 null");
            }
            if (workflowRules.Rules.Count != workflowRules.RuleInputs.Count)
            {
                throw new ArgumentOutOfRangeException($"规则集与数据集数量不一致:{workflowRules.Rules.Count}!={workflowRules.RuleInputs.Count}");
            }
            int length = workflowRules.Rules.Count;

            for (int i = 0; i < length; i++)
            {
                workflowRules.RuleResults.Add(Execute(workflowRules.Rules[i], workflowRules.RuleInputs[i]));
            }
            return(workflowRules.RuleResults);
        }
示例#11
0
        public async Task ExecuteRule_RuntimeError_ThrowsException()
        {
            var workflow = new WorkflowRules {
                WorkflowName = "TestWorkflow",
                Rules        = new[] {
                    new Rule {
                        RuleName   = "ruleWithRuntimeError",
                        Expression = "input1.Country.ToLower() == \"india\""
                    }
                }
            };

            var re = new RulesEngine(new[] { workflow }, null, new ReSettings {
                EnableExceptionAsErrorMessage = false
            });
            var input = new RuleTestClass {
                Country = null
            };

            _ = await Assert.ThrowsAsync <RuleException>(async() => await re.ExecuteAllRulesAsync("TestWorkflow", input));
        }
示例#12
0
        public async Task ExecuteRule_RuntimeError_ShouldReturnAsErrorMessage()
        {
            var workflow = new WorkflowRules {
                WorkflowName = "TestWorkflow",
                Rules        = new[] {
                    new Rule {
                        RuleName   = "ruleWithRuntimeError",
                        Expression = "input1.Country.ToLower() == \"india\""
                    }
                }
            };

            var re    = new RulesEngine(new[] { workflow }, null, null);
            var input = new RuleTestClass {
                Country = null
            };

            var result = await re.ExecuteAllRulesAsync("TestWorkflow", input);

            Assert.NotNull(result);
            Assert.All(result, rule => Assert.False(rule.IsSuccess));
            Assert.All(result, rule => Assert.StartsWith("Error while executing rule :", rule.ExceptionMessage));
        }
示例#13
0
        private WorkflowRules[] GetWorkflowWithActions()
        {
            var workflow1 = new WorkflowRules {
                WorkflowName = "ActionWorkflow",
                Rules        = new List <Rule> {
                    new Rule {
                        RuleName           = "ExpressionOutputRuleTest",
                        RuleExpressionType = RuleExpressionType.LambdaExpression,
                        Expression         = "1 == 1",
                        Actions            = new Dictionary <ActionTriggerType, ActionInfo> {
                            { ActionTriggerType.onSuccess, new ActionInfo {
                                  Name    = "OutputExpression",
                                  Context = new Dictionary <string, object> {
                                      { "expression", "2*2" }
                                  }
                              } }
                        }
                    },
                    new Rule {
                        RuleName           = "EvaluateRuleTest",
                        RuleExpressionType = RuleExpressionType.LambdaExpression,
                        Expression         = "1 == 1",
                        Actions            = new Dictionary <ActionTriggerType, ActionInfo> {
                            { ActionTriggerType.onSuccess, new ActionInfo {
                                  Name    = "EvaluateRule",
                                  Context = new Dictionary <string, object> {
                                      { "workflowName", "ActionWorkflow" },
                                      { "ruleName", "ExpressionOutputRuleTest" }
                                  }
                              } }
                        }
                    }
                }
            };

            return(new [] { workflow1 });
        }
示例#14
0
        /// <summary>
        /// Lamda 表达式工作流的股票购买
        /// </summary>
        public static void LambdaStockWorkFlowTest()
        {
            var rand = new Random();

            var workflow = new WorkflowRules()
            {
                RuleInputs = new List <IDictionary <string, object> >(defaultCount),
                Rules      = new List <Rule>(defaultCount)
            };

            for (int i = 0; i < defaultCount; i++)
            {
                var rule = new Rule()
                {
                    RuleExpressionType = RuleExpressionType.Lambda,
                    RuleExpression     = $"price < expectPrice",
                    FaildMessage       = "股价报价为:#(price)#,预期价位为:#(expectPrice)#,股价不匹配,取消购买",
                    SucessMessage      = "股价报价为:#(price)#,预期价位为:#(expectPrice)#, 当前余额:#(totalMoney)#,可买入,购买系数:#rate#(余额的比例),买入数量:#(Math.round(totalMoney*rate/price))#,买入后余额:#(totalMoney-Math.round(totalMoney*rate/price)*price)#",
                    RuleName           = "判断股价,价格匹配就买入",
                };
                var dct = new Dictionary <string, object>();
                dct["price"]       = rand.Next(1, 100);
                dct["rate"]        = rand.NextDouble();
                dct["expectPrice"] = rand.Next(1, 100);
                dct["totalMoney"]  = rand.Next(1, 100) * rand.Next(2, 200);
                workflow.Rules.Add(rule);
                workflow.RuleInputs.Add(dct);
            }
            // 执行
            var resultList = ruleEngine.Execute(workflow);

            if (saveTestData)
            {
                File.WriteAllText($"{resultDataDir}{MethodBase.GetCurrentMethod().Name}.txt", JsonConvert.SerializeObject(resultList));
            }
        }
示例#15
0
        public async Task ExecuteRule_WithNullInput_ShouldNotThrowException()
        {
            var workflow = new WorkflowRules {
                WorkflowName = "Test",
                Rules        = new Rule[] {
                    new Rule {
                        RuleName = "RuleWithLocalParam",

                        RuleExpressionType = RuleExpressionType.LambdaExpression,
                        Expression         = "input1 == null || input1.hello.world = \"wow\""
                    }
                }
            };

            var re = new RulesEngine();

            re.AddWorkflow(workflow);

            var result1 = await re.ExecuteAllRulesAsync("Test", new RuleParameter("input1", value : null));

            Assert.True(result1.All(c => c.IsSuccess));


            var result2 = await re.ExecuteAllRulesAsync("Test", new object[] { null });

            Assert.True(result2.All(c => c.IsSuccess));

            dynamic input1 = new ExpandoObject();

            input1.hello       = new ExpandoObject();
            input1.hello.world = "wow";

            List <RuleResultTree> result3 = await re.ExecuteAllRulesAsync("Test", input1);

            Assert.True(result3.All(c => c.IsSuccess));
        }
        private RulesEngine CreateRulesEngine(WorkflowRules workflow)
        {
            var json = JsonConvert.SerializeObject(workflow);

            return(new RulesEngine(new string[] { json }, null));
        }
 public bool HasResolved()
 {
     return(Handled && WorkflowRules?.Any() == true);
 }
示例#18
0
 public void AddOrUpdateWorkflowRules(string workflowName, WorkflowRules rules)
 {
     _workflowRules.AddOrUpdate(workflowName, rules, (k, v) => rules);
 }
        public Task <IEnumerable <WorkflowRules> > GetRulesAsync(Type inputType, CancellationToken cancellationToken = default)
        {
            IEnumerable <WorkflowRules> rules = new WorkflowRules[0];

            return(Task.FromResult(rules));
        }