Von der Datenbank initialisierte Drools sind leer
Posted: 25 Dec 2024, 19:23
Ich konnte Drools zum Kategorisieren von Transaktionen verwenden, als ich Regeln als Datei im Ressourcenordner gespeichert hatte. Da ich jedoch eine CRUD-API benötige, habe ich begonnen, Regeln aus einer Datenbank zu laden. Ich habe einen Nachmittag damit verbracht, aber keine Transaktion ist kategorisiert und ich denke, das liegt an einer Fehlkonfiguration.
gradle:
Drools-Konfigurations-Bean
Drools-Init-Dienst
Regelausführer
Eine Regel
Maven ist eingerichtet (M2_HOME). Ich habe überprüft, ob die Regeln aus der Datenbank geladen werden. Es liegt kein Kompilierungsfehler vor. Ich habe sogar einen Listener zu KieStatelessSession hinzugefügt, aber er wurde nie aufgerufen. Wenn ich versuche, KieBase zu überprüfen, scheint es leer zu sein, aber KieFileSystem enthält die Dateien aus der Datenbank.
Protokolle:
Ich vermute, dass die dritte Zeile auf das Problem hinweist.
gradle:
Code: Select all
droolsVersion = '8.44.0.Final'
implementation ("org.drools:drools-ruleunits-engine:${droolsVersion}")
implementation ("org.kie:kie-ci:${droolsVersion}")
implementation ("org.drools:drools-xml-support:${droolsVersion}")
Code: Select all
@Component
public class DroolsConfig {
private final DroolsService droolsService;
private final KieServices kieServices;
private final KieFileSystem kieFileSystem;
private KieContainer kieContainer;
private KieBase kieBase;
public DroolsConfig(DroolsService droolsService) {
this.droolsService = droolsService;
kieServices = KieServices.Factory.get();
kieFileSystem = kieServices.newKieFileSystem();
buildInitialKieBase();
}
private void buildInitialKieBase() {
kieContainer = droolsService.loadRulesFromDatabase(kieServices, kieFileSystem);
kieBase = kieContainer.getKieBase();
}
}
Code: Select all
@Service
public class DroolsService {
@Autowired private final DroolsRuleRepository ruleRepository;
public KieContainer loadRulesFromDatabase(KieServices kieServices, KieFileSystem kieFileSystem) {
List rules = ruleRepository.findByActive(true);
log.info("Found {} active rules", rules.size());
for (DroolsRule rule : rules) {
kieFileSystem.write("/rules/global/" + rule.getId() + ".drl", rule.getContent());
}
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
log.info("Rules compiled with following messages: {}", kieBuilder.getResults().getMessages());
for (Message message : kieBuilder.getResults().getMessages(Message.Level.ERROR)) {
System.out.println("Error in rule file: " + message.getText());
}
if (kieBuilder.getResults().hasMessages(Message.Level.ERROR)) {
throw new IllegalStateException("Errors while building rules: " + kieBuilder.getResults());
}
return kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
}
}
Code: Select all
@Service
public class RuleExecutorService {
private final DroolsConfig droolsConfig;
private final TransactionCategorizationService categorization;
private StatelessKieSession kieSession;
@PostConstruct
private void initializeSession() {
refreshSession();
}
public void refreshSession() {
log.info("Creating a new Kie session");
var kieContainer = droolsConfig.getKieContainer();
kieSession = kieContainer.newStatelessKieSession();
kieSession.setGlobal("TOOLS", categorization);
KieBase kieBase = kieSession.getKieBase();
for (KiePackage kiePackage : kieBase.getKiePackages()) {
for (Rule rule : kiePackage.getRules()) {
System.out.println("Rule: " + rule.getName());
}
}
}
public void executeRules(Transaction transaction) {
log.info("Executing rules for transaction {}", transaction.getBankReference());
kieSession.execute(transaction);
log.info("Rules executed");
}
Code: Select all
rule "Tesco transactions"
salience 10
activation-group "shopIdentification"
when
$t : Transaction(transactionType == null && TOOLS.containsText($t, "Tesco"))
then
$t.setMerchant("Tesco");
$t.setExpenseCategory("FOOD");
$t.setTransactionType(TransactionType.EXPENSE);
end
Protokolle:
Code: Select all
INFO c.l.a.s.DroolsService [restartedMain] Loading rules from database
INFO c.l.a.s.DroolsService [restartedMain] Found 14 active rules
WARN o.d.c.k.b.i.AbstractKieProject [restartedMain] No files found for KieBase defaultKieBase
INFO c.l.a.s.DroolsService [restartedMain] Rules compiled with following messages: []
INFO o.d.c.k.b.i.KieContainerImpl [restartedMain] Start creation of KieBase: defaultKieBase
INFO o.d.c.k.b.i.KieContainerImpl [restartedMain] End creation of KieBase: defaultKieBase
INFO c.l.a.s.RuleExecutorService [restartedMain] Creating a new Kie session