Проблемы с использованием retract в тогдашнем состоянии правила
Я пытаюсь написать правило, чтобы определить, произошло ли данное событие в течение "n" раз за последний "m" промежуток времени. Я использую слюни версии 5.4. Наконец. Я также попробовал 5.5. Финал без эффекта.
Я обнаружил, что есть пара Условных Элементов, как называет это Друлы, которые накапливаются и накапливаются. Я использовал коллекцию в моем примере правила ниже
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 - Alert
0 - LogMessage1 - Нет оповещения
3 - LogMessage2 - Нет оповещения
6 - LogMessage3 - Alert1 (LogMessage1, LogMessage2, LogMessage3)
9 - LogMessage4 - Нет оповещения
12 - LogMessage5 - Нет оповещения
15 - LogMessage6 - Alert2 (LogMessage4, LogMessage5, LogMessage6)
Но что происходит с текущим кодом
Фактический результат
Secs - Log - Alert
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, чтобы удалить обработанные факты из своей рабочей памяти. Но когда я добавил ретракт в тогдашнюю часть правила, правила перестали срабатывать вообще. Я не смог понять, почему правила перестают срабатывать после добавления ретракта.
Пожалуйста, дайте мне знать, где я иду не так.
1 ответ
Вы, кажется, забыли установить как обработанные остальные 3 факта в списке. Для этого вам понадобится вспомогательный класс как глобальный, потому что это должно быть сделано в цикле for. В противном случае эти группы сообщений также могут вызывать правило:
1 нет триггера 1,2 нет триггера 1,2,3 триггера 2,3,4 триггера, потому что добавлен новый факт, и 2 и 3 были в списке 3,4,5 триггера, потому что добавлен новый факт, а 3 и 4 были в списке
и так далее
надеюсь это поможет