I need help writing a Drools rule. I have two classes named Context and CreditReport.
Context is inserted as a fact into the knowledge session before the rules are fired.
I need to write a rule that prints 'Excellent' on the console when the Credit Score is more than 800.
Ideally, I'd insert CreditReport directly into the session, but unfortunately I do not have that option.
The rule that I've written doesn't look good as:
Thanks for your help!
// Context.java
public class Context {
private Map<String, Object> data = Maps.newHashMap();
public <T> T getData(final String key, final Class<T> clazz) {
return clazz.cast(data.get(key));
}
public void putData(final String key, final Object value) {
this.data.put(key, value);
}
}
// CreditReport.java
public class CreditReport {
private final String name;
private final int creditScore;
public String getName() {
return this.name;
}
public int getCreditScore() {
return this.creditScore;
}
}
// Main method
context.put("creditReport", new CreditReport("John", 810));
session.insert(Arrays.asList(context));
session.fireAllRules();
// Rule
rule "Excellent_Score"
when Context($creditReportObject : getData("creditReport"))
then
final CreditReport creditReport = (CreditReport) $creditReportObject;
if (creditReport.getCreditScore() >= 800) {
System.out.println("Excellent");
}
end
What makes you insert a List<Context>
containing a single Context object? The Java code should do
context.put("creditReport", new CreditReport("John", 810));
session.insert( context );
session.fireAllRules();
The rule can now be written as
rule "Excellent_Score"
when
Context( $creditReportObject : getData("creditReport") )
CreditReport( creditScore > 800 ) from $creditReportObject
then
System.out.println("Excellent");
end
You could, of course, get and insert the CreditReport from Context. - I suspect it's more convoluted that what you've shown, but "I do not have that option" is a code smell anyway.
Edit A single rule for more than one reason for printing "excellent" could be written like the one below, although this isn't much better that two rules, considering that you can wrap the RHS into a method or DRL function.
rule "Excellent_Score_2"
when
Context( $creditReport : getData("creditReport"),
$account: getData("account") )
( CreditReport( creditScore > 800 ) from $creditReport
or
Account( balance >= 5000 ) from $account )
then
System.out.println("Excellent");
end