2017-08-08 2 views
0

J'ai besoin d'exécuter des règles spécifiques en utilisant leurs valeurs associées et j'ai essayé d'implémenter un filtre d'agenda personnalisé pour exécuter une seule règle à la fois mais il semble exécuter toutes les règles. règles. J'utilise une session sans état que je définis comme ceci:Drools 6.5 Exécution d'une règle spécifique à l'aide d'un filtre d'agenda personnalisé

@Bean 
    @ConditionalOnMissingBean(KieSession.class) 
    public StatelessKieSession kieSession() throws IOException { 
     return kieContainer().newStatelessKieSession(); 
    } 

Ma logique pour itérer la carte et l'exécution de chaque règle est la suivante:

for (Map.Entry<Long, String> entry : ruleIdsAndData.entrySet()){ 

    List<Object> facts = new ArrayList<Object>(); 
    facts.add(entry.getValue()); 

    Map<String, String> ruleResponse = new HashMap<String, String>(); 
    kieSession.setGlobal("ruleResponse", ruleResponse);      

    TrackingAgendaEventListener agendaEventListener = new TrackingAgendaEventListener(); 
    kieSession.addEventListener(agendaEventListener); 

    String ruleName = myRuleService.retrieveRuleNameById(entry.getKey());    
    log.debug("Attempting to fire the following rule : " + ruleName); 

    facts.add(new FireAllRulesCommand(new RuleNameEqualsAgendaFilter(ruleName))); 
    kieSession.execute(facts); 

    log.debug("RuleResponse after rule has fired is : " + ruleResponse);                
} 

et la classe RuleNameEqualsAgendaFilter ressemble à ceci:

import lombok.extern.slf4j.Slf4j; 
import org.kie.api.runtime.rule.AgendaFilter; 
import org.kie.api.runtime.rule.Match; 

    @Slf4j 
    public class RuleNameEqualsAgendaFilter implements AgendaFilter { 

     private final String ruleName; 

     private final boolean accept; 

     public RuleNameEqualsAgendaFilter(final String name) { 
      this(name, true); 
     } 

     public RuleNameEqualsAgendaFilter(final String name, final boolean accept) { 
      this.ruleName = name; 
      this.accept = accept; 
     } 

     public String getName() { 
      return ruleName; 
     } 

     public boolean isAccept() { 
      return accept; 
     } 

     public boolean accept(Match match) { 
      log.debug("Comparing : " + match.getRule().getName() + " to ruleName : " + this.ruleName); 
      if (match.getRule().getName().equals(this.ruleName)) { 
       return this.accept; 
      } else { 
       return !this.accept; 
      } 
     } 
    } 

Des idées pourquoi cela exécuterait une règle différente de celle que je spécifie dans ruleName?

+0

Qu'est-ce qui vous fait dire que toutes les règles sont exécutées avec chaque appel à exécuter? – laune

+0

si je hardcode my ruleName dans la ligne suivante, la sortie de la console affiche un autre ruleName: facts.add (new FireAllRulesCommand (new RuleNameEqualsAgendaFilter ("myHardCodedRuleName"))); Je me demande si la configuration ci-dessus est OK ou devrais-je passer une liste de commandes et utiliser CommandFactory.newBatchExecution .... – Orby

+0

Qui crée ces journaux? Que fait 'TrackingAgendaEventListener'? –

Répondre

0

Ici, vous ajoutez des faits à une liste:

List<Object> facts = new ArrayList<Object>(); 
facts.add(entry.getValue()); 

Et ici vous ajoutez un autre objet, un FireAllRulesCommand:

facts.add(new FireAllRulesCommand(new RuleNameEqualsAgendaFilter(ruleName))); 

Et vous appelez

kieSession.execute(facts); 

qui insère tous les faits, puis appelle fireAllRules. Donc, l'AgendaFilter est juste un fait dans WM.

Utilisez une session statefull, insérez les faits et appelez fireAllRules avec le paramètre AgendaFilter en tant qu'argument.

+0

Un grand merci, c'est d'activer le filtre d'agenda maintenant quand j'ai utilisé une statefulSession pour que je puisse voir la bonne journalisation. Si j'ai 2 règles et seulement 1 exécute et l'autre pas quand je m'attendrais à ce que le 2 s'exécute. Changer la session en une session statefulSession ne provoquerait pas l'exécution de seulement 1 règle si votre session d'appel .insert ou session.fireAllRules (...) plusieurs fois? – Orby

+0

Lorsque je passe mon second ruleName au filtre de l'ordre du jour, il ne se connecte pas, mais le premier le fait, ma première règle est exécutée mais la deuxième règle ne fonctionne pas – Orby

+0

Je ne suis pas certain de comprendre ces commentaires. - Attention, vous devrez recréer et disposer une session avec état avant et après l'appel de fireAllRules pour obtenir le même résultat qu'avec une session sans état. – laune