问题
I'm using Drools 7 as rule engine. Initially I loaded rules from classpath with the following code to build a StatelessKieSession:
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
StatelessKieSession statelessKieSession = kContainer.newStatelessKieSession();
then I decided to load rules from DB, here's the code:
KnowledgeBuilder knowledgeBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
SqlRowSet sqlRowSet = new JdbcTemplate(ds).queryForRowSet("select drl_code from rule");
while(sqlRowSet.next()) {
Resource r = ResourceFactory.newReaderResource(new StringReader(sqlRowSet.getString("drl_code")));
knowledgeBuilder.add(r, ResourceType.DRL);
}
KieBase kieBase = knowledgeBuilder.newKieBase();
StatelessKieSession statelessKieSession = kieBase.newStatelessKieSession();
What worries me is that KnowledgeBuilder interface is in an internal package ("org.kie.internal").
Is there another way to build a StatelessKieSession when loading rules from DB using a "public" API?
回答1:
Similar case i have done as follow. I used load my rules from MYSQL.
public void reloadRules() {
// TODO Auto-generated method stub
List<DroolsDrlModel> droolsDrlModels = droolsDrlDao.findAll();
KieContainer kieContainer = loadDroolsSessionContainer(droolsDrlModels);
this.kieContainer=kieContainer;
KieSession kieSession = this.kieContainer.newKieSession();
Thread t1 = new Thread(new Runnable() {
public void run() {
kieSession.fireUntilHalt();
}
});
t1.start();
}
public KieContainer loadDroolsSessionContainer(List<DroolsDrlModel> droolsDrlModels){
long startTime = System.currentTimeMillis();
if(this.kieServices == null){
this.kieServices = KieServices.Factory.get();
}
// add following if you are using timer in your rules
KieSessionConfiguration ksconf = kieServices.newKieSessionConfiguration();
ksconf.setOption(TimedRuleExecutionOption.YES);
KieRepository kr = kieServices.getRepository();
KieFileSystem kfs = kieServices.newKieFileSystem();
for(DroolsDrlModel drlModel:droolsDrlModels){
kfs.delete("src/main/resources/" + drlModel.getRuleFileName() + ".drl");
LOGGER.info("Drools DRL was deleted sucessfully"+drlModel.getRuleFileName());
kfs.write("src/main/resources/" + drlModel.getRuleFileName() + ".drl", drlModel.getDroolContent());
LOGGER.info("Drools DRL was created sucessfully "+drlModel.getRuleFileName());
}
KieBuilder kb = kieServices.newKieBuilder(kfs);
kb.buildAll();
if (kb.getResults().hasMessages(Message.Level.ERROR)) {
throw new RuntimeException("Build Errors:\n" + kb.getResults().toString());
}
long endTime = System.currentTimeMillis();
LOGGER.info("Time to build rules : " + (endTime - startTime) + " ms" );
startTime = System.currentTimeMillis();
KieContainer kContainer = kieServices.newKieContainer(kr.getDefaultReleaseId());
endTime = System.currentTimeMillis();
LOGGER.info("Time to load container: " + (endTime - startTime) + " ms" );
return kContainer;
}
And my DroolDrl Model
@Entity(name="rules_table")
public class DroolsDrlModel{
@Column(name = "drl_file_name")
private String ruleFileName;
@Column(name = "drl_content")
private String droolContent;
@Column(name = "version")
private int version;
// getter and setters
来源:https://stackoverflow.com/questions/61867320/drools-7-load-rules-from-db