In the below rules I expect Rule2 is fire because I am modifying customer name to mahesh. But when I execute Rule2 is not firing but Rule3 is firing. Am I missing anything here
rule "Rule1"
lock-on-active true
salience 95
when
$c:Customer($customerName:customerName)
then
System.out.println($customerName+" =======2========");
modify($c){
setCustomerName("mahesh");
}
System.out.println($customerName);
end
rule "Rule2"
lock-on-active true
salience 85
when
$c1:Customer($customerName:customerName=="mahesh");
then
System.out.println($customerName+" Rules Name is 1 - " + drools.getRule().getName());
$c1.setCustomerName("mahesh456");
update($c1);
end
rule "Rule3"
lock-on-active true
when
$c:Customer($customerName:customerName)
then
System.out.println($customerName+ "***** ");
end
What lock-on-active does is to prevent a rule to be activated if the agenda group where the rule is defined is already active.
In your case, because you was already executing the rules (fireAllRules) the MAIN agenda group (which is the group that both of your rules belong to) was already active. This mean that the second rule activation is going to be cancelled by Drools.
You can find here a more in depth explanation.
Hope it helps,
Related
Right now, in my drools project I have two groups of rules in separate DRL files which are split by agenda groups. For the agenda group "initial" I am setting auto focus to true for each rule in that agenda group.
rule "rule1"
agenda-group "initial"
auto-focus true
salience 50
when
// condition1
then
//
end
For the other agenda group - "final" - the rules do NOT have the auto focus attribute set. Example:
rule "rule2"
agenda-group "final"
activation-group "group1"
salience 0
when
// condition2
then
//
end
Below is the code snippet
val trigger(kieContainer: KieContainer) = {
val kieSession = kieContainer.newStatelessKieSession
val commands = new BatchExecutoinCommandImpl()
val agendaGroup = new AgendaGroupSetFocusCommand("initial")
val agendaGroup1 = new AgendaGroupSetFocusCommand("final")
executionCommand.addCommand(agendaGroup)
executionCommand.addCommand(agendaGroup1)
executionCommand.addCommand(CommandFactory.newInsert(customObject,
"obj"))
kieSession.execute(commands)
}
However, when the rules are executed, it seems like the rules in the "rule2" agenda group are being evaluated first. I have no idea why. I'm relatively new to drools, but I was sure this design would ensure the "rule1" rules would evaluate first.
I also had this "strange" behavior recently, but the Drools documentation explains that the agenda groups are managed with a stack:
Each time the setFocus() call is made in a Java application, the
Drools engine adds the specified agenda group to the top of the rule
stack
So with your current code, the "final" agenda group is given focus in first, since this is the last "AgendaGroupSetFocusCommand" you add in your command.
If you reverse the order of the "addCommand"s, you will have the expected behavior.
I am using guided rule in business central, Modiying the fact in action part with no-loop true .
Still the looping is happening .
when I use lock-on-active the rule do not run at all.
Please help.
rule "today true and close time is before 15pm"
dialect "mvel"
salience 120
ruleflow-group "gogo"
no-loop true
lock-on-active true
when
v : VendorWorkingDays( eval( vendorWD contains(java.time.LocalDate.now().plusDays(1).getDayOfWeek().toString()) )&& todayFlag == true && eval( closeTime.isBefore(java.time.LocalTime.parse("15:00:00")) ))
then
modify( v ) {
setTodayOneE( "NA" ),
setTodayOneM( "Available" ),
setTodayOneFlag( true )
}
System.out.println("today true and close time is before 15pm");
end
You may want to take a look at this other question: what is the difference between no-loop and lock-on-active in drools
In your case, the use of modify is causing the rules related to the VendorWorkingDays to be re-evaluated. The use of no-loop only works for when you have a single rule looping. I guess that in your case, you may have multiple rules involved in the infinite loop.
The use of lock-on-active will prevent the execution of this rule if the VendorWorkingDays is being inserted into the session (or modified) from another rule.
There is a link to a blog post in the question I mentioned that will give you a better explanation about these two attributes (the blog post is quite old, but the principles are still more or less valid for the latest version of Drools).
Say I have a rule file like below. Below rules are built on 2 properties Instrument and maverickModelMappingId. Can Drools tell me how many rules use the field "Instrument"? My use case is that I want to know if I am deleting an attribute or a field, how many rules and which rules are going to be affected.
package abc.modelMapping.ruleEngine;
dialect "java"
declare FRONTOFFICESYSTEM
Instrument : String
maverickModelMappingId : String
end
rule "rule_MurexCredit_Rule_3"
salience 3
no-loop true
when
$frontOfficeSystem : FRONTOFFICESYSTEM("Default swap".equalsIgnoreCase(Instrument))
then
$frontOfficeSystem.setMaverickModelMappingId("001282");
System.out.println("001282 "+"MurexCredit_Rule_3+");
end
rule "rule_MurexCredit_Rule_2"
salience 2
no-loop true
when
$frontOfficeSystem : FRONTOFFICESYSTEM("Euro credit index option".equalsIgnoreCase(Instrument))
then
$frontOfficeSystem.setMaverickModelMappingId("001283");
System.out.println("001283 "+"MurexCredit_Rule_2+");
end
rule "rule_MurexCredit_Rule_1"
salience 1
no-loop true
when
$frontOfficeSystem : FRONTOFFICESYSTEM("Credit index".equalsIgnoreCase(Instrument))
then
$frontOfficeSystem.setMaverickModelMappingId("001282");
System.out.println("001282 "+"MurexCredit_Rule_1+");
end
This is not possible with Drools, as of the current version (7.33.0.Final). As mentioned in the comments, the better solution will be to use your IDE's search tools -- or other find/grep solution -- to search the text of the rule file(s) for references to the given attribute or method.
relative new comer to drools and rules engines.
I have three rules that essentially check if different instances of the same object exist, if they don't, they create one and insert it into the working memory. After performing a series of other related rules, theres a rule that checks for validity of the models.
The goal here is to have three different instances of the same object that represent three different entities and proceed as long as 2 of them are in a valid state.
They're defined as follows:
rule "SetupA"
salience 80
lock-on-active
when
not InvalidModel(name == "A-Name")
then
InvalidModel invalidA = new InvalidModel();
invalidA.setName("A-Name");
insert(invalidA);
end
rule "SetupB"
salience 80
lock-on-active
when
not InvalidModel(name == "B-Name")
then
InvalidModel invalidB = new InvalidModel();
invalidB.setName("B-Name");
insert(invalidB);
end
rule "SetupC"
salience 80
lock-on-active
when
not InvalidModel(name == "C-Name")
then
InvalidModel invalidC = new InvalidModel();
invalidC.setName("C-Name");
insert(invalidC);
end
rule "VALIDATE_MODEL_FOR_ANY_INVALID_FLAGS"
salience -10
when
$invalidList: List(size > 1) from collect(InvalidModel(isNotFound || isFlagged || isNotActive))
then
setDecision(result, "Denied");
end
However, what's happening is that it seems like these rules are matched on every request to this ruleset which I interpret as the facts not existing in the Working Memory. I'd expect the rules to be fired once, when each of the facts for the respective names dont exist, and then to not fire again as there is nothing that would remove them from the working memory. However, my audit log of the rules that fire show that for every request those rules get fired.
Furthermore, the fourth rule's condition seems to not be performing as expected as it returns a response like such
=============== DEBUG MESSAGE: illegal bytecode sequence - method not verified ================
My ask is for some guidance on where my logic/drools language structure may have gone astray. Thanks for your time.
I have a .drl file generated from a rule xls:
#From row number: 19
rule "check_19"
salience 65517
activation-group "testCheck"
when
application : Application(eval( isApplicantType(applicantType, "SINGLE")))
applicant : Applicant(eval(isValid("18")))
then
result.add("false");
end
The drools fires without any errors but the result is always null. The activation group testCheck is set to XOR so I'm assuming either one of application or applicant must be true. Can someone explain to me the issue here? Thanks