1
votes

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>

Result in eclipse console.

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.

1
Because only one rule matched your inputs.Roddy of the Frozen Peas
Notice, the other two rules require that there be a patient (Pacijent) present in your working memory, but you are only inserting an instance of ValidacijaDiagnoze .Roddy of the Frozen Peas
Yes that is the problem, now when I added patient all rules are fired. Thank you very much.neca
Excellent. I will add the above comments as an answer explaining the situation. Have fun with Drools! :)Roddy of the Frozen Peas

1 Answers

1
votes

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.