Loading and updating rules from database in Drools 6
How can rules be loaded from a database table at startup and updated from the same table in Drools 6.2.0? I found an example using Drools 5 that could probably convert from Scala to Java, but it looks like the API has changed a lot. For example, I don't see the RuleBaseFactory class.
Any sample or documentation would be appreciated.
source to share
I'm not sure where this org.dools.RuleBaseFactory came from. Here's how it was done in Drools 5.3 (and possibly earlier) up to 5.6:
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ..., ResourceType.DRL);
if( kbuilder.hasErrors() ){
System.err.println( "### compilation errors ###" );
KnowledgeBuilderErrors errors = kbuilder.getErrors();
for( KnowledgeBuilderError err: errors ){
System.err.println( err.toString() );
}
throw new IllegalStateException( "compile errors" );
}
KnowledgeBase kbase = kbuilder.newKnowledgeBase();
StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();
The ellipsis indicates where to insert data containing the text of the rule. Check the API for suitable types; java.lang.String should be acceptable.
This is how I use for 6.2:
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kfs = kieServices.newKieFileSystem();
kfs.write( "src/main/resources/simple.drl", ... );
KieBuilder kieBuilder = kieServices.newKieBuilder( kfs ).buildAll();
Results results = kieBuilder.getResults();
if( results.hasMessages( Message.Level.ERROR ) ){
System.out.println( results.getMessages() );
throw new IllegalStateException( "### errors ###" );
}
KieContainer kieContainer =
kieServices.newKieContainer( kieServices.getRepository().getDefaultReleaseId() );
KieBase kieBase = kieContainer.getKieBase();
kieSession = kieContainer.newKieSession();
source to share
drools-templates has ResultSetGenerator.java which has a compile (resultSet, template) method to do the job.
I had data coming over HTTP to convert to a rule. I found a way to do this using ObjectDataCompiler. Maybe some people might find this useful.
ObjectDataCompiler compiler = new ObjectDataCompiler();
String generatedDRL = compiler.compile(ruleAttributes, new FileInputStream(REGULATION_TEMPLATE_FILE));
where ruleAttributes
List<Map<String, String>> ruleAttributes = new ArrayList<>();
Map<String, String> rule1 = new HashMap<>();
rule1.put("ruleid", "2");
rule1.put("ifcondition", "abc: Abc(xyz.getId() == 2);");
rule1.put("thencondition", "myGlobal.setPqr(200.1D);");
ruleAttributes.add(rule1);
Then KieBase can be created like this:
KieServices kieServices = KieServices.Factory.get();
KieHelper kieHelper = new KieHelper();
//multiple such resoures/rules can be added
byte[] b1 = generatedDRL.getBytes();
Resource resource1 = kieServices.getResources().newByteArrayResource(b1);
kieHelper.addResource(resource1, ResourceType.DRL);
KieBase kieBase = kieHelper.build();
The rules can be applied as follows:
KieSession kieSession = kieBase.newKieSession();
kieSession.setGlobal("myGlobal", myGlobal);
kieSession.insert(abc);
int numberOfRulesFired = kieSession.fireAllRules();
kieSession.dispose();
The template file looks like this:
template header
ruleid
ifcondition
thencondition
import fk.sp.seldon.msku.MSKU
global com.something.blah.MyGlobal myGlobal
template "tmp1"
rule "@{ruleid}"
dialect "mvel"
when
@{ifcondition}
then
@{thencondition};
end
end template
source to share