Search code examples
javadrools

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?


Solution

  • 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