1

I'm new to Drools. I'm trying to write a simple Complex Event Processing (CEP) application using Drools Fusion.

My requirement is

  - 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

I have a simple Event class which is as follows:

public class Event {

    private String id;
    private Date timestamp;
    private String source;
    private Event.Severity severity;
    private String description;

 /// With Getter and Setter ///

}

The rules file is as follows:

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

For testing, I'm injecting 4 events to the working memory - e1, e2, e3, e4 respectively with the following timeline 0m, 4m, 10m, 12m.

Jave Class File

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();

I expect e1 to pass the rule since it has no preceding event. I also expect e3 to pass since the preceding event is away by 6 minutes.

However, I get a different output:

Expecting Output

  • CRITICAL alert caused by event: e1
  • CRITICAL alert caused by event: e3

But I am getting

  • CRITICAL alert caused by event: e1
  • CRITICAL alert caused by event: e2
  • CRITICAL alert caused by event: e3

Addition information: I'm using STREAM mode for event processing. Can anyone please explain the output and tell me where I'm wrong. Thanks!

Prog_G
  • 1,539
  • 1
  • 8
  • 22
Mohankumar D
  • 63
  • 1
  • 2
  • 8

2 Answers2

0

I'm sure you did, but just wanted to check that you explicitly set the clock type to pseudo and not the default realtime:

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

There may also be an issue with just calling fireAllRules() once after multiple calls to advanceTime(). You may want to run fireUntilHalt() in a separate thread or call fireAllRules() after each call to advanceTime(). Check out this link:

Drools Fusion Samples

JohnFullard
  • 177
  • 5
0

With the codes provided by you, I get the expected output:

CRITICAL alert caused by event: e1
CRITICAL alert caused by event: e3


version of Drools: 5.5.0-final

Tan Hui Onn
  • 424
  • 4
  • 8