[rules-users] Implementation of my use case - what am I doing wrong?

Elran Dvir elrand at checkpoint.com
Sun Sep 15 08:22:45 EDT 2013


Hi all,

A few weeks ago I posted a question about my use case to the mailing list. The correspondence is attached.
This is the example of the use case I implemented:


Port scan event - the basic event is connection log. For each combination

of source_ip and destination_ip, detect a port scan event,
if over 5 seconds there were more than 2 connection logs with

different ports .

The event will stay open for 10 seconds and an update will be

sent for any new port detected. Every update will contain the count of
connection logs combining it and their id ("marker").

the drl fie:

package test;

import correlation.impl.drools.Log
import correlation.impl.drools.CorrelatedEvent

global correlation.server.EventsHandler externalEventsHandler;

declare Log
      @role( event)
end

declare CorrelatedEvent
        @role( event)
        @timestamp( getTimestamp().getTime() )
        @expires( 10s )
        @duration( getDuration() )
end

// this rule will create a "Port Scan" event if none exist for this group-by values
rule "Create Port Scan Event"
dialect "java"
no-loop
when
  $log : Log() from entry-point "Log stream" //get all the logs in the last 5 seconds
  accumulate( Log( this after[0s,5s] $log, fieldsMap.get("src") == $log.fieldsMap.get("src") , fieldsMap.get("dst") == $log.fieldsMap.get("dst"), $port : fieldsMap.get("port")) from entry-point "Log stream";
                                $portSet : collectSet($port);
                                $portSet.size > 2 )
  accumulate( Log( this after[0s,5s] $log, fieldsMap.get("src") == $log.fieldsMap.get("src") , fieldsMap.get("dst") == $log.fieldsMap.get("dst"), $marker : fieldsMap.get("marker")) from entry-point "Log stream";
                                $markerSet : collectSet($marker))
  not CorrelatedEvent(getName() == "portScan" , fieldsMap.get("src") == $log.fieldsMap.get("src") , fieldsMap.get("dst") == $log.fieldsMap.get("dst"))
then
  System.out.println(drools.getRule().getName());

  CorrelatedEvent $ce = new CorrelatedEvent();
  $ce.setName("portScan");
  $ce.setEventsHandler(externalEventsHandler);
  $ce.setDurationInSec(10);
  $ce.fieldsMap.put("src", $log.fieldsMap.get("src"));
  $ce.fieldsMap.put("dst", $log.fieldsMap.get("dst"));
  $ce.endUpdate($markerSet);

  insert($ce);
end

rule "Create Port Scan Event - update"
dialect "java"
no-loop
when
  $ce: CorrelatedEvent(getName() == "portScan")
  accumulate( Log(fieldsMap.get("src") == $ce.fieldsMap.get("src") , fieldsMap.get("dst") == $ce.fieldsMap.get("dst") , $port : fieldsMap.get("port") , (this meets $ce || this during $ce || this metby $ce)) from entry-point "Log stream";
                                $portSet : collectSet($port);
                                $portSet.size > 0 )
  accumulate( Log(fieldsMap.get("src") == $ce.fieldsMap.get("src") , fieldsMap.get("dst") == $ce.fieldsMap.get("dst") , $marker : fieldsMap.get("marker") , (this meets $ce || this during $ce || this metby $ce)) from entry-point "Log stream";
                                $markerSet : collectSet($marker))
then
  System.out.println(drools.getRule().getName());

  modify( $ce ) {endUpdate($markerSet)}
end

my questions:

1)      If I have only one stream of data , can I omit the use of entry point and insert logs to the session ? Or the use of entry points is mandatory in Drools Fusion?

2)       When I tested it with matching data, rule "Create Port Scan Event - update" was never fired. When I replaced "(this meets $ce || this during $ce || this metby $ce)" with "this after $ce.getStartTime() , this before $ce.getEndTime()" everything worked fine.
Why?

3)      I tried to use sliding windows in  rule "Create Port Scan Event" and an exception was thrown at runtime. I decided to use "this after[0s,5s] $log" instead. Is it correct?

4)      Is my basic Implementation correct?

Thank you all very much.

Log class:

public class Log {
    public HashMap<String, Object> fieldsMap = new HashMap<>();
}

CorrelatedEvent class:

public class CorrelatedEvent
{
    public Map<String, Object> fieldsMap;
    private String name;
    private Set<String> markersSet;
    private long logsCount;
    private Calendar startTime;
    private Calendar endTime;
    private int duration;
    private EventsHandler eventsHandler;

    public CorrelatedEvent()
    {
        startTime = Calendar.getInstance();
        endTime = Calendar.getInstance();
        endTime.setTime(startTime.getTime());
        fieldsMap = new HashMap<>();
        markersSet = new HashSet<>();
        logsCount = 0;
    }

                public Date getTimestamp()
    {
        return startTime.getTime();
    }

                public Date getStartTime()
    {
        return startTime.getTime();
    }

                public Date getEndTime()
    {
        return endTime.getTime();
    }

    public void setDurationInSec(int duration)
    {
        this.duration = duration;
        endTime.setTime(startTime.getTime());
        endTime.add(Calendar.SECOND, duration);
    }

    public int getDuration()
    {
        return duration;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
        fieldsMap.put("name", name);
    }

    public void setEventsHandler(EventsHandler eventsHandler)
    {
        this.eventsHandler = eventsHandler;
    }

    public void endUpdate(Set<String> markersSet)
    {
        this.markersSet.addAll(markersSet);
        if (this.markersSet.size() > logsCount) {
            logsCount = this.markersSet.size();
            if (eventsHandler == null)
                return;
            Map<String, Object> clonedFieldsMap = getClonedFieldsMap();
            clonedFieldsMap.put("markers", this.markersSet.toString()); //need  a function that converts a set of markers to a "\n" separated list
            clonedFieldsMap.put("count", logsCount);
            eventsHandler.handleEvent(clonedFieldsMap);
        }
    }

    private Map<String, Object> getClonedFieldsMap()
    {
        Map<String, Object> clonedFieldsMap = new HashMap<>();
        clonedFieldsMap.putAll(fieldsMap);

        return clonedFieldsMap;
    }

}


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20130915/1f193360/attachment-0001.html 
-------------- next part --------------
An embedded message was scrubbed...
From: Wolfgang Laun <wolfgang.laun at gmail.com>
Subject: Re: [rules-users] Is my use case suuported in Drools?
Date: Tue, 13 Aug 2013 09:53:59 +0000
Size: 10177
Url: http://lists.jboss.org/pipermail/rules-users/attachments/20130915/1f193360/attachment-0001.mht 


More information about the rules-users mailing list