Drools:drools事件处理有问题

时间:2012-04-09 07:21:13

标签: drools

我对流口水很新。

我正在开发一个应用程序,我的drools引擎每秒都会获得一系列事件。我需要查看过去10秒内的所有事件是否具有低于10的属性值,如果条件为真,我必须进行一些处理。以下是我尝试过的示例代码,请帮助我理解并解决问题。

我的规则文件.....

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;


declare Employee 
@role (event)
@expires(10s)
end

// Using timer to ensure rule processing starts only after 10 secs, 
//else processing starts as soon as first event comes in
rule "Test Timer"
no-loop true
10timer(int: 5s)
when
$E : Employee()
$total : Number( doubleValue < 1 ) 
    from accumulate( Employee( Age > 10 ), count() )
then 
   System.out.println(  $E.getName() + " is crossing the threshold of 20");
retract($E);
end

主要课程

// import classes removed from here...
public class MainClass {

/**
 * @param args
 */
public static void main(String[] args){

    //Create KnowledgeBase...
    KnowledgeBase knowledgeBase = createKnowledgeBase();

    //Create a stateful session
    StatefulKnowledgeSession session = knowledgeBase.newStatefulKnowledgeSession();
//  KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(session);
    try {

        // Using random generator to simulate the data.
        int randomInt=0;
        Random randomGenerator = new Random();
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date date = null; 

        while (true) {
            Thread.sleep(1000);
            date = new Date();
            randomInt = randomGenerator.nextInt(12);

            //Create Facts and insert them      
            Employee emp = new Employee();
            emp.setName("Anurag" + randomInt);
            emp.setAge(randomInt);

            //LOAD THE FACT AND FIREEEEEEEEEEEEEEEEEEE............
            System.out.println(dateFormat.format(date)+ " => Random no " + randomInt);
            session.insert(emp);
            session.fireAllRules();
        } 

    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        session.dispose();
    }
}

    /**
    * Create new knowledge base
    */
private static KnowledgeBase createKnowledgeBase() {
    KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
            //Add drl file into builder
    File drl = new File("D:\\eclipse\\worspace\\Research\\misc\\testforall.drl");
    builder.add(ResourceFactory.newFileResource(drl), ResourceType.DRL);
    if (builder.hasErrors()) {
        System.out.println(builder.getErrors().toString());
        //throw new RuntimeException(builder.getErrors().toString());
    }

    KnowledgeBase knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
            //Add to Knowledge Base packages from the builder which are actually the rules from the drl file.
    knowledgeBase.addKnowledgePackages(builder.getKnowledgePackages());
    KnowledgeBaseConfiguration config = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();

    config.setOption( EventProcessingOption.STREAM );
    return knowledgeBase;
}
}

public class Employee {
private String Name;
private int Age;
// getter - setters
}

2 个答案:

答案 0 :(得分:2)

您检查了Drools Fusion文档吗? 首先,员工听起来并不是一个好主意。事件是与您的域相关的某些事件的状态的有意义的更改。因此,事件可能是员工到达办公室或离开时间的时间,但员工本身是一个域实体(或规则引擎的事实)而非事件。 如果您对使用Drools融合时间运算符感兴趣,我建议您阅读有关滑动窗口(时间窗口)的信息,这样您就可以看到过去十秒内发生的事情。您不需要使用计时器。 干杯

答案 1 :(得分:1)

如果你这样做的话,你忘了告诉你发生了什么事。

如果你的实体设置不是很大,我认为这个问题可以通过基础Drools发行版轻松解决。

我有一个与你相似的应用程序,并为我工作:

rule "Clear only auxiliar fact"
  salience 1
  when
    af: AuxFact()
  then
    DroolsRepository.retractFact(af);
end

rule "Clear auxiliar fact and an old meaningful fact"
  salience 1000
  when 
    af: AuxFact()
    mf: MeaningfulFact()
  then
    if(DroolsRepository.getCurrentTimeMillis() - tmf.getCreationDate().getTime() > 5000){
      DroolsRepository.retractFact(af);
      DroolsRepository.retractFact(mf);
      // YOUR MEANINGFUL CODE
    }
    else{
      DroolsRepository.retractFact(af);}
end

query "getAllFacts"
  $result: Fact()
end

// Boot rules re-executing thread.
new Thread(new Runnable(){
  public void run(){
  do{
    kSession.insert(new AuxFact());
    try{
      Thread.sleep(99);}
    catch(InterruptedException e){
      e.printStackTrace();}}
  while(true);}
}).start();

类似的方法可能更简单有效。