Drools, RuleTable and #Watch annotation - drools

I have now run out of ideas on how to get a RuleTable in Excel to define the #Watch annotation.
All the Drools documentation shows you how to define the #Watch with individual files, but no mention on how to add this to RuleTables.
My RuleTable is generating 100% at the moment and works fine for a primitive test case, but I need to have the #Watch on a more complex rule.
When I use the test compiler, I can edit the .drl files by hand and upload them to the engine. My rules are firing correctly then.
Some help on how to define this in Excel will be greatly appreciated.
This is the current Excel RuleTable I have defined:
This is the target .drl I'm aiming for(I have left out the other two rules generated):
rule "TestWatch One"
no-loop
when
$payCommResponseDTO: PaymentCommissionResponseDTO(commissionStructure == CommissionStructure.ADJUSTED) #Watch(commissionStructure)
then
System.out.println("watch one");
end

Related

CodeEffects Rule Engine. How to use + operator in evaluation rules

We are doing POC on business rules using CodeEffects rule engine. Trying to write evaluation rules using rule editor. Here question is how to use + operator between custom functions to evaluate specific rule. For example, I would like to write rule like below
check if(somefunc(somevar1)+somefunc(somevar2)+somefun(somevar3) is greater than [1]
Please help how to write such rule in editor.
You need to use the calculation option (the "Add calculation..." menu item) as the value of your condition. Keep in mind that in Code Effects each condition must begin with either a field or an in-rule method. Because of that, your rule needs to be changed as follows:
Check if Somefunc(Somevar1) is greater than
{ Somefunc(Somevar2) + Somefunc(Somevar3) - [1] }
Notice that the result of the evaluation is still the same, I just moved some rule elements around.

Drools does not match my fact

I am new to drools and have defined two rules :
package com.mgaudin.sandbox.drools.rules;
import com.mgaudin.sandbox.drools.models.Lead;
rule "rule1"
when
l: Object()
then
System.out.println(l.getClass().getCanonicalName());
end
And
package com.mgaudin.sandbox.drools.rules;
import com.mgaudin.sandbox.drools.models.Lead;
rule "rule2"
when
Lead()
then
System.out.println("It's a match !");
end
When I insert a new com.mgaudin.sandbox.drools.models.Lead fact, the output is the following :
com.mgaudin.sandbox.drools.models.Lead
Therefore we can deduce that :
The rules compiles properly
The rules are executed
The first rule matches with a fact of type "com.mgaudin.sandbox.drools.models.Lead"
So why is the rule "rule2" not matching ?
Thanks !
OK I found the answer and it's not related to Drools, it's related to Spring-boot-devtools !
I don't know the exact mechanism but to enable fast hot reload (even if a method signature changes), spring-boot-devtools must mess with the JVM and proxify some objects, in my case, the fact. Because of this and the way Drools matches fact, the rule did not triggered.
All I had to do was remove the maven dependency to spring-boot-devtools.
Rules are not matching since your fact (Lead) is loaded with different ClassLoader so Drools don't see it. This is done by devtools as described here:
https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#using-spring-boot-restart-vs-reload
But it's not necessary to disable devtools, just add the following lines to META-INF/spring-devtools.properties as was hinted here:
restart.include.drools=/drools-[\\s\\S]+\.jar
restart.include.kie=/kie-[\\s\\S]+\.jar
So Drools is loaded with Restart Classloader - the same as your Classes.
I had a problem that inserted facts are never recognized inside rules, but had no problem with globals.
Removing
spring-boot-devtools
dependency made my life easier.

Drools Ruleflow from different drl files

I'm trying to make a drools flow out of different .drl files in order to have a clear rule flow for my project , however the example in the documentation is very simple and has no indication for this ..
Does anyone know how it's done ?? (linking Droolsflow to drl files in order to make the knowledge base and execute the rules ? (I added "ruleflow-group" to the rule in the .drl file but didn't know how to link it afterwards ) and if you know any useful links on this matter , I'd be grateful if you share ^^

Modify a drools rule to set rule attributes programmatically

I see classes like org.drools.lang.api.PackageDescrBuilder and org.drools.lang.api.impl.RuleDescrBuilderImpl to create rules programmatically, but I don't see any examples of that.
Basically user will create a rule and upload the file to a location. I have read these rule files and set rule attributes like date-effective, date-expires, enabled etc.
As per org.drools.rule.Rule api, there are methods to set, but I don't get any idea on how to read the rule.drl file and convert it to object of type org.drools.rule.Rule.
Any idea on this or how to modify a drools rule using drools api will be useful.
Note: I don't want to do string replacement for modifying a rule.
You could take a look at the tests for the PackageBuilder:
https://github.com/droolsjbpm/drools/blob/5.6.x/drools-compiler/src/test/java/org/drools/compiler/PackageBuilderTest.java
... which has examples of doing this.

Drools for test case formulation

I am testing a rather complex system, which behaves according to some business rules (written as semi-formal text).
The goal is to create test cases, which cover as many states of the system as possible. I want to automate this task in the following way:
1) Formalize the business rules in Drools
2) Then use some mechanism to create a list of all possible situations (which need to be tested)
For example, I have following business rule package with two rules (this is only an example, real business rules are much more complex):
global List outErrorCodes;
global Boolean condition1;
global Boolean condition2;
global Boolean condition3;
rule "01"
when
eval( condition3 == false);
then
outErrorCodes.add("ERROR_CODE1");
end
rule "02"
when
eval((condition1 == true) && (condition2 == true));
then
outErrorCodes.add("ERROR_CODE2");
end
condition1, condition2 and condition3 are inputs.
outErrorCode is the output.
That is, condition1, condition2 and condition3 describe a certain situation, and outErrorCode describes the expected behaviour of the system in that particular situation.
I want to create a mechanism, which automatically creates a list of all possible tuples (condition1, condition2, condition3, outErrorCodes), based on the logic in the rules. Each tuple represents a state of the system.
These tuples will then be used as a basis for creating actual test cases.
Is it possible with Drools? If so - how?
Many thanks in advance
Dmitri
We had success in taking the ruleset, deploying it as a service using drools-server, and then writing a script to make web service calls exercising each possible value of each input variable. Within about an hour we were able to make 5000+ calls to our rule base and see output for each case.
The downside (and I don't think you will get around this with any solution) is that you are testing business logic. When you think about it, you can generate all the test data you want, but you can't generate test input and an expected result without running the business logic (which you are testing). Just saying that if you get into auto generating input to business logic, you can't actually know the expected results without violating the integrity of the test.