Drools- how to find out which all rules were matched?

后端 未结 5 1629
后悔当初
后悔当初 2021-02-02 13:32

I\'ve one .DRL file which has say 10 rules. Once I insert a fact, some rules may be matched- how do I find out which rules were matched programmatically?

5条回答
  •  别那么骄傲
    2021-02-02 13:38

    Note that this answer is valid for versions of Drools up to 5.x. If you have moved on to 6 or above, then take a look at the modified answer from @melchoir55. I haven't tested it myself, but I'll trust that it works.

    To keep track of rule activations, you can use an AgendaEventListener. Below is an example, as found here:

    https://github.com/gratiartis/sctrcd-payment-validation-web/blob/master/src/main/java/com/sctrcd/drools/util/TrackingAgendaEventListener.java

    You just need to create such a listener and attach it to the session like so:

    ksession = kbase.newStatefulKnowledgeSession();
    AgendaEventListener agendaEventListener = new TrackingAgendaEventListener();
    ksession.addEventListener(agendaEventListener);
    //...
    ksession.fireAllRules();
    //...
    List activations = agendaEventListener.getActivationList();
    

    Note that there is also WorkingMemoryEventListener which enables you to do the same with tracking insertions, updates and retractions of facts.

    Code for a tracking & logging AgendaEventListener:

    package com.sctrcd.drools.util;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    
    import org.drools.definition.rule.Rule;
    import org.drools.event.rule.DefaultAgendaEventListener;
    import org.drools.event.rule.AfterActivationFiredEvent;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * A listener that will track all rule firings in a session.
     * 
     * @author Stephen Masters
     */
    public class TrackingAgendaEventListener extends DefaultAgendaEventListener {
    
        private static Logger log = LoggerFactory.getLogger(TrackingAgendaEventListener.class);
    
        private List activationList = new ArrayList();
    
        @Override
        public void afterActivationFired(AfterActivationFiredEvent event) {
            Rule rule = event.getActivation().getRule();
    
            String ruleName = rule.getName();
            Map ruleMetaDataMap = rule.getMetaData();
    
            activationList.add(new Activation(ruleName));
            StringBuilder sb = new StringBuilder("Rule fired: " + ruleName);
    
            if (ruleMetaDataMap.size() > 0) {
                sb.append("\n  With [" + ruleMetaDataMap.size() + "] meta-data:");
                for (String key : ruleMetaDataMap.keySet()) {
                    sb.append("\n    key=" + key + ", value="
                            + ruleMetaDataMap.get(key));
                }
            }
    
            log.debug(sb.toString());
        }
    
        public boolean isRuleFired(String ruleName) {
            for (Activation a : activationList) {
                if (a.getRuleName().equals(ruleName)) {
                    return true;
                }
            }
            return false;
        }
    
        public void reset() {
            activationList.clear();
        }
    
        public final List getActivationList() {
            return activationList;
        }
    
        public String activationsToString() {
            if (activationList.size() == 0) {
                return "No activations occurred.";
            } else {
                StringBuilder sb = new StringBuilder("Activations: ");
                for (Activation activation : activationList) {
                    sb.append("\n  rule: ").append(activation.getRuleName());
                }
                return sb.toString();
            }
        }
    
    }
    

提交回复
热议问题