我是Drools的新手。我正在尝试使用Drools Fusion编写一个简单的复杂事件处理(CEP)应用程序。
我的要求是
- on receipt of a CRITICAL event, perform an action (right now that's a SOP)
- if another CRITICAL event arrives within 5 minutes of the previous event
and from the same source, ignore it
我有一个简单的Event类,如下所示:
public class Event {
private String id;
private Date timestamp;
private String source;
private Event.Severity severity;
private String description;
/// With Getter and Setter ///
}
规则文件如下:
declare Event
@role(event)
end
rule "Alert for CRITICAL events. Don't alert for the next 5 minutes if
from the same source"
when
$ev1: Event($source: source, severity == Event.Severity.CRITICAL)
from entry-point "events"
not (
Event(this != $ev1, source == $source,
severity == Event.Severity.CRITICAL,
this before [1ms, 5m] $ev1) from entry-point "events"
)
then
System.err.println("###### CRITICAL alert caused by event: "
+ $ev1.getId());
end
为了测试,我将4个事件分别注入工作存储器 - e1,e2,e3,e4,时间线分别为0m,4m,10m,12m。
Jave类文件
Event event1 = new Event("e1", new Date(), "server1",
Event.Severity.CRITICAL, "server down");
//calendar.add(Calendar.MINUTE, 4);
Event event2 = new Event("e2", new Date(), "server1",
Event.Severity.CRITICAL, "server down");
//calendar.add(Calendar.MINUTE, 6);
Event event3 = new Event("e3", new Date(), "server1",
Event.Severity.CRITICAL, "server down");
//calendar.add(Calendar.MINUTE, 2);
Event event4 = new Event("e4", new Date(), "server1",
Event.Severity.CRITICAL, "server down");
eventsEP.insert(event1);
clock.advanceTime(4, TimeUnit.MINUTES);
eventsEP.insert(event2);
clock.advanceTime(6, TimeUnit.MINUTES);
eventsEP.insert(event3);
clock.advanceTime(2, TimeUnit.MINUTES);
eventsEP.insert(event4);
ksession.fireAllRules();
我希望e1能够通过规则,因为它没有先前的事件。我还希望e3能够通过,因为前一个事件已经过了6分钟。
但是,我得到了不同的输出:
期待输出
但我正在
添加信息:我正在使用STREAM模式进行事件处理。 任何人都可以解释输出,并告诉我我错在哪里。谢谢!
答案 0 :(得分:0)
我确定你做到了,但只是想检查你是否明确将时钟类型设置为伪而不是默认的实时:
KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
config.setOption( ClockTypeOption.get("pseudo") );
在多次调用advanceTime()之后,调用fireAllRules()一次也可能存在问题。您可能希望在单独的线程中运行fireUntilHalt(),或者在每次调用advanceTime()之后调用fireAllRules()。看看这个链接:
答案 1 :(得分:0)
使用您提供的代码,我得到预期的输出:
事件引起的严重警报:e1
Drools的版本:5.5.0-final