2012-04-09 4 views
0

나는 졸졸을 아주 좋아합니다.Drools : drools 이벤트 처리에 문제가 있습니다.

내 drools 엔진이 일련의 이벤트를 매초마다 얻을 수있는 응용 프로그램을 만들고 있습니다. 지난 10 초 동안의 모든 이벤트에 속성 값이 10 미만인지 확인해야합니다. 조건이 true이면 일부 처리를해야합니다. 여기에 제가 시도한 예제 코드가 있습니다. 제발 이해를 돕고 문제를 해결하십시오.

내 규칙 파일

.....

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

당신은 Drools가 퓨전 설명서를 확인 했습니까? 우선 Employee는 이벤트에 좋은 아이디어로 들리지 않습니다. 이벤트는 도메인과 관련된 무언가의 의미있는 변화입니다. 따라서 이벤트는 직원이 사무실에 도착할 시간 또는 출발 시간이 될 수 있지만 직원 자체는 이벤트가 아닌 도메인 엔터티 (또는 규칙 엔진의 사실)입니다. Drools fusion temporal operators를 사용하고 싶다면 슬라이딩 윈도우 (temporal ones)에 대해 읽어 보는 것이 좋습니다. 그러면 시간이 지난 10 초 동안의 상황을 항상 볼 수 있습니다. 타이머를 사용할 필요가 없습니다. 환호

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(); 

유사한 접근 방식

이 간단하고 효과적 일 수있다 :

나는 나를 위해 당신과 작품 유사한 응용 프로그램을 가지고있다.