2012-09-09 22 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搜索来达到文档,有时您不会重定向到当前版本文档,所以它似乎...