как правильно запускать правила Drools для нескольких объектов? - PullRequest
0 голосов
/ 22 мая 2019

Я впервые попадаю на Drools (с Java), и я совершенно запутался из-за его сессий и способности работать с коллекциями объектов. это тот случай:

Я создаю веб-приложение, основанное на отдыхе.

У меня есть класс с именем Log с двумя полями (eventType и RiskLevelId).

Mycode извлекает из БД несколько таких объектов в определенный период времени.

Если эта коллекция объектов содержит один Log с eventType == 2 и RiskLevelId == 1 и другой Log с eventType == 3 и RiskLevelId == 1, правило должно выполняться.

Через интерфейсы Drools я правильно получаю KieServices, KieBuilder, KieContaier, KieBase и KieSession.

try {
        // load up the knowledge base
        KieServices kieServices = KieServices.Factory.get();
        KieFileSystem kfs = kieServices.newKieFileSystem();
        FileInputStream fis = f;
        kfs.write( "src/main/resources/simple.drl",
                kieServices.getResources().newInputStreamResource( fis ) );
        KieBuilder kieBuilder = kieServices.newKieBuilder( kfs ).buildAll();
        Results results = kieBuilder.getResults();
        if( results.hasMessages( Message.Level.ERROR ) ){
            System.out.println( results.getMessages() );
            throw new IllegalStateException( "### errors ###" );
        }
        KieContainer kieContainer = kieServices.newKieContainer( kieServices.getRepository().getDefaultReleaseId() );
        KieBase kieBase = kieContainer.getKieBase();
        kieSession = kieContainer.newKieSession();




    }catch (Throwable t) {
        t.printStackTrace();
    }

Затем я получаю каждое значение Log в цикле for. оставаясь в цикле, я также добавляю объект в KieSession и запускаю правило:

@Autowired
KieSessionFactory kieSessionFactory;



@Override
public void run() {

    KieSession kieS =  kieSessionFactory.getKieSessionCheckSavedLog();

    try {
        List<Log> logs = logRepo.getAllInGivenTimeSec(10);
        for(Log l : logs) {
            kieS.insert(l);
            kieS.fireAllRules();
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

Вот правило, которое я написал:

package com.sample 
import it.protodrools.beans.Log;

dialect "java"

rule "log2"
    when
        $l1 : Log( eventType == 2 && riskLevelId == 1);
        $l2 : Log( this != $l1 && eventType == 3 && riskLevelId == 1 );
    then
       System.out.println( "deadly threat !" );
end

Мой вопрос: будет ли это правило учитывать весь список объектов, которые я передаю (хотя и не через List, так как я прочитал, что это не очень хорошая практика), и, таким образом, учитывать, есть ли соответствие условий пара объектов среди тех, кого я сдал?

Вы предлагаете какой-то другой обходной путь?

заранее спасибо

1 Ответ

1 голос
/ 11 июня 2019

Нет, не будет.

for(Log l : logs) {
    kieS.insert(l);
    kieS.fireAllRules();
}

Согласно вашему циклу вы будете вставлять объект, а после каждой вставки сразу после этого вы будете запускать все правила. Я не уверен, как Drools отреагирует на ваш цикл, но то, что вы, вероятно, хотите сделать, это вставить все журналы в рабочую память и затем запустить правила:

for(Log l : logs) {
    kieS.insert(l);
}
kieS.fireAllRules();

Проектирование тестового класса JUnit показало бы вам это сразу же.

...