Drools 在规则的条件下使用retract的问题

Drools 在规则的条件下使用retract的问题,drools,drools-fusion,Drools,Drools Fusion,我正在尝试编写一个规则,以检测给定事件在最后一个“m”持续时间内是否发生了“n”次。 我正在使用drools版本5.4.Final。我也试过5.5.Final,但没有效果 我发现有两个条件元素,Drools称之为累积和收集。我在下面的示例规则中使用了collect rule "check-login-attack-rule-1" dialect "java" when $logMessage: LogMessage() $logMessages : ArrayList ( siz

我正在尝试编写一个规则,以检测给定事件在最后一个“m”持续时间内是否发生了“n”次。 我正在使用drools版本5.4.Final。我也试过5.5.Final,但没有效果

我发现有两个条件元素,Drools称之为累积和收集。我在下面的示例规则中使用了collect

rule "check-login-attack-rule-1"
dialect "java"
when
    $logMessage: LogMessage()
    $logMessages : ArrayList ( size >= 3 ) 
                    from collect(LogMessage(getAction().equals(Action.Login) 
                    && isProcessed() == false) 
                    over window:time(10s))
then
    LogManager.debug(Poc.class, "!!!!! Login Attack detected. Generating alert.!!!"+$logMessages.size());
    LogManager.debug(Poc.class, "Current Log Message: "+$logMessage.getEventName()+":"+(new Date($logMessage.getTime())));
    int size = $logMessages.size();
    for(int i = 0 ; i < size; i++) {
        Object msgObj = $logMessages.get(i);
        LogMessage msg = (LogMessage) msgObj;
        LogManager.debug(Poc.class, "LogMessage: "+msg.getEventName()+":"+(new Date(msg.getTime())));
        msg.setProcessed(true);
        update(msgObj); // Does not work. Rule execution does not proceed beyond this point.
        // retract(msgObj) // Does not work. Rule execution does not proceed beyond this point.
    }
    // Completed processing the logs over a given window. Now removing the processed logs.
    //retract($logMessages) // Does not work. Rule execution does not proceed beyond this point.
有了这个,我能做的就是在最后10秒内检查是否存在上述日志消息。我还可以找到触发规则的前10秒内发生的日志消息的确切集合

问题是,一旦这些消息被处理,它们就不应该参与下一个评估周期。这是我无法实现的。我将举例说明这一点

考虑下面的时间线,该时间线显示日志消息的插入和应发生的警报生成状态

预期结果

--日志--警报

0--日志消息1--无警报

3--日志消息2--无警报

6--日志消息3--警报1(日志消息1、日志消息2、日志消息3)

9--日志消息4--无警报

12--日志消息5--无警报

15—日志消息6—警报2(日志消息4、日志消息5、日志消息6)

但当前代码的作用是

实际结果

--日志--警报

0--日志消息1--无警报

3--日志消息2--无警报

6--日志消息3--警报1(日志消息1、日志消息2、日志消息3)

9--日志消息4--警报2(日志消息2、日志消息3、日志消息4)

12--日志消息5--警报3(日志消息3、日志消息4、日志消息5)

15—日志消息6—警报4(日志消息4、日志消息5、日志消息6)

基本上,我无法丢弃已经处理并参与警报生成的消息。我试图使用收回从它的工作记忆中删除处理过的事实。但是,当我在规则的然后部分中添加retract时,规则完全停止了触发。我无法理解为什么规则在添加收回后停止触发


请告诉我哪里出了问题

您似乎忘记了将列表中的其他3个事实设置为已处理。您需要一个助手类作为全局类来执行此操作,因为它应该在for循环中完成。否则,这些消息组也会触发规则:

1无触发 1,2无触发 1,2,3触发器 2,3,4个触发器,因为添加了一个新事实,并且2和3在列表中 3,4,5个触发器,因为添加了一个新事实,3和4在列表中

等等

希望这有助于类似的讨论
        final StatefulKnowledgeSession kSession = kBase.newStatefulKnowledgeSession();
        long msgId = 0;
        while(true) {
            // Generate Log messages every 3 Secs.
            // Every alternate log message will satisfy a rule condition
            LogMessage log = null;
            log = new LogMessage();
            log.setEventName("msg:"+msgId);
            log.setAction(LogMessage.Action.Login);
            LogManager.debug(Poc.class, "PUSHING LOG: "+log.getEventName()+":"+log.getTime());
            kSession.insert(log);
            kSession.fireAllRules();
            LogManager.debug(Poc.class, "PUSHED LOG: "+log.getEventName()+":"+(new Date(log.getTime())));
            // Sleep for 3 secs
            try {
                sleep(3*1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            msgId++;
        }