Drools Drl activation group - Java @ Desk

Saturday, December 27, 2014

Drools Drl activation group

Drools Drl activation group

activation-group is a reserved keyword in drools drl file. There can be a single rule or multiple rules that can belong to a particular activation-group.

Rules that belong to activation-group fire in similar fashion to "if..else if..else" block in java. activation-group must contains set of those rules from which 1 and only 1 rule needs to be fired.

For example, a business requirement is
1) If age < 18, do X
2) If age > 20 && age < 32, do Y
3) If age > 32 && age < 48, do Z

or some more

1) If sale > 10,500 units && sale < 15,500 units, set commission = 5%
2) If sale > 15,500 units && sale < 25,500 units, set commission = 7.25%
3) If sale > 20,500 units && sale < 35,500 units, set commission = 9.5%

In both the cases, there is no need to fire all the three scenarios because 1 and only 1 input will fit in the given criteria.
The same thing in Java can be implemented using "if..else if..else".
Any rule fired within a activation-group will stop the other rules from getting fired.

Sample Code

DrlActivationGroup.drl
package com.sample
 
import com.sample.*;

rule "Platinum Customer"
lock-on-active true
activation-group "activation test"
salience 60
    when
     c : Customer()
 then
  c.setCustType("Platinum");
        System.out.println("Customer : " + c.getCustId() + " is a Platinum Customer");
end

rule "Gold Customer"
lock-on-active true
salience 50
activation-group "activation test"
    when
     c : Customer()
 then
  c.setCustType("Gold");
        System.out.println("Customer : " + c.getCustId() + " is a Gold Customer");
end




Java Standalone file to test the activation group
package com.sample;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;

public class DrlActivationGroup {
 public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KnowledgeBase kbase = readKnowledgeBase();
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
            KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
            
            Customer customer = new Customer();
   customer.setCustId("C1500564");
            
            ksession.insert(customer);
            
            ksession.fireAllRules();
            logger.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private static KnowledgeBase readKnowledgeBase() throws Exception {
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newClassPathResource("DrlActivationGroup.drl"), ResourceType.DRL);
        KnowledgeBuilderErrors errors = kbuilder.getErrors();
        if (errors.size() > 0) {
            for (KnowledgeBuilderError error: errors) {
                System.err.println(error);
            }
            throw new IllegalArgumentException("Could not parse knowledge.");
        }
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
        return kbase;
    }

}


Output

Run the above client file will generate this output
Customer : C1500564 is a Platinum Customer


As shown, since the salience of rule "Platinum Customer" is high, it gets fired and thus it stopped execution of the rule "Gold Customer" because it belongs to same activation group.
If the salience of rule "Platinum Customer" will be changed to value that is lesser than the salience rule "Gold Customer", then "Platinum Customer" rule will not be fired.







3 comments:

  1. I am using classes from org.kie.api package. Even after defining "activation-group" in drl file, it is not working as if-else. It is trying to execute other rules.

    ReplyDelete
  2. bad wording. It will never work as ifelse.behavior is simple. if one rule is executed , the others in same activation group will not execute even if condition is satisfied. that is the essence of activation group.

    ReplyDelete