JBoss Drools – Decision Tables

I have been playing around with JBoss Drools(Version 4.0.7) – the open source rules engine.  JBoss supports business rules implementation using three techniques:

  1. Decision Tables
  2. Writing DRL file
  3. Defining business flow using rules flow rf file

This post is going to cover the first technique for business rules definition using Drools Decision table.

Business users regularly crib about the fact that they need IT involvement to make changes to business rules.  One of the typical business rules implementation requirement is a decision table. Business rules can be laid out in tabular fashion and association between conditions and actions clearly defined.

JBoss Drools simplifies the decision table implementation approach by supporting defining decision tables in Microsoft Excel spreadsheets. For better understanding, I am going to use a simple insurance quick quote example.

The first thing to get started is installing Eclipse on your machine. I had Eclipse Europa version installed on my machine, hence I have to pick up the appropriate Drools Engine, Eclipse plug-in download. Next comes the procedure for setting up Drools Engine, IDE et al is available here.

If the Drools Eclipse plug-in setup is working fine, you should be able to use the Eclipse File –> New menu to create a new Rule Project. In the newly created project named say “BusinessRules”, you will see the following folder structures:

BusinessRules|
             |----- src/main/java
             |
             |----- src/main/rules

The src/main/java folder will hold the java class file source code and the rules files (.xls, .drl, .rf) wil be housed in src/main/rules. To create a new Decision table, select File –> New –> New Decision Table. The excel spreadsheet created will have the same features of a normal MS Excel spreadsheet except the rows 1 to 10 which have been created with information specific to Drools.

Please find below a screen shot of the decision table I prepared for an insurance quoting engine. The table decides based on the following if the applicant is eligible for insurance cover or not.

  • Applicant’s gender
  • Applicant’s age
  • Face Amount applied for
  • Policy Issue State
  • Smoker Status
  • Whether the applicant is suffering from any adverse disease.

Drools Decision Table
Drools Decision Table

In case the screen shot is not completely visible, click here to enlarge. Now that we have a sample decision tables done let’s set up the java source.

package com.insure.qq;

public class QuickQuoteInputProfile {

	private String state              = null;
	private String gender             = null;
	private int age                   = 0;
	private Double faceAmount         = null;
	private boolean adverseDiagnosis  = false;
	private SmokerProfile smokingProf = null;

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Double getFaceAmount() {
		return faceAmount;
	}

	public void setFaceAmount(Double faceAmount) {
		this.faceAmount = faceAmount;
	}

	public boolean isAdverseDiagnosis() {
		return adverseDiagnosis;
	}

	public void setAdverseDiagnosis(boolean adverseDiagnosis) {
		this.adverseDiagnosis = adverseDiagnosis;
	}

	public SmokerProfile getSmokingProf() {
		return smokingProf;
	}

	public void setSmokingProf(SmokerProfile smokingProf) {
		this.smokingProf = smokingProf;
	}

}

package com.insure.qq;

public class SmokerProfile {

	private String smokerStatus = null;

	public String getSmokerStatus() {
		return smokerStatus;
	}

	public void setSmokerStatus(String smokerStatus) {
		this.smokerStatus = smokerStatus;
	}

}

Now that we have all the code we need, let’s try and understand what have done.

First things first the decision table. The rows C2, C3 and C4 store specific tag information, They specify that their adjoining columns D2, D3 and D4 signify the name of the ruleset, the java class import statements and notes regarding the rules if any. A developer should not add any information in these columns besides the ones specified. The excel spread sheet does allow the developer the flexibility of defining two rule tables. We will limit ourselves to using one. Rows C6 to C10 have their own significances. C6 is used to name the rules table, C7 by itself has not information but the subsequent columns can hold two values “CONDITION” or “ACTION”. Note that the rules will not be valid unless the value in the column is one or the other. In D8 and subsequent columns, we specify the actual java class referenced in the business rule. In our case it is QuickQuoteInputProfile. Note the notation used is <variable name>: <Java Class name>. There should always be a space after the colon or else you would end up debugging some weird Drools error messages. In D9 and the following columns we specify the class attribute and the condition in which it is analyzed. D10 and following columns can be used to give business friendly names to each evaluation parameter.

