0

我对流口水很陌生。

我正在开发一个应用程序,我的 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
}
4

2 回答 2

2

你检查过 Drools Fusion 文档吗?首先,Employee 对于 Event 来说听起来不是一个好主意。事件是与您的领域相关的事物状态的有意义的变化。因此,事件可能是员工到达办公室的时间或离开的时间,但员工本身是域实体(或规则引擎的事实)而不是事件。如果您对使用 Drools 融合时间算子感兴趣,我建议您阅读有关滑动窗口(时间算子)的内容,这将让您始终了解过去十秒内发生的情况。您不需要为此使用计时器。干杯

于 2012-04-09T16:58:15.813 回答
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();

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

于 2013-06-27T17:48:06.037 回答