2012-09-09 24 views
2

Ciao,我已經通過多種方式進行了測試,但是我仍然無法測試和驗證Drools Fusion中的事件過期機制,所以我正在尋找一些小指導?Drools Fusion CEP中的測試事件過期Ciao

我已經閱讀手冊,我對此功能感興趣:

換言之,一個事件被插入到工作內存,可以使發動機以找出當事件不能再匹配其他事實並自動收回它,釋放其相關資源。

我使用Drools的IDE Eclipse中,5.4.0.Final和我修改的「新的Drools項目」嚮導創建測試和驗證的事件到期模板代碼。

下面的代碼。我的理解,使「生命週期」,以正確的工作方式是:

  • 你必須設置的KBase流模式 - 檢查
  • 必須插入按照時間順序的活動 - 檢查
  • 你必須定義事件之間的時間限制 - 檢查我的情況是最後一條消息()

但是,當我在最後檢查EventFactHandle時,沒有任何Event()已過期。 感謝您的幫助。

的Java:

public class DroolsTest { 

    public static final void main(String[] args) { 
     try { 
      KnowledgeBase kbase = readKnowledgeBase(); 
      // I do want the pseudo clock 
      KnowledgeSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(); 
      conf.setOption(ClockTypeOption.get("pseudo")); 
      StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(conf, null); 
      SessionPseudoClock clock = ksession.getSessionClock(); 
      KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); 
      // Insert of 2 Event: 
      Message message = new Message(); 
      message.setMessage("Message 1"); 
      message.setStatus(Message.HELLO); 
      ksession.insert(message); 
      ksession.fireAllRules(); 
      clock.advanceTime(1, TimeUnit.DAYS); 
      Message message2 = new Message(); 
      message2.setMessage("Message 2"); 
      message2.setStatus(Message.HELLO); 
      ksession.insert(message2); 
      ksession.fireAllRules(); 
      clock.advanceTime(1, TimeUnit.DAYS); 
      ksession.fireAllRules(); 
      // Now I do check what I have in the working memory and if EventFactHandle if it's expired or not: 
      for (FactHandle f : ksession.getFactHandles()) { 
       if (f instanceof EventFactHandle) { 
        System.out.println(((EventFactHandle)f)+" "+((EventFactHandle)f).isExpired()); 
       } else { 
        System.out.println("not an Event: "+f); 
       } 
      } 
      logger.close(); 
     } catch (Throwable t) { 
      t.printStackTrace(); 
     } 
    } 

    private static KnowledgeBase readKnowledgeBase() throws Exception { 
     KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); 
     kbuilder.add(ResourceFactory.newClassPathResource("Sample.drl"), ResourceType.DRL); 
     KnowledgeBuilderErrors errors = kbuilder.getErrors(); 
     if (errors.size() > 0) { 
      for (KnowledgeBuilderError error: errors) { 
       System.err.println(error); 
      } 
      throw new IllegalArgumentException("Could not parse knowledge."); 
     } 
     KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); 
     kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); 
     // following 2 lines is the template code modified for STREAM configuration 
     KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration(); 
     config.setOption(EventProcessingOption.STREAM); 
     return kbase; 
    } 

    /* 
    * This is OK from template, as from the doc: 
    * By default, the timestamp for a given event is read from the Session Clock and assigned to the event at the time the event is inserted into the working memory. 
    */ 
    public static class Message { 

     public static final int HELLO = 0; 
     public static final int GOODBYE = 1; 

     private String message; 

     private int status; 

     public String getMessage() { 
      return this.message; 
     } 

     public void setMessage(String message) { 
      this.message = message; 
     } 

     public int getStatus() { 
      return this.status; 
     } 

     public void setStatus(int status) { 
      this.status = status; 
     } 

    } 

} 

的Drools:

package com.sample 

import com.sample.DroolsTest.Message; 

declare Message 
@role(event) 
end 

declare window LastMessageWindow 
    Message() over window:length(1) 
end 

rule "Hello World" 
    when 
     accumulate($m : Message(status==Message.HELLO) from window LastMessageWindow, 
       $messages : collectList($m)) 
    then 
     System.out.println(((Message)$messages.get(0)).getMessage()); 
end 

請注意:即使我添加1秒到消息事件到期後,

@expires(1s) 

我還是不得到預期的結果,即插入第一個Message事件,我預料現在已過期?謝謝你的幫助。

回答

3

找到解決方案!顯然,這是我愚蠢,沒有意識到我正在使用Drools 5.4.0.Final,同時仍然參考5.2.0.Final的舊文檔。在Drools Fusion 5.4.0.Final的更新文檔中,此框添加爲2.6.2。滑動長度窗口

請注意,基於長度的窗口不會爲會話中的事件到期定義時間限制,並且引擎不會考慮它們。如果事件沒有其他規則來定義時間限制並且沒有明確的過期策略,那麼引擎將無限期地保持它們在會話中。

所以我最初招募的「你必須定義事件之間的時間限制」第三要求顯然沒有得到滿足,因爲我現在明白了滑動長度窗口在Drools中5.4.0.Final:

Message() over window:length(1) 

是實際上不是會話中事件到期的時間約束的定義。

更新此答覆希望有人會發現它有幫助。此外,爲了您的所知,我實際上是愚蠢的依靠Google搜索來達到文檔,有時您不會重定向到當前版本文檔,所以它似乎...