0
votes

I have a drools decision table in excel spreadsheet with two rules. (This example has been greatly simplified, the one I am working with has alot more rules.)

enter image description here The first rule checks if amount is more than or equal to 500. If it is, then it sets status to 400. The second rule checks if status is 400. If it is, then it sets the message variable. The problem is, I am unable to get the second rule to fire, even though sequential is set. I also have to use no-loop and lock-on-active to prevent infinite looping.

My goal is to get the rules to fire top down, and the rules that come after might depend on changes made to the fact/object by earlier rules.

Is there a solution to this problem? Any help would be appreciated, thanks!

package com.example;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

public class SalaryTest {

    public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KieServices ks = KieServices.Factory.get();
            KieContainer kContainer = ks.getKieClasspathContainer();
            KieSession kSession = kContainer.newKieSession("ksession-dtables");

            Salary a = new Salary();
            a.setAmount(600);

            kSession.insert(a);
            kSession.fireAllRules();


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

    public static class Salary{
        private String message;
        private int amount;
        private int status;

        public String getMessage() {
            return message;
        }
        public void setMessage(String message) {
            this.message = message;
        }
        public int getAmount() {
            return amount;
        }
        public void setAmount(int amount) {
            this.amount = amount;
        }
        public int getStatus() {
            return status;
        }
        public void setStatus(int status) {
            this.status = status;
        }

    }
}
2

2 Answers

1
votes

The attribute lock-on-active countermands any firings after the first from the group of rules with the same agenda group. Remove this column.

Don't plan to have rules firing in a certain order. Write logic that describes exactly the state of a fact as it should trigger the rule. Possibly you'll have to write

rule "set status"
when
  $s: Salary( amount >= 500.0 && < 600.0, status == 0 )
then
  modify( $s ){ setStatus( 400 ) }
end

to avoid more than one status setting to happen or just the right setting to happen. But you'll find that your rules may be more outspoken and easier to read.

Think of rule attributes are a last resort.

0
votes

Please replace the action in the column H in the following way:

Current solution:

a.setStatus($param);update(a);

New solution:

modify(a) {
    setStatus($param)
}