当前位置: 首页 > 知识库问答 >
问题:

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

缑桐
2023-03-14

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

我发现有几个条件元素,如Drools所说,累积和收集。我在下面的示例规则中使用了收集

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.

终止

注入日志的代码如下所示。该代码每3秒注入一次日志并触发规则。

        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++;
        }

有了这个,我能做的就是在最后10秒内检查上述日志消息是否存在。我还可以找到触发规则的前10秒内发生的日志消息的确切集合。

问题是,一旦这些消息被处理,它们就不应该参与下一个评估周期。这是我无法实现的。我会用例子来解释这个问题。

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

预期成果

秒--日志--警报

0--LogMessage1--无警报

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

6—LogMessage3—警报1(LogMessage1、LogMessage2、LogMessage3)

9--LogMessage4--没有警报

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

15--LogMessage6--Alert2(LogMessage4、LogMessage5、LogMessage6)

但当前代码的情况是

实际结果

秒--日志--警报

0--LogMessage1--无警报

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

6—LogMessage3—警报1(LogMessage1、LogMessage2、LogMessage3)

9—LogMessage4—警报2(LogMessage2、LogMessage3、LogMessage4)

12—LogMessage5—Alert3(LogMessage3、LogMessage4、LogMessage5)

15--LogMessage6--Alert4(LogMessage4, LogMessage5, LogMessage6)

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

请告诉我哪里出了问题。

共有1个答案

姚永年
2023-03-14

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

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

等等

希望这有帮助

 类似资料:
  • 我想达到的,大致可以概括为一个简单的或者有条件的。 虽然使用Fluent验证支持其他属性上的条件属性验证(When/Unless ),但似乎没有一种方法支持同一属性上的条件规则。还是我错过了什么? 本质上我想实现: 唯一的替代方法是将规则组合在一个自定义规则中? 然而,这紧密地耦合了规则逻辑,实际上它们是完全独立的条件,我可能想在其他对象/字段上使用。 有人建议在 FluentValidation

  • 我想运行一个调用Java方法并从另一个规则传递事实(或者更确切地说,它的逻辑值)的规则,尽管我不知道java方法是否对这个问题很重要。描述起来并不容易,所以我将尝试基于一个示例来展示它: 这里的问题是,第一条规则并不总是触发,因此不总是定义某些条件,也不计算第二条规则。 我的第二次尝试是创建这样两个独立的规则: 这也不能像预期的那样工作,因为它首先计算someconditionfalse规则,甚至

  • 我试图使用Bazel编译一个基于dhall-kubernetes的dhall程序来生成一个Kubernetes YAML文件。 不使用dhall-kubernetes的基本dhall编译使用一个简单的bazel宏可以正常工作。 构建。dhall-Kubernetes: 示例/K8S/Build:

  • 我目前正试图建立一个小型应用程序上的firebase作为它的评估。它看起来很有趣,而且超级高效,但我对firestore规则有一个问题。 我有一个集合(游戏),其对象如下所示: 它没有像预期的那样起作用。我希望它允许我列出的文档,但是如果有一个文档我无法,我希望获得“缺少或不足的权限”。我所能做的是列出所有文档,但不直接读取其中一些文档(规则在试图获取单个文档时有效,但在从集合中列出文档时无效)。

  • 我创建了一个规则,其“when”条件如下:- 上述条件运行良好。现在我如何在一个规则中添加多个布尔条件?为(如)。上面的规则可以概括为:a和b,所以如果我想创建一个规则:(a和b)或c,那么它的实际drl语法是什么。我对drools是新手,所以请帮助我了解规则(a和b)或C的语法。 我确实创建了一个语法 错误消息:Message[id=1,level=Error,path=mapiteration