Now let us understand how each parameter is evaluated.  Note that $param is a standard used to specify the value mentioned in the excel spreadsheet cell.

state in ($param) – It checks if the state requested for is part of the eligible states. Here state is an attribute of the QuickQuoteInputProfile class. Drools implicitly uses the getter method. The ‘in’ operator usage signifies list comparison. As we want multiple String value comparisons, they are defined in the cell using a comma separator. The ” ” around the value specifies that the value is evaluated as a string.

gender == $param – String or any other primitive data type can be compared using the == operator. Putting the apostrophes around the param “$param” converts the evaluation values i.e. MALE/FEMALE into string values.

age >= $1, age <=$2 – In case we need to do a range comparison like an applicant’s a

ge is within a given range, we can use the greater than, less than operators and use $1 and $2 as place holders. You can also use $param1 etc as the name. Also note that the comma separator between the age >= $1, age <= $2 is an implicit AND condition.  This can be changed. To make the condition an OR condition instead of age >= $1, age <= $2 put the condition age >= $1 || age <= $2 and to make the condition more explicit with respect to the other conditions, enclose this condition in brackets like (age >= $1 || age <= $2).

quickQuoteProfile.smokingProf.smokerStatus == “$param” – It is possible that we are evaluating an object composed of objects. Drools makes it possible to navigate the entire hierarchy, using the dot(.) notation. Just ensure that all the objects are instantiated(otherwise you will get NullPointerExceptions) and that the getters will appropriate access modifiers provided.

Sometimes we need to write rules that will be triggered by the mere presence or absence of an object. For example, if SmokerProfile object exists within QuickQuoteInputProfile, then take certain action. In DRL this can be done by exists quickQuoteProfile.smokingProf(), unfortunately this fails in Excel based decision tables as a param is expected. Therefore the work around is to define the condition as exists (quickQuoteProfile.smokingProf.smokerStatus == $param) and in the rule cell write smokerStatus. The rule achieves the same effect as required.

Note that all rules are evaluated with an implicit AND condition between them. For example, rule 1 translates to the following condition:

The policy issue state should be one of the US states “VA”, “PA”, “NY” AND applicant gender should be MALE AND applicant age is greater than 20 and less than 65 AND faceamount greater than 50K and less than 250K AND applicant is a non-smoker AND applicant does not suffer from any disease which could lead to an adverse rating.

I will cover the ACTION using the following screenshot.

Drools Decision Tables - 2
Drools Decision Tables - 2
In case of visibility issues click here to enlarge.

A typical rule will have a condition, which is evaluated and based on the evaluation an action taken. The decision/action arrived at by rules engine is conveyed to rules engine invoking client via a java object. Drools has a concept of a global variable. It can be defined as specified in row 25. In cell D25, we store the complete class name and the variable name. In our current example it is “com.insure.qq.ro.QuickQuoteResult result” where result is the variable name.  The structure of the Java class QuickQuoteResult is as below:

package com.insure.qq.ro;

public class QuickQuoteResult {

	private boolean eligible = false;

	public boolean isEligible() {
		return eligible;
	}

	public void setEligible(boolean eligible) {
		this.eligible = eligible;
	}

}

How does the decision table know that this is the class to instantiate? In cell J9, we say result.setEligible($param) and in cell C25 and D25 we specify the Variable and variable class name. Note that J9 is a cell defined under the “ACTION” column, thus translating to an action condition.(Hope this write-up is satisfactory “Novice”. Thanks for the rap on the head, must have become lazy.)

Now how do we run the rules engine. Create the following test class:

package com.insure.qq.test;

import java.io.StringReader;

