请注意,此答案对于 Drools 5.x 及以下版本有效。如果您已转到 6 或更高版本,请查看 @melchoir55 修改后的答案。我自己还没有测试过,但我相信它是有效的。
要跟踪规则激活,您可以使用 AgendaEventListener。下面是一个示例,如下所示:
https://github.com/gratiartis/sctrcd- payment-validation-web/blob/master/src/main/java/com/sctrcd/drools/util/TrackingAgendaEventListener.java https://github.com/gratiartis/sctrcd-payment-validation-web/blob/master/src/main/java/com/sctrcd/drools/util/TrackingAgendaEventListener.java
您只需要创建这样的侦听器并将其附加到会话,如下所示:
ksession = kbase.newStatefulKnowledgeSession();
AgendaEventListener agendaEventListener = new TrackingAgendaEventListener();
ksession.addEventListener(agendaEventListener);
//...
ksession.fireAllRules();
//...
List<Activation> activations = agendaEventListener.getActivationList();
请注意,还有WorkingMemoryEventListener,它使您能够执行相同的操作来跟踪事实的插入、更新和撤回。
跟踪和记录 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<Activation> activationList = new ArrayList<Activation>();
@Override
public void afterActivationFired(AfterActivationFiredEvent event) {
Rule rule = event.getActivation().getRule();
String ruleName = rule.getName();
Map<String, Object> 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<Activation> 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();
}
}
}