I have these 2 rules :
rule "challenge 1" salience 10
when
ClientTransaction(amount < 30)
then
challenge.setChallenge("challenge1");
end
rule "challenge 2" salience 0
when
eval( true )
then
challenge.setChallenge("challenge2");
end
and this java code :
public class ComputeChallengeDroolsRulesImplementation implements IComputeChallenge {
private KieServices kieServices = KieServices.Factory.get();
private KieSession kieSession = getKieSession();
private static final String RULES_PATH = "rules/";
public KieFileSystem getKieFileSystem() throws IOException {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
String[] rules = new File(getClass().getClassLoader().getResource(RULES_PATH).getFile()).list();
for (String rule : rules) {
kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_PATH + rule));
}
return kieFileSystem;
}
public KieContainer getKieContainer() throws IOException {
getKieRepository();
KieBuilder kb = kieServices.newKieBuilder(getKieFileSystem());
kb.buildAll();
KieModule kieModule = kb.getKieModule();
KieContainer kContainer = kieServices.newKieContainer(kieModule.getReleaseId());
return kContainer;
}
public void getKieRepository() {
final KieRepository kieRepository = kieServices.getRepository();
kieRepository.addKieModule(
new KieModule() {
public ReleaseId getReleaseId() {
return kieRepository.getDefaultReleaseId();
}
});
}
@Bean
public KieSession getKieSession() {
try {
return getKieContainer().newKieSession();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public Challenge2 computeChallenge(ClientTransaction clientTransaction) {
kieSession.insert(clientTransaction);
Challenge2 challenge = new Challenge2();
kieSession.setGlobal("challenge", challenge);
kieSession.fireAllRules();
return challenge;
}
}
here is the ClientTransation class :
public class ClientTransaction {
private String id;
private String merchant;
private double amount;
public ClientTransaction() {
}
public ClientTransaction(String id, String merchant, double amount) {
this.id = id;
this.merchant = merchant;
this.amount = amount;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMerchant() {
return merchant;
}
public void setMerchant(String merchant) {
this.merchant = merchant;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
}
And here is the Challenge2 class :
public class Challenge2 {
private String challenge;
public Challenge2() {
}
public Challenge2(String challenge) {
this.challenge = challenge;
}
public String getChallenge() {
return challenge;
}
public void setChallenge(String challenge) {
this.challenge = challenge;
}
}
when i call ComputeChallengeDroolsRulesImplementation.computeChallenge with an amount < 30 multiple times, it does return a challence object with a "challenge1" value multiple times as expected.
But when i call ComputeChallengeDroolsRulesImplementation.computeChallenge with an amount >= 30 multiple times, the first time it does return a "challenge2" value, but every subsequent time it return a Challenge2 object with a null value ?
Am i doing something wrong ?
Thank you
I am assuming you want to fire challenge 2 rule only when ClientTransaction event occurs. You can add a no condition check on a rule based on the occurrence of an event by just calling default constructor in the when part of a drool rule. Try changing you challenge 2 rule as below:
rule "challenge 2" salience 0
when
ClientTransaction()
then
challenge.setChallenge("challenge2");
end
Also, it is not recommended to use eval
so much in the drools rule. To more about best practices, check here