import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.WorkingMemory;
import org.drools.audit.WorkingMemoryFileLogger;
import org.drools.compiler.PackageBuilder;
import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.drools.rule.Package;

import com.insure.qq.QuickQuoteInputProfile;
import com.insure.qq.SmokerProfile;
import com.insure.qq.ro.QuickQuoteResult;

public class QQBRETest {

	public static void main(String[] args) {
        try {

        //load up the rulebase
            RuleBase ruleBase = readDecisionTable();
            WorkingMemory workingMemory =  ruleBase.newStatefulSession();

            WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger(workingMemory);
            logger.setFileName("C:/drools-audit");

            QuickQuoteInputProfile input = new QuickQuoteInputProfile();
            input.setAge(21);
            input.setFaceAmount(Double.valueOf(200000));
            input.setState("VA");
            input.setGender("MALE");
            input.setAdverseDiagnosis(false);

            SmokerProfile prof = new SmokerProfile();
            prof.setSmokerStatus("Y");

            input.setSmokingProf(prof);
            QuickQuoteResult result = new QuickQuoteResult();

            workingMemory.insert(input);
            workingMemory.setGlobal("result", result);
            workingMemory.fireAllRules();
            logger.writeToDisk();

            System.out.println(result.isEligible());

        } catch (Throwable t) {
            t.printStackTrace();
        }
	}

	private static RuleBase readDecisionTable() throws Exception {
		//read in the source
        final SpreadsheetCompiler converter = new SpreadsheetCompiler();
        final String drl = converter.compile( "/QuickQuoteExample.xls", InputType.XLS );
        System.out.println(drl);
		PackageBuilder builder = new PackageBuilder();
		builder.addPackageFromDrl( new StringReader( drl ) );
		Package pkg = builder.getPackage();
		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
		ruleBase.addPackage( pkg );
		return ruleBase;
	}

}

Note the usage of the WorkingMemoryFileLogger. This will create an audit file named drools-audit.log in C: drive. You can view the contents using the audit view within the Drools Eclipse perspective. In the readDecisionTable method, there is an implementation of converting the decision table spreadsheet into Drools DRL file.

Update(16th December 2009):

My previous decision table example considered only one input object. In case there are more than one input objects, the decision table has no problem in supporting them. Please refer the decision table excel sheet below and for better viewing refer here.

Drools with multiple=

The rest of the structure remains the same except the addition of a new column J with rule name header “Driving Violations” in the excel sheet and addition of a new row Rule-14.

Please find below the new test code for the updated decision table.

package com.insure.qq.test;

import java.io.StringReader;

import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.WorkingMemory;
import org.drools.audit.WorkingMemoryFileLogger;
import org.drools.compiler.PackageBuilder;
import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.drools.rule.Package;

import com.insure.qq.DrivingViolations;
import com.insure.qq.QuickQuoteInputProfile;
import com.insure.qq.SmokerProfile;
import com.insure.qq.ro.QuickQuoteResult;

public class QQBRETest {

	public static void main(String[] args) {
        try {

        	//load up the rulebase
            RuleBase ruleBase = readDecisionTable();
            WorkingMemory workingMemory = ruleBase.newStatefulSession();

            WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger(workingMemory);
            logger.setFileName("C:/drools-audit");

            QuickQuoteInputProfile input = new QuickQuoteInputProfile();
            input.setAge(21);
            input.setFaceAmount(Double.valueOf(200000));
            input.setState("VA");
            input.setGender("MALE");
            input.setAdverseDiagnosis(false);

            SmokerProfile prof = new SmokerProfile();
            prof.setSmokerStatus("Y");

            input.setSmokingProf(prof);
            QuickQuoteResult result = new QuickQuoteResult();

            DrivingViolations vol = new DrivingViolations();

            workingMemory.insert(input);
            workingMemory.insert(vol);
            workingMemory.setGlobal("result", result);
            workingMemory.fireAllRules();
            logger.writeToDisk();

            System.out.println(result.isEligible());

        } catch (Throwable t) {
            t.printStackTrace();
        }
	}

