Introduction
Microsoft Rules Engine doing fantastic job in handling and evaluating rules and its expressions. Big Thank to its Authors for the mind-blowing invention to tackle workflow based rules and its evaluation on the fly. I am just an beginner for this package and initially tried with some predefined workflow evaluation in azure function. I came across with some weird issue "Rule config file is not present". In this article I will drive you to solve this kind of problem
Predefined Discount Workflow for evaluation
I just followed samples provided in https://microsoft.github.io/RulesEngine/
[ { "WorkflowName": "Discount", "Rules": [ { "RuleName": "GiveDiscount10", "Expression": "input1.country == \"india\" AND input1.loyalityFactor <= 2 AND input1.totalPurchasesToDate >= 5000 AND input2.totalOrders > 2 AND input3.noOfVisitsPerMonth > 2" }, { "RuleName": "GiveDiscount20", "Expression": "input1.country == \"india\" AND input1.loyalityFactor == 3 AND input1.totalPurchasesToDate >= 10000 AND input2.totalOrders > 2 AND input3.noOfVisitsPerMonth > 2" } ] } ]
Issue Video
Code
using System; using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; using RulesEngine.Models; namespace EvaluateFunction { public static class Function1 { [FunctionName("Function1")] public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { bool result = false; try { string WorkflowName = req.Query["WorkflowName"]; string rulename = req.Query["rulename"]; var jsonRuleData = "[{\"WorkflowName\":\"Discount\",\"Rules\":[{\"RuleName\":\"GiveDiscount10\",\"Expression\":\"input1.country == \\\"india\\\" AND input1.loyalityFactor <= 2 AND input1.totalPurchasesToDate >= 5000 AND input2.totalOrders >2 AND input3.noOfVisitsPerMonth > 2\"},{\"RuleName\":\"GiveDiscount20\",\"Expression\":\"input1.country == \\\"india\\\" AND input1.loyalityFactor == 3 AND input1.totalPurchasesToDate >= 10000 AND input2.totalOrders > 2 AND input3.noOfVisitsPerMonth >2 \"}]}]"; var workflowData = JsonConvert.DeserializeObject<List<Workflow>>(jsonRuleData); if (workflowData != null && workflowData.Any()) { var data = workflowData.Where(x => x.WorkflowName.ToLowerInvariant() == WorkflowName.ToLowerInvariant()).FirstOrDefault(); if (data != null) { var rules = data.Rules.Where(x => x.RuleName.ToLowerInvariant() == rulename.ToLowerInvariant()); if (rules != null && rules.Any()) { var re = new RulesEngine.RulesEngine(workflowData.ToArray()); dynamic input1 = new { country = "india", loyalityFactor = 1, totalPurchasesToDate = 5002 }; dynamic input2 = new { totalOrders = 3 }; dynamic input3 = new { noOfVisitsPerMonth = 3 }; var rp1 = new RuleParameter("input1", input1); var rp2 = new RuleParameter("input2", input2); var rp3 = new RuleParameter("input3", input3); var resultList = await re.ExecuteAllRulesAsync(WorkflowName, rp1, rp2, rp3); if (resultList != null && resultList.Any()) { var finalResult = resultList.Where(x => x.Rule.RuleName.ToLowerInvariant() == rulename.ToLowerInvariant()).FirstOrDefault().IsSuccess; result = finalResult; } } } } } catch (Exception e) { throw e; } return new OkObjectResult(result); } } }
Code Walkthrough - Http Trigger Azure Function
For this article I have only predefined set of rules and we are evaluating that with fixed rules parameter values. Let's walkthrough the code
Get Query string values - Http Get Request
Let's assume that our HTTP Get Request is having two query string parameters
- WorkflowName
- RuleName
Get those query string values HttpRequest Objects
Convert Json Into C# Json string
To Evaluate predefined values we need to convert Discount workflow Json into C# Json string, we will get something like this
var jsonRuleData = "[{\"WorkflowName\":\"Discount\",\"Rules\":[{\"RuleName\":\"GiveDiscount10\",\"Expression\":\"input1.country == \\\"india\\\" AND input1.loyalityFactor <= 2 AND input1.totalPurchasesToDate >= 5000 AND input2.totalOrders >2 AND input3.noOfVisitsPerMonth > 2\"},{\"RuleName\":\"GiveDiscount20\",\"Expression\":\"input1.country == \\\"india\\\" AND input1.loyalityFactor == 3 AND input1.totalPurchasesToDate >= 10000 AND input2.totalOrders > 2 AND input3.noOfVisitsPerMonth >2 \"}]}]";
Deserialize Json string to WorkFlow List Object
Microsoft Rules Engine is built with some sophisticated inbuit models. Let's try to deserialize json
string Workflow list object
Construct Rules Engine Object
After doing all our serialization and deserilaization process. Let's try to instantiate our RulesEngine Object with workflow array list.
Predefined Rules Parameter
Let's construct rules parameter based on discount workflow rules expressions. These expressions have three primary fields
- input1
- input2
- input3
These primary fields will have their own subordinate or secondary expression fields.
input1 rule parameter has following fields
- country
- loyalityFactor
- totalPurchasesToDate
input2 rule parameter has the following
- totalOrders
input3 rule parameter has the following
- noOfVisitsPerMonth
Execute Discount Workflow Rules
Let's execute RulesEngine object with ExecuteAllRulesAsync method primarily carries workflow array object and input rule parameter to evaluate all rules and its expression and will return RuleResultTree list object
var resultList = await re.ExecuteAllRulesAsync(WorkflowName, rp1, rp2, rp3);
Issue Root Cause
I Initially found that Rules engine is case sensitive. Discount workflow name is having Pascal case but I provided the value which is in the form of camel case. Expected workflow name value is Discount but provided discount as workflow name. That's why we got the issue "Rule config file is not present" not present.
Solution
We should provide exact Workflow or rulename as provided in Config file in our case json string will fix the issue.
Conclusion
I provided the proper workflow name and then rules engine evaluated and its provided the result as expected. Hope this article is helpful to you.
Comments
Post a Comment