Как поддерживать глобальный счетчик Drools для фактов и применять правила на основе его значения

Я новичок в Drools и работаю над требованием, чтобы получить набор фактов (информация о банковском счете). Я должен дать предупреждающее сообщение, когда три последовательных второстепенных аккаунта (возраст ‹16) вставлены в рабочую память сеанса. Я пытался поддерживать глобальную переменную и увеличивать ее при вставке второстепенной учетной записи. Но я не могу определить правило на основе значения глобального счетчика, с помощью которого я должен доставить предупреждающее сообщение. Пожалуйста, найдите ниже файл DRL и предоставьте решение для этого.

Приведенное ниже правило не срабатывает

 rule checkCounterAndProduceAlert when
       b: ResultFact( value > 2 )   
    then
        System.out.println("Alert****");  
    end

Here is the DRL full content of DRL file




        package com.ys.drools.rules

import com.ys.drools.facts.*;

rule checkCounterAndProduceAlert 

no-loop true
when
   b: ResultFact( value > 2 )   
then
    System.out.println("Alert****");  
end


rule checkSeriesOfMinorAccount when
    a : AccountHolder( age < 16 )
    b : ResultFact()
then
b.inc();
update(b);

System.out.println("Incrementing count  since minor account appered");
System.out.println("***********************************************");
System.out.println(b.getValue());
end


rule checMajorAccount when
    a : AccountHolder( age >16 )
    b :ResultFact()
then
b.reset();
update(b);
System.out.println("Making count zero since major account appered");
System.out.println(b.getValue());
end

Вот класс Java, который загрузит 3 второстепенных аккаунта и протестирует приложение.

package com.ys.drools.data.loader;

import java.util.ArrayList;
import java.util.List;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ys.drools.facts.AccountHolder;
import com.ys.drools.util.BankAccountUtilService;
import com.ys.drools.util.DroolsGlobalUtil;

public class Test {
    private BankAccountUtilService service;
    private  KieContainer kieContainer;
    private KieSession kieSession;
    private static Logger log = LoggerFactory
            .getLogger(Test.class);

    private List<AccountHolder> accountHolders=new ArrayList<AccountHolder>();  

    public Test(){
        kieContainer= KieServices.Factory.get().getKieClasspathContainer();     
          kieSession = kieContainer.newKieSession("BankAccountSession");
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Test test=new Test();
        List<AccountHolder> aList=test.fillAccountHolderList();
         ResultFact fact=new ResultFact();
       test.kieSession.insert(fact);
       for(int i=0;i<aList.size();i++){
        test.kieSession.insert(aList.get(i));
        test.kieSession.fireAllRules();
        }

      }


    public List<AccountHolder> fillAccountHolderList(){
         List<AccountHolder> accountHolders=new ArrayList<AccountHolder>(); 
         AccountHolder a1=new AccountHolder("Karun", 12);
         AccountHolder a2=new AccountHolder("kumar", 12);
         AccountHolder a3=new AccountHolder("rakesh", 10);
         accountHolders.add(a1);
         accountHolders.add(a2);
         accountHolders.add(a3);
         return accountHolders; 
    }
}

Пожалуйста, предоставьте решение для этого. Вывод при запуске тестового класса

Incrementing count  since minor account appered
***********************************************
1
Incrementing count  since minor account appered
***********************************************
2
Incrementing count  since minor account appered
***********************************************
3
Making count zero since major account appered
0

("Предупреждение****") не отображается даже после того, как значение >2 . правило "checkCounterAndProduceAlert" не срабатывает


person Kiran    schedule 02.12.2016    source источник


Ответы (1)


Решение простое.

class Counter {
    private int value;
    public void inc(){ value++; }
    public void reset(){ value = 0; }
    public int getValue(){ return value; }
}

Вставьте контрфакт в рабочую память и используйте методы inc и reset, где это уместно, после добавления шаблона $c: Counter() в правила.

rule checkCounterAndProduceAlert when
    Counter( value == 3 )   
then
    System.out.println("Alert****");  
end

Вам может понадобиться уточнение, следует ли выдавать еще одно предупреждение после шестого, девятого,... счета несовершеннолетнего подряд.

Изменить

Вы также можете объявить и вставить это в файл DRL:

declare Counter
  value : int
end

rule "insert counter"
  salience 999999
when
  not Counter()
then
  insert( new Counter() );
end
person laune    schedule 03.12.2016
comment
Спасибо за ответ . Не могли бы вы объяснить, где мне нужно объявить этот контрфакт в файле DRL? Поскольку фактические правила я применяю к другому факту, и в этой части я должен увеличивать или сбрасывать счетчик. Нужно ли мне снова объявлять это глобальным ..? - person Kiran; 05.12.2016
comment
Обратите внимание, что я написал вставить контрфакт. Смотрите мое обновление. - Нет глобалов. - person laune; 05.12.2016
comment
Спасибо за обновление. Я отредактировал содержимое DRL, пожалуйста, просмотрите это и помогите мне решить проблему. Я вставляю ResultFact в рабочую память через программу Java. Другие методы inc и reset работают нормально, и я могу распечатать значение счетчика, используя метод getValue, но правило checkCounterAndProduceAlert не срабатывает - person Kiran; 05.12.2016
comment
Я не вижу insert( new ResultFact() ); в вашем коде. - person laune; 06.12.2016
comment
Пожалуйста, проверьте сейчас ResultFact fact=new ResultFact(); test.kieSession.insert(факт); Пожалуйста, помогите мне решить эту проблему. Я также добавляю вывод консоли. все в порядке, за исключением того, что правило не срабатывает при значении ›2 - person Kiran; 06.12.2016
comment
О, вам придется обернуть вызовы inc и reset для фактов счетчика в операторах модификации или вызвать обновление для факта. Извините, я думал, вы это знаете... Очень просто... - person laune; 07.12.2016
comment
Я обновил факт результата и его работу. Но как избежать бесконечного цикла? после добавления строки фактов обновления в файле drl. Он выполняется непрерывно - person Kiran; 07.12.2016
comment
Что именно у вас сейчас есть в вашем файле DRL? - person laune; 08.12.2016
comment
Я обновил рассматриваемый файл DRL. Пожалуйста, посмотрите на него и помогите мне с решением. - person Kiran; 08.12.2016
comment
Вам не нужен цикл для правил с вызовами обновления, а не для того, который отображает предупреждение. - person laune; 08.12.2016
comment
Не повезло .. тот же результат - person Kiran; 08.12.2016