	private static RuleBase readDecisionTable() throws Exception {
		//read in the source
        final SpreadsheetCompiler converter = new SpreadsheetCompiler();
        final String drl = converter.compile( "/QuickQuoteExample.xls", InputType.XLS );
        System.out.println(drl);
		PackageBuilder builder = new PackageBuilder();
		builder.addPackageFromDrl( new StringReader( drl ) );
		Package pkg = builder.getPackage();
		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
		ruleBase.addPackage( pkg );
		return ruleBase;
	}
}

This portion of the post is in response to Jagadeesh’s query regarding accessing object variables. My assumption is that he is interested is ascertaining the possibility of accessing input object variables within the ACTION column. Here’s how you can set the input variable’s value in the action column. I have made the following modifications to the updated decision table. In cell L9, the cell below the ACTION header cell, I have replaced result.setEligible($param); with quickQuoteProfile.setFlag($param); In the QuickQuoteInputProfile class I have added a boolean property flag with its accessors and modifiers. The cell corresponding to the ACTION column for Rule-14 has been left blank. This is necessary as the new decision table has two objects as input. Rule-14 does not require the QuickQuoteInputProfile, therefore there is no variable reference to this class’s instance in rule-14’s when clause. If a value was put in the ACTION column cell for rule-14, we would get a exception. Refer the decision table below:

Drools Input Object in Action
Drools Input Object in Action

Click here to enlarge.

The modified test code for this functionality can be found below:

package com.insure.qq.test;

import java.io.StringReader;

import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.WorkingMemory;
import org.drools.audit.WorkingMemoryFileLogger;
import org.drools.compiler.PackageBuilder;
import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.drools.rule.Package;

import com.insure.qq.DrivingViolations;
import com.insure.qq.QuickQuoteInputProfile;
import com.insure.qq.SmokerProfile;
import com.insure.qq.ro.QuickQuoteResult;

public class QQBRETest {

	public static void main(String[] args) {
        try {

        	//load up the rulebase
            RuleBase ruleBase = readDecisionTable();
            WorkingMemory workingMemory = ruleBase.newStatefulSession();

            WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger(workingMemory);
            logger.setFileName("C:/drools-audit");

            QuickQuoteInputProfile input = new QuickQuoteInputProfile();
            input.setAge(21);
            input.setFaceAmount(Double.valueOf(200000));
            input.setState("VA");
            input.setGender("MALE");
            input.setAdverseDiagnosis(false);

            SmokerProfile prof = new SmokerProfile();
            prof.setSmokerStatus("Y");

            input.setSmokingProf(prof);
            QuickQuoteResult result = new QuickQuoteResult();

            DrivingViolations vol = new DrivingViolations();

            workingMemory.insert(input);
            workingMemory.insert(vol);
            workingMemory.setGlobal("result", result);
            workingMemory.fireAllRules();
            logger.writeToDisk();

            System.out.println(input.isFlag());

        } catch (Throwable t) {
            t.printStackTrace();
        }
	}

	private static RuleBase readDecisionTable() throws Exception {
		//read in the source
        final SpreadsheetCompiler converter = new SpreadsheetCompiler();
        final String drl = converter.compile( "/QuickQuoteExample.xls", InputType.XLS );
        System.out.println(drl);
		PackageBuilder builder = new PackageBuilder();
		builder.addPackageFromDrl( new StringReader( drl ) );
		Package pkg = builder.getPackage();
		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
		ruleBase.addPackage( pkg );
		return ruleBase;
	}
}

The input and output variables can be combined together as well. The cell below the ACTION column header can be set as

quickQuoteProfile.setFlag($param);result.setEligible($param);

Finally, In case you need to explicitly set some values directly in the ACTION column or use some values from the input object, do as shown in the diagram. The value in the ACTION cell for the individual rules is semi-colon (;). It works! Refer the decision table below:

