Andriy Kryvtsun Andriy Kryvtsun - 2 months ago 21
Java Question

Reuse part of Drools `when` statement

I have bulk of Drools rules with the similar

when
parts. E.g.

rule "Rule 1"
when
trn: TransactionEvent()

// some `trn` related statements

not ConfirmEvent (
processMessageId == trn.groupId )
then
// some actions
end

rule "Rule 2"
when
trn: TransactionEvent()

// some other `trn` related statements

not ConfirmEvent (
processMessageId == trn.groupId )
then
// some other actions
end


Is it possible to define one time this statement

not ConfirmEvent (
processMessageId == trn.groupId )


and reuse somehow where needed?

Answer

Two approach ideas:

  1. Use the rule "extends" keyword with each rule to extend a base rule containing the shared when statements.

  2. Create a rule with the shared when statements that infers a fact ("extract rule"). Use that fact in the when conditions of the rules needing the shared conditions. This option is typically my preferred approach as it defines a "concept" (a named fact) for those conditions and evaluates only once vs each rule.

    Rule example for #2:

    rule "Transaction situation exists"
        when
            trn: TransactionEvent()
    
            // some `trn` related statements
    
            $optionalData : // bind as wanted
    
            not ConfirmEvent (
                processMessageId == trn.groupId )
        then
            InferredFact $inferredFact = new InferredFact($optionalData);
            insertLogical($inferredFact);
    end
    
    rule "Rule 1"
        when
            InferredFact()
            AdditionalCondition()
        then
            // some actions
    end
    
    rule "Rule 2"
        when
            InferredFact()
            OtherCondition()
        then
            // some other actions
    end