Проблемы с использованием 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 были в списке

и так далее

надеюсь это поможет

Другие вопросы по тегам