Drools 7 - load rules from DB

六眼飞鱼酱① 提交于 2021-02-04 08:23:08

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!