I need help with drools. Problem is that when I run an application (which is otherwise done in the spring) and when I try to fire all rules, only the first rule starts and the other rules cannot be started.
This is a my drl file with some my 3 rules.
package drools.medicine
import com.example.demo.model.Pacijent;
import com.example.demo.model.Lek;
import com.example.demo.model.SastojakLeka;
import com.example.demo.model.Pregled;
import com.example.demo.model.ValidacijaDiagnoze;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
rule "test-rule"
agenda-group "alergija"
when
$vd: ValidacijaDiagnoze()
then
System.out.println("TEEEST!!!");
end
rule "Alergic-on-medicine"
agenda-group "alergija"
when
$v: ValidacijaDiagnoze()
$pregled: Pregled($prepisaniLek: prepisanLek)
$lek: Lek() from $prepisaniLek
$pacijent: Pacijent(alergicanNaLek($lek))
then
System.out.println("Pacijent je alergican na lek: "+ $lek.getNazivLeka());
modify( $v ){
setValid(false),
setMessage("PATIENT IS ALLERGIC!")
}
end
rule "Alergic-on-ingredient"
agenda-group "alergija"
lock-on-active
when
$v: ValidacijaDiagnoze()
$pregled: Pregled($prepisaniLek: prepisanLek)
$lek: Lek($sastojci: sastojak) from $prepisaniLek
$sastojak: SastojakLeka() from $sastojci
$pacijent: Pacijent(alergicanNaSastojak($sastojak))
then
System.out.println("Pacijent je alergican na sastojak " + $sastojak.getNazivSastojka());
modify( $v ){
setValid(false),
setMessage("PATIENT IS ALLERGIC ON INGREDIENT!")
}
end
Below is where i call the kieSession to fire all rules.
// Take medicine(and ingredient) and decide throw rules are they ok or not.
@CrossOrigin(origins = "http://localhost:3000")
@PostMapping(value = "/validation")
public ResponseEntity<?> validateDiagnosis(@RequestBody PregledDto pregledDto){
//TO DO--
KieSession kieSession = kieContainer.getKieBase("MedicineBase").newKieSession();
//initial state, witch can be changed in rules if patient is allergic
ValidacijaDiagnoze vd = new ValidacijaDiagnoze();
vd.setMessage("PATIENT IS NOT ALLERGIC");
vd.setValid(true);
FactHandle fact;
fact = kieSession.insert(vd);
kieSession.getAgenda().getAgendaGroup("alergija").setFocus();
System.out.println("Number of fired rules: "+ kieSession.fireAllRules()); // 1
kieSession.dispose();
return new ResponseEntity<>(vd, HttpStatus.OK);
}
And there is my kmodule file in META-INF folder.
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<kbase name="DiagnosisBase" packages="drools.diagnosis">
<ksession name="diagnosis" />
</kbase>
<kbase name="DiagnosisBase2" packages="drools.diagnosis2">
<ksession name="diagnosis2" />
</kbase>
<kbase name="MedicineBase" packages="drools.medicine">
<ksession name="medicine" />
</kbase>
</kmodule>
Help me to solve problem I am new in using drools.
Also let me know where I am making mistakes and what are the best practices when using drools, thank you very much.
The number returned by the method kieSession.fireAllRules()
is the number of rules that actually matched and were executed by the Drools engine. If a rule's left hand side (the 'when' clause) does not match the inputs, it does not match, and it will not be executed.
In the example rules given, the test rule checks only for the presence of a ValidacijaDiagnoze
in working memory. The other two rules require that the ValidacijaDiagnoze
includes children (a Lek
instance or SastojakLeka
instance) as well as an instance of Pacijent
also in working memory.
However, in the code that fires the rules, only a ValidacijaDiagnoze
is added to the working memory like this:
ValidacijaDiagnoze vd = new ValidacijaDiagnoze();
vd.setMessage("PATIENT IS NOT ALLERGIC");
vd.setValid(true);
Since this instance has no Lek
or SastojakLeka
associated with, it won't trigger the other rules. Additionally, since there is no Pacijent
in the working memory, those other rules won't trigger either.
Therefore, since only the first rule can trigger, fireAllRules
returns 1 because that is the number of rules that actually executed.