Modify keyword not working Drools - drools

I am testing infinite loops using Modify keyword.
But it is not re triggering the rule.
Rule 1:
rule "Entitle for promotion"
when
$i: EmployeeFinancialFact(rating==Rating.ONE.getRating())
then
PromotionFact $promotion=new PromotionFact($i.getEmpID(),$i.getEmpName());
insert($promotion);
end
Rule 2:
rule "Print EmployeeFinancialFact name entitled for promotion"
when
$p: PromotionFact()
then
modify($p) {setSentForApproval(true);}
end
I am expecting RHS of rule 2 will re-trigger the rule 2 again but it is getting fired only once.
Can anyone please tell me the reason.

The first obvious question would be if you are sure your rules are indeed getting executed (sounds like a silly question, but it has solved many many issues here in SO).
Some other relevant questions are:
which version of Drools are you using?
Is PromotionFact a java class? or a defined declaration in your DRL?
Do you know if Property Reactive is enabled in your kbase? It used to be disabled in versions < 7, but since version 7 is enabled by default.
Hope it helps,

Disable property reactive in Kmodule.xml in Drools 7 by adding following lines:
<configuration>
<property key="drools.propertySpecific" value="ALLOWED"/>
</configuration>

Related

Drools, RuleTable and #Watch annotation

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

Using UIMA Ruta: How do I annotate the first token of a text and use that annotation further?

I would like to annotate the first token of a text and use that annotation in following rules. I have tried different patterns:
Token.begin == 0 (doesn't work, although there definitely is a token that begins at 0)
Token{STARTSWITH(DocumentMetaData)}; (also doesn't work)
The only pattern that works is:
Document{->MARKFIRST(First)};
But if I try to use that annotation e.g. in the following way:
First{->MARK(FirstAgain)};
it doesn't work again. This makes absolutely no sense to me. There seems to be a really weird behaviour with annotations that start at 0.
This trivial task can be a bit tricky indeed, mainly because of the visibility settings. I do not know why your rules in the question do not work without having a look at the text that should be processed.
As for UIMA Ruta 2.7.0, I prefer a rule like:
# Token{->First};
Here some additional thoughts about the rules in the question:
Token.begin == 0;
Normally, there is not token with begin at 0 since the document starts with some whitespaces or line breaks. If there is actually a token that starts at offset 0 and the rule does not match, then something invisible is covering the begin of the end of the token. This depends of course of the filtering settings, but in case that you did not change them, it could be a bom.
Token{STARTSWITH(DocumentMetaData)};
Here, either the problem above applies, or the begin offset is not identical. If the DocumentMetaData covers the complete document, then I would bet on the leading whitespaces. Another reason could be that the internal indexing is broken, e.g., the tokens or the DocumentMetaData are created by an external analysis engine which was called with EXEC and no reindexing was configured in the action. This situation could also occur with unfortunate optimizations using the config params.
Document{->MARKFIRST(First)};
First{->MARK(FirstAgain)};
MARKFIRST creates an annotation using the offset of the first RutaBasic in the matched context IIRC. If the document starts with something invisible, e.g., a line break, then the second rule cannot match.
As a general advice in situations like this when some obvious simple rules do not work correctly as expected, I recommend adding some additional rules and using the debugging config with the explanation view. As rule like Token; can directly highlight if the visibility setting are problematic for the given tokens.
DISCLAIMER: I am a developer of UIMA Ruta

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.

WF validation error at runtime

I have two workflow foundation (.NET 3.5 SP 1) application which compiles fine. It has two declarative rule conditions in it. Both are very simple, examples:
- !this.Shutdown
- this.Runtime == null
The project builds correctly without error or warning, however when I run the application it fails with the exception: error 1342: Activity 'whileNotShutdown' validation failed: Can not find the condition "Shutdown not requested".
In the other application I am using a more complex ruleset in policy which generates the following exception: error 1398: Activity 'Defaults' validation failed: Can not find the rule set "Rule Set1". Check if rule set is defined in the rules file.
I have tried removing the .rules file and recreating it by recreating the two rules and that did not help.
The question is: What is wrong that is causing this error?
Some things I have tried:
Placing the workflow rules in the larger workflow makes no difference to the issue.
The issue is effecting all workflows in the solution now (even those that used to work).
Using a code rule condition doesn't have the same problem - the issue is related to the rules file somehow.
Rebuilding workflow didn't help
Declarative workflow rules are not checked by the compiler so there is no help there. When you reference 'this' in rule it means the workflow. So your properties Shutdown and Runtime must be declared at the workflow level. I presume the Runtime refers to the WorkflowRuntime and that is kind of unusual, and not recommended, to have inside of your workflow so there may be a design issue here.
Eventually found the cause - it was caused by spaces in the class name, which causes the rules file to have spaces in it, which seems to cause the issue.
For example this will cause the error:
alt text http://img512.imageshack.us/img512/661/clipboard01wdu.png
However this will not:
alt text http://img140.imageshack.us/img140/9366/clipboard02t.png