2017-03-28 3 views
0

Droolsを擬似時計で実行するにはいくつかの困難があります。 ストリームモードでエンジンを設定し、realModeプロパティで使用するクロックの種類を選択します。Drools 6.5擬似時計

Date refDate = new Date(System.currentTimeMillis()); 
    boolean realMode = false; 
    SessionPseudoClock clock = null; 

    KieServices ks = KieServices.Factory.get(); 

    KieSessionConfiguration config = KieServices.Factory.get().newKieSessionConfiguration(); 
    if(realMode) { 
     config.setOption(ClockTypeOption.get("realtime"));       
    } else { 
     config.setOption(ClockTypeOption.get("pseudo")); 
    } 

    KieContainer kc = ks.getKieClasspathContainer(); 
    KieSession ksession = kc.newKieSession("cep-rules",config); 
    KieRuntimeLogger logger = ks.getLoggers().newFileLogger(ksession, "./out/helloworld"); 

    addNewLogLine (ksession, "GDE" , 0); 
    addNewLogLine (ksession, "GDE" , 11); 
    addNewLogLine (ksession, "GDE" , 3); 
    addNewLogLine (ksession, "GDE" , 8); 

    logger.close(); 

    ksession.dispose(); 

AddNewLogLine機能

if(realMode) { 
     try { 
      Thread.sleep(delaiInSeconds*1000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     }   
    } else { 
     if (clock==null) { 
      clock = ksession.getSessionClock(); 
     } 
     clock.advanceTime(delaiInSeconds, TimeUnit.SECONDS); 
    } 
    delai += delaiInSeconds; 

    LogItem logLine = new LogItem(); 
    logLine.setEventDate(new Date (refDate.getTime()+(delai*1000))); 
    logLine.setMessage("Message number " + count); 
    logLine.setSourceSystemName(sourceSystemName); 

    System.out.println(logLine); 
    ksession.insert(logLine); 

    ksession.fireAllRules(); 

のコードでは、私はアパートに私problemaには関係ありませんいくつかの余分なコードを残します。

ルール:

declare LogItem 
     @role (event) 
     @timestamp(eventDate) 
    end 

    rule "LogInserted" 
     dialect "mvel" 
     when 
      l : LogItem () 
     then 
     System.out.println ("New Log inside from " + l.getSourceSystemName()); 
    end 

    rule "Nb Log SameSystem" 
     dialect "mvel" 
     when 
      accumulate(LogItem (sourceSystemName == "GDE") over window:time(10s) ; $cnt: count(1); $cnt == 2) 
     then 
     System.out.println ("2 Logs in engine"); 
    end 

目的:10秒のウィンドウ内に2つのログ行を検出します。 最初と秒は(11s)ではなく、次の2行、はいです。

リアルモードでは正常に動作します。擬似クロックモードで

LogItem { message : Message number 1, date : 28/03/2017 11:17:26, sourceSystemName : GDE } 
    New Log inside from GDE 
    LogItem { message : Message number 2, date : 28/03/2017 11:17:37, sourceSystemName : GDE } 
    New Log inside from GDE 
    LogItem { message : Message number 3, date : 28/03/2017 11:17:40, sourceSystemName : GDE } 
    New Log inside from GDE 
    2 Logs in engine 
    LogItem { message : Message number 4, date : 28/03/2017 11:17:48, sourceSystemName : GDE } 
    New Log inside from GDE 
    2 Logs in engine 

それ作業を行いません。ここでの結果です。 4行が同じ時間に挿入されるので、2は最初にルールを有効にします。したがって、疑似クロックは使用されません。ここで

は結果である:

LogItem { message : Message number 1, date : 28/03/2017 11:17:26, sourceSystemName : GDE } 
    New Log inside from GDE 
    LogItem { message : Message number 2, date : 28/03/2017 11:17:37, sourceSystemName : GDE } 
    New Log inside from GDE 
    2 Logs in engine 
    LogItem { message : Message number 3, date : 28/03/2017 11:17:40, sourceSystemName : GDE } 
    New Log inside from GDE 
    LogItem { message : Message number 4, date : 28/03/2017 11:17:48, sourceSystemName : GDE } 
    New Log inside from GDE 

私はデ擬似クロックを管理していないからだと仮定します。しかし、私はどこが間違っているのかは分かりません。

誰か? ありがとうございます。

答えて

0

あなたの問題は疑似クロックの誤った操作によるものだと思います。また、最良の結果を得るために、fireUntilHaltを実行し、独自のスレッドでセッションを実行します。

Runnable fireUntilHaltRunnable = new Runnable() { 
    public void run() { 
     //  System.out.println("fireUntilHalt"); 
     kSession.fireUntilHalt() 
    } 
}; 
Thread fireUntilHaltThread = new Thread(fireUntilHaltRunnable); 

事実が別のスレッドから挿入されています。あなたは、擬似クロックでテストを実行している場合は、フィールドとして、タイムスタンプが含まれているイベントを使用している場合は、擬似クロックがイベントのタイムスタンプに設定されていることを確認します

private void advance(Date eventDate){ 
    long currentTime = clock.getCurrentTime(); 
    long eventTime = eventDate.getTime(); 
    clock.advanceTime(eventTime - currentTime, TimeUnit.MILLISECONDS); 
} 

は前にこのを行いますあなたは次の事実を挿入します。インサートの間に寝る必要はありません。