1

我是 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

我有一个简单的事件类,如下所示:

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 分钟。

但是,我得到了不同的输出:

期望输出

  • 事件引起的 CRITICAL 警报:e1
  • 由事件引起的 CRITICAL 警报:e3

但我越来越

  • 事件引起的 CRITICAL 警报:e1
  • 由事件引起的 CRITICAL 警报:e2
  • 由事件引起的 CRITICAL 警报:e3

补充信息:我正在使用 STREAM 模式进行事件处理。谁能解释一下输出并告诉我哪里错了。谢谢!

4

2 回答 2

0

我确定您做到了,但只是想检查您是否将时钟类型明确设置为伪而不是默认实时:

KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
config.setOption( ClockTypeOption.get("pseudo") );

在多次调用advanceTime() 之后只调用一次fireAllRules() 也可能存在问题。您可能希望在单独的线程中运行 fireUntilHalt() 或在每次调用 advanceTime() 后调用 fireAllRules()。看看这个链接:

Drools 融合样品

于 2013-07-24T17:38:30.080 回答
0

使用您提供的代码,我得到了预期的输出:

由事件引起的 CRITICAL 警报:e1 由事件
引起的 CRITICAL 警报:e3


Drools 版本:5.5.0-final

于 2013-12-06T17:38:49.483 回答