Drools/ Kogito Dynamic runtime flow/ process - drools

I'm new to drools (I can consider Kogito as well) we have a requirements where the rules with orders are stored in a decision table and it should be executed based on the order given by the users the rules order could change at anytime. Please keep in mind that the response(output) from any rules is the input for the next one. is there anyway to achieve this?
example:
Rules
rank
rule 1
1
rule 2
2
order might change to:
Rules
rank
rule 1
2
rule 2
1

Related

How to dynamically select drools rules for execution at business rule task level?

I've few drools rules that I want to use in different rule flows. Since, Drools rule supports only one ruleflow-group name at a time and rule flow business rule task also can be mapped with single ruleflow-group, I'm not able to use same rule in different rule flows. Is there any other way that I can use to filter the rules? like using tags or and metadata?
You could create your own rule groups. You create a class OwnRuleGroup with String group in it as a field. Then when you fire rules you create an instance of your own rule grup:
OwnRuleGroup myGroup = new OwnRuleGroup();
myGroup.group = "foo";
and insert it into session with other facts. In every rule you could specify which of the groups you want to fire.
rule "This will fire for groups foo,bar"
when
OwnRuleGroup(group in ["foo", "bar"])

TSQL list of business rules in MDS

I need help with querying my business rules in SQL!
I have created couple of business rules in MDS web service to validate my master data and found out that 2 % of my data is not complying with the rules. Now I have created a SQL subscription view to report on the invalid data in PowerBI. In my PowerBI report I need to tell the business user why the data is invalid but I cannot since the subscription view only tells where the data is invalid but not why the data is invalid. So I need to know how I might query my business rules from MDS database in SQL and map it with my PowerBI data model. Is there a way to query the list of business rules from MDS database?
OK, so there are multiple ways to go about this. Here are some solutions, pls choose one that suits your scenario.
1. SQL - List of all Business Rules
The following query will retrieve the list of all Active Business Rules created in MDS.
SELECT *
FROM [MDM].[mdm].[viw_SYSTEM_SCHEMA_BUSINESSRULES]
WHERE Model_Name = 'YourModelName'
AND BusinessRule_StatusName = 'Active'
You can, of course, further filter by Entity_Name, etc.
The important columns in your case are going to be:
[BusinessRule_Name]
[BusinessRule_Description]
[BusinessRule_RuleConditionText]
[BusinessRule_RuleActionText]
Note: The challenge in your scenario, I think, is going to be that the Subscription View of the entity does not have IDs of the exact Business Rules that failed. So I'm not sure how you'll tie these 2 together (failing Rows -> List of Business Rules). Also remember that each row may have more than 1 business rule that failed.
2. using View viw_SYSTEM_USER_VALIDATION
This is a view that has a historical list of all business rules (+row info) that failed. You may use the view in this way:
SELECT
DISTINCT ValidationIssue_ID, Version_ID, VersionName, Model_ID, ModelName, Entity_ID, EntityName, Hierarchy_ID, HierarchyName, Member_ID, MemberCode, MemberType_ID, MemberType, ConditionText, ActionText, BusinessRuleID, BusinessRuleName, PriorityRank, DateCreated, NotificationStatus_ID, NotificationStatus
FROM [MDM].[mdm].[viw_SYSTEM_USER_VALIDATION]
WHERE --CAST(DateCreated as DATE) = CAST(GETDATE() as DATE) AND
ModelName = 'YourModelName'
--AND EntityName IN ('Entity_1','Entity_2') -- Use this to Filter on specific Entities
Here, use the columns Model_ID, Entity_ID and Member_ID/MemberCode to identify the specific model, entity & row that failed.
Columns BusinessRuleName, ConditionText & ActionText will give your users additional info on the Business Rule that failed.
Note:
One issue with using this view is that even though, let's say, your failure condition was resolved the next day by the user, the view will still show that on a certain date, a validation had failed. (via column DateCreated).
Also note that the same failed data row will appear multiple times here if multiple Business Rules on the same row failed validation (there will be different BusinessRuleID/Name, etc). Just something to take note of.
Similarly, the same row may appear multiple times if it has failed again & again at different times. To workaround this, and if your final report can do with that, add a WHERE clause on the DateCreated column so that you only get to see any row that Failed today. The commented out line of code <--CAST(DateCreated as DATE) = CAST(GETDATE() as DATE) AND> does the same. If you can't use that, just make sure the data row are distinct. However, if you do this, remember that if something Failed yesterday (and is still in the Failed status), it may not show up.
My suggestion would be to use a slightly modified version of Solution #2:
Get the list of Failed Rows from your Subscription View (the data row's ValidationStatus is actually still 'Failed'), then JOIN with viw_SYSTEM_USER_VALIDATION making sure that you only select the row with MAX(DateCreated) value (of course for the same data row AND Business Rule).
Best of luck and if you find anything else while solving this issue, do share your learning here with all of us.
Lastly, if you found this useful, pls remember to Mark it as the Answer :)

