Drools fusion не запускает правила в случае нового события

Я работаю над финальной версией 6.2 drools fusion и хочу активировать правила в случае нового события в потоковом режиме. Но правила не стреляют сами по себе.

Содержимое файла моих правил выглядит следующим образом:

//created on: May 8, 2015
package com.test

import com.test.Applicant
declare Applicant
   @role(event)
end

rule "Your First Rule"
when
    accumulate( $st : Applicant(age: age) over window:time(10ms) from      entry-point X , $c: average ( age ) )
then
    System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~avg~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    System.out.println($c);
    System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~avg~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
end

И код следующим образом:

package com.test;

import org.kie.api.KieBaseConfiguration;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSessionConfiguration;
import org.kie.api.runtime.conf.ClockTypeOption;
import org.kie.api.runtime.rule.EntryPoint;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.runtime.StatefulKnowledgeSession;

@SuppressWarnings("deprecation")
public class DroolsTest {


    public DroolsTest() {
        KieBaseConfiguration config_time = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
        config_time.setOption(EventProcessingOption.STREAM);

        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(ResourceFactory.newClassPathResource("test.drl", getClass()), ResourceType.DRL);
        if (kbuilder.hasErrors()) {
            System.out.println("EERRRRRRRROOOOOORRRR");
            System.out.println(kbuilder.getErrors().toString());
            System.out.println("EERRRRRRRROOOOOORRRR");
        }

        KieBaseConfiguration kBaseConfig = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();

        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(kBaseConfig);
        kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

        KieSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
        conf.setOption(ClockTypeOption.get("REALTIME"));
        final StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(conf, null);
        final EntryPoint atmStream = ksession.getEntryPoint("X");

        for (int i = 0; i < 100; i++) {
            System.out.println("LOOOOOOOOOOOOOOOOOOOOP  " + i);
            Applicant applicant = new Applicant("Mr John Smith " + i, i);
            atmStream.insert(applicant);
//          ksession.fireAllRules();
        }
        ksession.dispose();
    }

    public static void main(String[] args) {
        new DroolsTest();
    }

}

Правила срабатывают при преднамеренном вызове, но не срабатывают в случае нового события в потоке.


person Ankit Varshney    schedule 28.05.2015    source источник


Ответы (2)


Если вы не вызовете fireAllRules, вы не увидите никакого эффекта правил. Раскомментируйте эту строку:

ksession.fireAllRules();

Хотя запускать сессию с повторными вызовами fireAllRules — не лучший вариант. Лучше использовать поток для вызова fireUntilHalt, например.

    new Thread() {
        @Override
        public void run() {
            kieSession.fireUntilHalt();
        }
    }.start();

и вставлять события из другого потока, например, из цикла при имитации событий и течения времени с помощью Thread.sleep или чтения событий из внешнего источника.

person laune    schedule 28.05.2015
comment
Но я хочу сделать сложную обработку событий на основе скользящего окна. И каждый раз вызывать fireAllRules не получится. - person Ankit Varshney; 28.05.2015
comment
Я показал вам альтернативу: использование fireUntilHalt в отдельном потоке — это способ сделать это. - person laune; 28.05.2015
comment
В приведенном выше коде правил определено окно, основанное на времени. Таким образом, решение использовать поток не работает - person Ankit Varshney; 29.05.2015
comment
Кажется, вы не понимаете Drools CEP. Поверьте мне, это работает. - person laune; 29.05.2015

Похоже, у вас есть 2 определенные конфигурации KieBaseConfigurations. config_time.setOption(EventProcessingOption.STREAM); настроен для потоковой передачи, но никогда не используется.

Попробуйте установить EventProcessingOption.STREAM в kBaseConfig, который вы фактически используете.

person Andrew Davis    schedule 29.05.2015