我正在尝试编写一个规则,以检测给定事件在最后一个“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时,规则就完全停止了。我一直无法理解为什么规则在添加了收回后会停止触发。
请告诉我哪里出了问题。
您似乎忘记了将列表中的其他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