2

特定のイベントが最後の「m」の期間に「n」回発生したかどうかを検出するルールを作成しようとしています。私はdroolsバージョン5.4.Finalを使用しています。5.5.Finalも試しましたが効果はありません。

Droolsがそれを呼んでいるように、いくつかの条件付き要素があり、蓄積して収集することがわかりました。以下のサンプルルールでcollectを使用しました

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秒間に上記のLogMessageの存在を確認することです。また、ルールをトリガーする最後の10秒間に発生したLogMessageの正確なセットを見つけることもできました。

問題は、これらのメッセージが処理されたら、次の評価サイクルに参加してはならないということです。これは私が達成できなかったことです。これを例を挙げて説明します。

以下のタイムラインを検討してください。タイムラインには、ログメッセージの挿入と、発生する必要のあるアラート生成の状態が表示されます。

期待される結果

- ログ - アラート

0-LogMessage1-アラートなし

3--LogMessage2-アラートなし

6 --LogMessage3 --Alert1(LogMessage1、LogMessage2、LogMessage3)

9--LogMessage4-アラートなし

12--LogMessage5-アラートなし

15 --LogMessage6-Alert2(LogMessage4、LogMessage5、LogMessage6)

しかし、現在のコードで何が起こっているのか

実結果

- ログ - アラート

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)

基本的に、すでに処理されてアラート生成に参加しているメッセージを破棄することはできません。リトラクトを使用して、処理されたファクトを作業メモリーから削除しようとしました。しかし、ルールのその部分にリトラクトを追加すると、ルールはまったく実行されなくなりました。リトラクトを追加した後、ルールの実行が停止する理由を理解できませんでした。

どこがおかしいのか教えてください。

4

1 に答える 1