Drools ACTION
Drools ACTION

Click here to enlarge.

That covers my initiation into the world of JBoss Drools Decision Tables. More drools stuff next time when write in.

Published by Vinay Rajadhyaksha

Vinay Rajadhyaksha a.k.a Mr President

75 thoughts on “JBoss Drools – Decision Tables

  1. Hi,
    Thanks for updating the already well-written article to make it Perfect :-).
    I have a small query. I have a set of rules each one almost like-
    rule “Rule 1”
    salience 1
    no-loop true
    when
    ruleReq : ArrayList()
    k : Key(keyName == “Form1”, keyValue == “101” || keyValue == “102” || keyValue == “103” )
    then
    ruleReq.add(new Key(k.getKeyName(), k.getKeyValue()));
    end

    The action part of this rule is not working fine in the decision table. Can you suggest how can I write the Then part of this rule in Decision table?

    Thanks in advance,
    FanduMax

    1. I do not have a ready codebase available to validate, but my first suggestion would be to make ruleReq a global variable.

  2. Hi Mr. President,

    Thanks for your response. Actually I tried with the global variable but could not get the desired results by adding values to result Array List using decision table. If you have any more clues for this, please post them here.
    Also, If possible, can you explain how to use functions in Decision tables? I’m struggling to get a few functions working with decision tables.
    Thanks in advance,
    Novice

    1. Here’s something to try out. I have used the code as per my Drools post titled “Defining business Rules”. I have added the following rule in the sample DRL:

      rule “Check a variation in code”
      salience 88
      when
      $policy : Policy()
      $list: ArrayList()
      from accumulate ( $coverage : Coverage(faceAmount > 25000) from $policy.coverages,
      init (ArrayList list = new ArrayList();),
      action (list.add($coverage);),
      reverse(;),
      result(list)

      )
      then
      result.setCoverages($list);
      end

      Added the following line of code in the PolicyRuleResult class with its appropriate getter and setter.

      private List coverages = new ArrayList();

      I think you will need a similar approach to tackle your key related problem. Hope this helps. As regards using functions in Decision tables, frankly I have not tried and I believe it will be a waste of effort. There is nothing in Drools documentation to suggest ways in implementing the same. IMHO better to code it in DRL.

  3. If a function is invoked from action column, does it pick the attributes that were assigned from the condition columns?

    1. Adding Drools functions is very difficult to implement using decision tables. My recommendation is to use a DRL.

    1. I have updated the post today with some more samples which should address your query. In case that is not adequate please reply back with specific information about what your requirement is.

  4. Woh…that is very helpful.

    I have another question…how do I check for not null condition through decision table. Is it possible.

    Thanks

    1. null checks should be easy. Please refer my decision table example. Let’s look at a specific condition, gender. Presently the condition is put in as gender == $param. Replace it as follows:

      gender !=null && gender == $param

      This will evaluate as per your requirement.

    1. I wish there was something like that available. However I am not aware of any way in which it is possible to create a decision table from a rules file.

      😉

  5. Thanks President. Your responses are helpful. Can we sequence conditions and actions in decision tables? I tried to do an example but it looks like all conditions and actions are grouped seperately so that conditions are evaluated first and then the actions (all of them) are evaluated next. Is it possible to have a sequence. I know agenda-group is an option with drl…is the same possible with decision tables?

    So basically i am checking to see if i can have 2 conditions then do an action and then do few more conditions and then do action…and so…

    1. JM,
      I found a reference to agenda group here. I have not tried it myself. You can take a shot and let me know.

      Do note that my code has been tested with Drools 4.0.7 and not 5.0. So I am not sure if this feature is available in 4.0.7.

  6. Yea, I have this yesterday. But how about >> So basically i am checking to see if i can have 2 conditions then do an action and then do few more conditions and then do action…and so…

    Is this possible?

    1. Jagadeesh,

      I think we are stretching it out quite a bit. Whatever I will be recommending next is purely speculation from my end. I think you will need to use agendagroup and setFocus together.

      Refer setFocus links 1 and 2. drools.setFocus is available in 4.0.7 and not in 5.0. For 5.0 use the option specified in link 2.

      Here’s what I recommend. Put in CONDITION 1 and in ACTION 1 do your actionable activities and then setFocus to agendagroup2. This should trigger the relevant rules(s) causing action 2 to get invoked.

      Let me know if this works.

  7. Thanks for the info. One thing that’s left out is how to query an object from working memory? You had that covered in the DRL example.

    1. If your question is how to implement QueryResults in decision tables, I am not sure either. Sorry about that. 🙂

    1. Upul,

      I do not believe there should be any specific limits except for the ones defined within EXCEL.

  8. Hi,

    I have an xml file and have generated java objects using jaxb. There are multiple elements in the xml with multiple attributes. How do I write a rule which tests all the elements of a particular type ie., which is of list type ?

    Thanks and regards,
    Anitha

    1. Anitha,

      As I understand it your requirement is to verify that elements/attributes defined within a XML conform to a specific type.

      I am not sure why you are trying to implement this functionality in a rules engine. It would be more appropriate to define an xml schema and verify the xml file compliance to the schema.

  9. Hi,

    I am sorry, that is not my requirement. May be , I havent putforth my thoughts clearly. Let me explain.

    We are developing an application which process loan application. The front end is done and the values are stored . Next step, we are calling a webservice which gives me a loan application stored values for a particular “id” in xml format and that is fed to jaxb , thereby obtaining java objects. Next step, we are integrating these objects with Drools rule engine wherein some rules are fed.

    Now, my problem is, the objects that I have obtained is of list type and I need to iterate through the rule engine.How do I do that ? Please help me…

    Thanks and regards,
    Anitha.

    1. I understand your requirement. I am cannot think how this can be implemented in decision tables. However if you are interested in a normal DRL it is possible. Check out how I have used collection of coverages in my other Drools post.

      I hope this answers your question.

  10. Hi,
    Is the following possible with Drools, if yes, how?-
    Say I define 5 rules and my input criteria fails for all 5.
    Can I specify a 6th rule which can be used as a default, like if the first 5 fail to get an action, use the 6th for getting the action?

    Please try to reply ASAP.

    Thanks
    Ankit

    1. Hi Ankit,

      I think you are looking for something like the switch operator in programming languages. If all cases fail, use default. Unfortunately it does not apply in BRMS. Based on the input data, BRMS are programmed to identify the applicable rules and execute only the applicable rules. This is unlike programming languages where each condition is evaluated at runtime. Therefore in your case you will have to write a business rule covering the failure of all the earlier five conditions to get rule no. 6 to execute.

  11. Dear Sir,
    I have another query with Drools, it would be great if you could spare some time to reply to it-
    How is it possible to force the rule matching to exit once a match has been found?
    I mean if I have 50 rules and the 5th rules matches, I want the system to exit with the result of 5th rule and not process the remaining 45 rules.
    Is there a way to achieve that?
    Thanks
    Ankit

      1. Actually, THis is possible. If you have a column called XOR-GROUP and have a common name for all the 50 rules, then Drools will exit from the agenda as soon as the first rule is executed.
        Also, you can use a PRIORITY column to indicate the salience of the rules, and this way the most apt rule will get fired first and exit

  12. I have question, for your rule-3, if state=”CA”, Gender=”MALE”,is the result still false? what empty condition mean?

    1. Sara,

      Yes in case of rule-3, the state=”CA” will be evaluated and the result will be false. I am not sure what you mean by an empty condition, please elaborate.

  13. Mr. President,

    I am new to decision tables. I just started working on an existing project. They have defined the condition as
    currentEnrollmentStatus==”$1″ ||currentEnrollmentStatus==”$2″ ||currentEnrollmentStatus==”$3″

    and action as m.addNextAvailableStatus(“$param”);

    There is a record having condition as LM10 and the action as LM2.

    But if the input is LM1, the application is giving LM2. The reason is that LM1 is a substring of LM10. Basically, it is evaluating a condition by doing startswith instead of equals. Any idea how to fix this?

    1. Hi Maddy,

      Could you please elaborate your issue, I am still not clear around what function/operator are you using to get a substring.

    1. Roy,

      Its been some time since I worked on this. Here’s a wild guess use “/CheckAccepted.xls” instead of “CheckAccepted.xls”. I am assuming that the xls file is in the classpath.

  14. Hi President,
    I am getting problem while using more than 9 parameters in Decision Table. Is there any known issue in Drools 5.11 ??

    1. RajCherukuri,

      I have not used 5.1.1, so I am not sure if there is an issue. Can you explain what is the exact nature of your problem?

  15. I am also getting an error when using more than 9 parameters like $10 in decision table. When the param has two digits like in the case of $10, $11, etc, Drools is replacing it with the value for $1 and adding the next digit (‘0’ for 10, ‘1’ for 11, ‘2’ for 12, etc) to it rather than using the 10th value.

  16. Hi All,

    Please suggest, when compared to decision table with DRL mechanism which one is better, if the business rules are huge and complicated ??

    Thanks,
    Kishore

    1. Hi Kishore,

      The selection between decision table or DRL is purely driven by whether the rule can be set up in decision table or not. If yes, decision table is the way to go. If not, use DRL to model. From a runtime standpoint there is no difference as decision tables are converted in drl files.

      Generally complex business rules cannot be modeled in decision table, therefore you will naturely use DRL.

  17. Hi, how do i do in java to get al matched rules?,
    i use
    session.insert(someobject);
    int rulesMatch = session.fireAllRules();
    rulesMatch counts 2 rules, in the variable someobject has the result of the first matche rules, buy how i do get the other matched rules?

    i hope you cna help me
    thanks

  18. I have tried the above example.when i try to run the class QQBERTest.java.
    i am getting the following error.

    WARNING: Wasn’t able to correctly close stream for decision table. nulljava.lang.NullPointerException
    at jxl.read.biff.File.(File.java:91)
    at jxl.Workbook.getWorkbook(Workbook.java:268)
    at org.drools.decisiontable.parser.xls.ExcelParser.parseFile(ExcelParser.java:75)
    at org.drools.decisiontable.SpreadsheetCompiler.compile(SpreadsheetCompiler.java:89)
    at org.drools.decisiontable.SpreadsheetCompiler.compile(SpreadsheetCompiler.java:68)
    at org.drools.decisiontable.SpreadsheetCompiler.compile(SpreadsheetCompiler.java:110)
    at com.insure.qq.test.QQBRETest.readDecisionTable(QQBRETest.java:58)
    at com.insure.qq.test.QQBRETest.main(QQBRETest.java:24)

    I am using drools5.3 version.Please help me in resolving the issue.

    1. Hi Srinivas,

      My take is that the xls file is not available in the classpath. Ensure that the xls file is present in your classpath. Alternatively use the overloaded version of the compile method which accepts InputStream. Use the absolute file path to pass the xls input stream.

  19. Facing following issues with decision tables on drools 5.3.

    1.Not able to specify the dialect for the rule inside the decision table.when i specify the dialect on the decision table after the condition column,Getting error saying only one Duration cell will be allowed.

    2. Not able to specify the auto-focus attribute for rules inside the decision tables.

    3.will it be possible to use drools fusion concepts inside the decision tables.
    for example i want to see if there any two events(with same attributes) with in 5 seconds or using over the window of 5 seconds.Basically i want to use the fusion 14 keywords(after,before etc) inside the decision tables.

    Please provide me pointers for the same.

  20. Is there any way to specify the stream name in descion table.

    for example e:Event() from entry-point “XYZStream”.

  21. Great Article Mr.President… Can you please throw more light on NAME keyword and can we just invoke a particular Rule usign the entities under NAME keyword. My requirement is something like i need to check for e.g. the age and the policy number length. My age Check should only execute when i give the ageCheckRule and same for policy number. Can we invoke a rule separately based on Rule Name under NAME keyword?
    Thanks for your response…

    1. Hi Ramanath,

      It has been a long time since I looked up Drools so my knowledge would be rusty. However I doubt that you can invoke a specific rule directly using a name. Only if the conditions are satisfied will the rule be invoked.

  22. Hi President,
    I tried decision table example.In that i need to use more than one class attributes in single condition.How to resolve this?
    Thanks in Advance

  23. Suppose the users want to write only the rule which set to true when all the coditions true. Because creating rules per combination of conditions lead to a huge number of business rules. But if the rule was failed, they need to know which all conditions failed. Would that be possible?

  24. how to add the following rule in decision table.
    rule “Check a variation in code”
    salience 88
    when
    $policy : Policy()
    $list: ArrayList()
    from accumulate ( $coverage : Coverage(faceAmount > 25000) from $policy.coverages,
    init (ArrayList list = new ArrayList();),
    action (list.add($coverage);),
    reverse(;),
    result(list)

    )
    then
    result.setCoverages($list);
    end

  25. Hi,
    The article was really good, but i am facing some problem:
    I have a class:

    class Client
    {
    int id;
    Sting name;
    // getters and setters
    }

    class user
    {
    int id;
    Client client;
    // getters and setters
    }
    // In the code:
    Client client = new Client ( 1, “Client1” );
    User user = new User(1, client);
    FactHandle userFact = (FactHandle) knowledgeSession.insert ( user );
    How do i access the client id in the decision table?
    i am using excel

    thanks in advance

  26. Mr. President,

    Thanks a lot for writing such a wonderful article. I want to integrate Drools Decision Table but want to provide Users capability to create tables in a CSV Format. Due you have a sample CSV file that accomplishes same goals as above mentioned example?

    Regards,

    Pankaj

  27. I have a comma separated string as value of an action column which I would like to set in a string array parameter of an action method if the condition is met. However, I am just getting the first string with $1…how can I get comma separated string as string array?

  28. Hi Good Article but can You please tell me the same code with Drools 6.0 or above??Will it be different and what will be the difference???Reply soon.

    1. I am sorry, Ankit. This was a POC I did some time back, so I cannot confirm if this will work with Drools 6.0.

  29. Hi, I am working on a decision table which will do the calculation in the action. Below is the rule set :

    Condition Condition Condition Action
    $dto.amount $dto.percentage $dto.addition $dto.setFinalValue($param)

    Rule-1 Yes Yes Yes 220
    Rule-2 Yes NO Yes 140

    The calculation done in Action is as below : Corresponding to amount 80, corresponding to percentage 80 and corresponding to addition 60. So 240 is calculate as 80+80+60

    Now in future if business decided to change the value of amount from 80 to 20. In that case i have to update each and every combination. Right now I have 200 such combinations.

    Can any one let me know how i can specify the values of amount, percentage and addition in another condition column that way instead of hardcoding the 220 i can use the value from that conditions in my action and then i can write the formula like
    condition4+ condition5+condition6

  30. Hi, I’m working on agenda-group in decision table in which I have two coditions, Action and agenda-group. When I fire the rule it is considering only one condition and ignoring other condition. Can someone please let me know?

    1. Hi Kaushik,

      We can add OR between two Condition Columns via merging Columns in decision table.

      Thanks,Muthu

  31. Hello Mr. President,
    I wanted to know if any API exists which can add one rule to decision table and as soon as a change is detected in the file, the updated decision table is added to the working memory.

Leave a reply to Srinivas Cancel reply