I'm struggling a bit with a concept in Drools, can anyone clarify if I'm looking at this problem the wrong way? The solution works but it seems like the wrong approach, as I'll explain at the end.
I have a Country model object containing id, continent, area; where area is the economic area for example EU or US; I have enums for CountryID, EconomicAreaId, ContinentID; I have a Request object containing origin:Country, destination:Country, srucharge:Int; I have two Drools rules (Actually expressed in xls, but I'll list the drl here):
<package and imports are correct>
rule "UK"
when
$c:Country($c.getId() in (CountryID.UNITED_KINGDOM))
then
$c.setArea(EconomicAreaID.EU);
$c.setContinent(ContinentID.EUROPE);
/* update($c); // I tried this too :) //
end
rule "US"
when
$c:Country($c.getId() in (CountryID.UNITED_STATES))
then
$c.setArea(EconomicAreaID.US);
$c.setContinent(ContinentID.N_AMERICA);
end
rule "EU to EU"
when
$rr:ChargeRequest($rr.getOrigin.getArea() == EconomicAreaID.EU, $rr.getDestination.getArea() == EconomicAreaID.EU)
then
$rr.setCharge(1);
end
rule "US to US"
when
$rr:ChargeRequest($rr.getOrigin.getArea() == EconomicAreaID.US, $rr.getDestination.getArea() == EconomicAreaID.US)
then
$rr.setCharge(2);
end
rule "EU to US"
when
$rr:ChargeRequest($rr.getOrigin.getArea() == EconomicAreaID.EU, $rr.getDestination.getArea() == EconomicAreaID.US)
then
$rr.setCharge(3);
end
rule "US to EU"
when
$rr:ChargeRequest($rr.getOrigin.getArea() == EconomicAreaID.US, $rr.getDestination.getArea() == EconomicAreaID.EU)
then
$rr.setCharge(4);
end
First I want to insert two country objects, origin and destination, and have Drools automatically assign the continent and economic area to their attributes;
Then I want Drools to calculate the surcharge, simplified here as an int.
In order to do this I have to add both country objects and fire all rules to populate the country objects, THEN add the request object and fire all rules AGAIN to get the surcharge.
KieSession kSession = kieContainer.newKieSession();
ChargeRequest rr = new ChargeRequest(new Country("UNITED_STATES"), new Country("UNITED_KINGDOM"));
kSession.insert(rr.getOrigin()); // add both country objects
kSession.insert(rr.getDestination());
kSession.fireAllRules(); // LINE 6 : fire rules to calculate the economic areas and continents of the country objects
kSession.insert(rr); // add the ChargeRequest object
kSession.fireAllRules(); // fire the rules to calculate the charge
return rr.toString(); // ChargeRequest(origin=Country(id=UNITED_STATES, continent=N_AMERICA, area=US), destination=Country(id=UNITED_KINGDOM, continent=EUROPE, area=EU), charge=4)
If I leave out line 6 then the charge is not calculated as 4 because Drools performs the charge rules on the underpopulated country objects. I thought Drools had the concept of evaluating all the rules in the correct order so it would "know" to apply rules to the countries before using them as input to the charge rules.
This is only a simplified example I'm playing with so it seems it shouldn't be this complicated, so have I got the conceptual approach wrong?