Я пытаюсь написать правило, чтобы определить, произошло ли какое-либо событие за число «n» в последнем «m» времени. Я использую drools версии 5.4.Final. Я также попробовал 5.5.Final без эффекта.Проблемы с использованием retract in then condition of rule
Я обнаружил, что есть несколько условных элементов, так как 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++;
}
С этим я мог бы проверить наличие вышеупомянутого LogMessage за последние 10 секунд. Я мог бы также узнать точный набор LogMessages, который произошел за последние 10 секунд, вызвав правило.
Проблема в том, что после обработки этих сообщений они не должны участвовать в следующем цикле оценки. Это то, чего я не смогу достичь. Я объясню это на примере.
Рассмотрите временную шкалу ниже, Временная шкала показывает вставку сообщений журнала и состояние генерации предупреждений, которое должно произойти.
Ожидаемый результат
Secs - Log - оповещения
0 - LogMessage1 - Нет оповещения
3 - LogMessage2 - Нет оповещения
6 - LogMessage3 - Alert1 (L ogMessage1, LogMessage2, LogMessage3)
9 - LogMessage4 - Нет оповещения
12 - LogMessage5 - Нет оповещения
15 - LogMessage6 - Alert2 (LogMessage4, LogMessage5, LogMessage6)
Но Что происходит с текущего кода
Фактический результат
Secs - Вход - оповещения
0 - LogMessage1 - Нет оповещения
3 - LogMessage2 - Нет оповещения
6 - LogMessage3 - Alert1 (LogMessage1, LogMessage2, LogMessage3)
9 - LogMessage4 - Alert2 (LogMessage2, LogMessage3, LogMessage4)
12 - LogMessage5 - Alert3 (LogMessage3, LogMessage4, LogMessage5)
15 - LogMessage6 - Alert4 (LogMessage4, LogMessage5, LogMessage6)
По существу, я не в состоянии отказаться от сообщений, которые уже обработаны и приняли участие в генерации предупреждений. Я попытался использовать retract, чтобы удалить обработанные факты из своей рабочей памяти. Но когда я добавил retract в , то часть правила, правила прекратили стрельбу вообще. Я не смог понять, почему правила прекращают стрельбу после добавления retract.
Пожалуйста, дайте мне знать, где я буду не так.