2013-02-28 2 views
2

Я пытаюсь написать правило, чтобы определить, произошло ли какое-либо событие за число «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.

Пожалуйста, дайте мне знать, где я буду не так.

ответ

0

Возможно, вы забыли установить как обработанные другие 3 факта в списке. Для этого вам понадобится класс-помощник, как глобальный, потому что это должно быть сделано в цикле for.В противном случае, эти группы сообщений не могут вызвать правило, а также:

-не вызывая 1,2 нет triggerning 1,2,3 не вызывает 2,3,4 триггера, потому что новый факт добавляются и 2 и 3 были в списке 3,4,5 вызывает, потому что новый факт добавляется и 3 и 4 были в списке

и так далее

надеюсь, что это помогает