ankita gupta
ankita gupta

Reputation: 203

Drool returning lowest salience rule

I am running into issue of multiple rules matched and getting rule with lowest Salience. This is the Source File.

package HotelAnalyticsLuxuryPromotions 
#generated from Decision Table
import com.mmt.analytics.hotel.promotions.drools.HotelPromotionsDroolsPojo;
import com.mmt.analytics.hotel.promotions.drools.HotelPromotionsDroolRules;
#From row number: 11
rule "for Luxury Hotel Promotions_11"
    salience 9
    when
        fact: HotelPromotionsDroolsPojo(
  eval(HotelPromotionsDroolRules.checkHotelId(fact,"12345")),
  eval(HotelPromotionsDroolRules.checkRsq(fact,"*")),
  eval(HotelPromotionsDroolRules.checkValidCheckInCheckOut(fact,"*")), 
  eval(HotelPromotionsDroolRules.checkLoggedStatus(fact,"*")))
        eval(HotelPromotionsDroolRules.checkActiveStatus(fact,"1"))
    then
        fact.setPackageName("Pack 2");
        fact.setRatePlanCode("ABC 2");
        fact.setTariffUrl("TariffUrl");
        fact.setClickUrl("ClickUrl");
        fact.setInclusionText("InclusionText");
end

#From row number: 12
rule "for Luxury Hotel Promotions_12"
    salience 10
    when
        fact: HotelPromotionsDroolsPojo(
  eval(HotelPromotionsDroolRules.checkHotelId(fact,"12345")), 
  eval(HotelPromotionsDroolRules.checkRsq(fact,"*")), 
  eval(HotelPromotionsDroolRules.checkValidCheckInCheckOut(fact,"*")), 
  eval(HotelPromotionsDroolRules.checkLoggedStatus(fact,"*")))
        eval(HotelPromotionsDroolRules.checkActiveStatus(fact,"1"))
    then
        fact.setPackageName("Pack 1");
        fact.setRatePlanCode("ABC 1");
        fact.setTariffUrl("TariffUrl");
        fact.setClickUrl("ClickUrl");
        fact.setInclusionText("InclusionText");
end

#From row number: 14
rule "for Luxury Hotel Promotions_14"
    salience 5
    when
        fact:HotelPromotionsDroolsPojo(
  eval(HotelPromotionsDroolRules.checkHotelId(fact,"12345")), 
  eval(HotelPromotionsDroolRules.checkRsq(fact,"*")), 
  eval(HotelPromotionsDroolRules.checkValidCheckInCheckOut(fact,"*")), 
  eval(HotelPromotionsDroolRules.checkLoggedStatus(fact,"*")))
        eval(HotelPromotionsDroolRules.checkActiveStatus(fact,"1"))
    then
        fact.setPackageName("Pack 3");
        fact.setRatePlanCode("ABC 3");
        fact.setTariffUrl("TariffUrl");
        fact.setClickUrl("ClickUrl");
        fact.setInclusionText("InclusionText");
end

I think rule with highest priority must be returned but I am getting the opposite.

Below is the code of rule Engine

   StatelessKnowledgeSession kSession = promotionsDroolManager.getStatelessSession();
        kSession.execute(droolsPojo);

I am using these Drool Config Properties

promotions.drools.agent.scan.resources=true
promotions.drools.agent.scan.directories=true
promotions.drools.resource.scanner.interval=1800
promotions.drools.agent.monitor.change.set.events=true
promotions.drools.knowledge.agent.name=Promotions_Knowledge_agent
promotions.drools.base.knowledge.agent.change.set.path=promotions.xml

Pls. suggest

Upvotes: 0

Views: 1729

Answers (3)

laune
laune

Reputation: 31290

You have three rules with identical left hand sides (conditions). If one matches, they all match. If one fires, they all fire. They fire in an order which you control using salience.

The right hand sides (consequences) are very much alike, values in the identical setters differ. If they all fire, the values in the last group of setters are bound to appear in the matched fact.

This is the group of setters in the rule with lowest salience.

Edit 1. Above all: Why are the conditions identical? It doesn't make sense. 2. Esteban's Proposal is an option. 3. If you don't want to fire more than one rule, call fireAllRules(1). 4. Add a constraint testing that one of the fields (e.g. packageName) is still null. You'll need to call modify or update:

when
   fact:HotelPromotionsDroolsPojo(packageName == null,
   ...
then
    fact.setPackageName("...");
    ...
    update( fact );

Upvotes: 1

Esteban Aliverti
Esteban Aliverti

Reputation: 6322

As Laune mentioned, the salience only determines the order in which the consequences of the rules are executed. In your case, given that the LHS (left hand side) of all your rules is the same, when 1 rule is activated, all of them are. Then, Drools will execute the RHS of these rules in the order given by the salience of each of the rules. The rule with higher salience will be executed first. That is the reason why you see as if the rule with lower salience was the only one being executed. This rule is basically overwriting what the other 2 rules have done.

In your case, I would say that what you need is to set the activation-group attribute of your rules. From Drools documentation:

Rules that belong to the same activation-group, identified by this attribute's string value, will only fire exclusively. More precisely, the first rule in an activation-group to fire will cancel all pending activations of all rules in the group, i.e., stop them from firing.

So, put all of your 'exclusive' rules in the same activation-group so when the first activation (with highest salience) is executed, the other activations will be cancelled.

Hope it helps,

Upvotes: 1

jomarko
jomarko

Reputation: 267

If you are using kie workbench for modeling rules, you can add salience attribute column like shown below. This will ensure that the last rule in your table has the most priority.

salience column

Upvotes: 1

Related Questions