Drools activation-group not work as expected

rule "one"
activation-group "Harris"
salience 10
when
$p : Person(age < 10);
then
$p.setDiscount(0.1);
end
rule "two"
activation-group "Harris"
salience 10
when
$p : Person(age > 10);
then
$p.setDiscount(0.2);
end
When I insert some Persons to working memory through KSession.insert(Object), only the first Person is evaluated, the other persons just ignored. My understanding about Drools activation-group is that if I have X number of rules that belong to the same activation-group with various salience values that each
Person will be processed by the rules and the one with the highest
salience will be fired and the rest will be ignored. Once that's
complete the next Person will come through and repeat the process. What
I'm experiencing is that the first Person to trigger any rule in that
activation-group will disable the entire activation group and no further
Persons will be processed.
Any suggestion?
"Only one rule within an activation group will fire, i.e., the first one to fire cancels any existing activations of other rules within the same group." This is pretty explicit.
Don't use an activation group if you want to do the same thing for many Person facts.
(a) Insert just one, fire all rules - repeat.
(b) Insert many persons, fire all rules but retract a Person fact in each consequence.
Salience is almost always bad. Use logic (constraints) for fine-grained control of the rule firing order.
activation-group will not work in your case. Insert and fireAlleules one by one shockingly that will work because it will fire up the rules considering the new updates in KnowledgeBase.(Not Recommended).
But i would suggest you to write up the unique rules to avoid activation-group. You can also try extending rules for more constructive.

Kie Server Guided Descision table rules not fired from REST API

I have a small project created on drools workbench deployed on a KIE server. Using the rest API I am able to insert facts, with rules appropriately fired. However the rules included in guided decision tables do not fire. Here is an example of a request I would send to the KIE server:
<batch-execution lookup="defaultKieSession">
<insert out-identifier="applicant" return-object="true" entry-point="DEFAULT">
<models.Applicant>
<timeEmployed>35</timeEmployed>
<employmentStatus>Contract</employmentStatus>
<violations>[]</violations>
</models.Applicant>
</insert>
<fire-all-rules/>
</batch-execution>
All rules that this data should trigger are fired, except for those included in the Decision table.
When I run a test scenario with the same data, all rules, including the decision table's rules, are fired correctly:
The problem seems to be related to the use of the REST API. Any ideas as to what I am doing wrong?
Here is the Table in question:
Violation simply calls a method that appends an error to the violations array.
Inside kmodule.xml I have.
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
Clarification
Just to be clear my requests fire rules from Guided DRLs, my issue is only with the rules in guided rules table. For example:
Given the rule:
If I send this request:
1994-04-15 11:03:44-0000
1970-01-13 16:19:41-0024
Contract
35
[]
This is a fragment of the response:
This data should also match the rule in the gdst however it is not fired.
While we can't see the condition operators in the table, my guess is the criteria doesn't meet any of the decision table rows/rules.
Mapping the input data to the decision table, we can see that:
Employment Status is Contract, so that matches row 1. In rows 3-11 it is ignored, so depends on the matching of the remaining columns.
Employment Duration is probably timeEmployed, and it does not match equality of any row. If the column operator is >, it matches rows 2-11. If it is <, then it matches row 1.
Job Category is ignored for rows 1 and 2, and has no apparent matching value in the input so rows 3-11 do not match.
Based on those:
3 says only rows 1 and 2 could match
1 says only row 1 could match of rows 1 and 2
2 is indeterminate based on what we see
My guess is row 1 is close but #2 doesn't match.

Firing particular rule by rule name in drools without using Agenda Filters

I read the rule file and add them into my knowledgeBase then I want to fire a particular rule in that knowledgeBase. Is this task possible in current drools version?
If you have a rule base where rules should be made active dynamically according to some criterion you have several choices.
Agenda filter. You say you don't want this, but why?
Put the alternative rules into agenda groups. Select the agenda group "group_3" prior to inserting the fact by a call to
kieSession.getAgenda().getAgendaGroup( "group_3" ).setFocus();
Write your rules to include a "selection" fact, e.g.
rule rule_3
when
Select( rule == "rule_3" )
Person( ... )
then ... end
The Select fact can be inserted along with the data fact but must be retracted after firing the rule.