how to know the rules which are using a particular attribute - 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.

Related

how to stop looping in drools rule?

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).

Where can I see if a pattern failed in rule?

I run a rule that contains a few patterns, I want to know which pattern failed:
I've tried to debug the code (drools 7.18.0), and didn't found the relevant place.
rule example:
rule "Trigger"
agenda-group "Trigger"
salience 100
when
$pcase : PCaseMgr()
D1($id: id, type != null, type == "AAA")
D2(aId == $id)
then
$pcase.printAnalyticsRuleLog(">>>>>>>>>>>>>>>>>>> In Trigger");
end
in the example above, if D1 pattern is passed, and D2 pattern is failed, where in the code (of drools 7.18.0) can i see if the pattern was failed?
You can't. Because of the algorithm Drools uses internally, patterns are decomposed into nodes and nodes can be shared among multiple rules in your knowledge base. If you really need to know why a rule was not fire, then you can create other rules that will tell you that. In your example, you could create something like this:
rule "No Trigger because of No D2"
agenda-group "Trigger"
salience 100
when
$pcase : PCaseMgr()
D1($id: id, type != null, type == "AAA")
not D2(aId == $id)
then
$pcase.printAnalyticsRuleLog(">>>>>>>>>>>>>>>>>>> No Trigger because no D2");
end
Hope it helps,

Drools trigger one rule per item in list input for StatelessKieSession

I am using decision tables and would like to trigger one rule per input item.
I am using decision have set the Sequential = true and defined all rules as part of the same ACTIVATION-GROUP.
When I trigger the drools rules engine using below it just evaluates for the first input item and others are ignored. The behavior I want is to evaluate at most 1 rule per input item (rule order defined by the Salience).
kieStatelessSession.execute(inputList)
I can get this working by sending one item at a time to the kieStatelessSession, but would prefer to execute all at once.
I am using Drools verison 6.5.0.FINAL and Java 7.
There is no out of the box support in Drools for what you are trying to achieve. If you want your rules to be evaluated once for each fact, you will need to code it yourself.
One approach could be to have another type of facts to mark when one of the inputs is processed:
declare Marker
fact : Object
end
//Bellow are the rules that should be coming from your decision table.
//Each rule will do whatever it needs to do, and then it will create a
//Marker fact for the fact that was processed.
//These rules now include a "not" Conditional Element to avoid a fact to be
//evaluated more than once.
rule "Rule 1"
salience 100
when
$fact: Object(...) //your conditions
not Marker(fact == $fact)
then
//... Your logic
insert(new Marker($fact));
end
...
rule "Rule 50"
salience 50
when
$fact: Object(...) //your conditions
not Marker(fact == $fact)
then
//... Your logic
insert(new Marker($fact));
end
Hope it helps,

Drools always return null

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

Why doesn't rule 1 consequence effect behavior of rule 2?

As an exercise in teaching myself drools I'm working on rules for bidding in the bridge card game. The rules work independently of each other (enforced by use of drools.halt() in the rules) but when I try to extend the example by removing the halt() calls, I get behavior I didn't expect. In the example below I am commenting out the halt() in the first rule, and adding the size() condition to the 2nd rule to replace it, trying to prevent the 2nd rule from firing. I would not expect the 2nd rule to fire because the consequence of the first rule added a bid to the Auction's collection, and so subsequently in rule 2 the count should not be zero. I've tried explicitly adding the 'update' or 'modify' directives in the first rule, but that didn't make any difference.
rule "rule1"
salience 100
when
$auction : Auction( $currentBidder : currentBidder != null )
$hand : Hand( owner.equals($currentBidder), getTotalPoints(getLongestSuit()) >= 13 )
then
$auction.bid($currentBidder, new Bid(1, $hand.getLongestSuit()));
//drools.halt();
end
rule "rule2"
salience 1
when
$auction : Auction( $currentBidder : currentBidder != null, getPlayerBids().size() == 0 )
Hand(owner.equals($currentBidder))
then
$auction.bid($currentBidder, new Pass());
drools.halt();
end
When you change an object, you need to tell the engine you updated it. So try adding update($action); at the end of the first rule.