向单例KieContainer添加新规则,同时保留现有规则。

huangapple go评论66阅读模式
英文:

Add new rules to singleton KieContainer by preserving existing rules

问题

配置类:

@Configuration
public class DynamicDroolsConfig {

    private KieServices kieServices;

    @Autowired
    private IPersistentSessionService iPersistentSessionService;

    @PostConstruct
    private void init() {
        this.initDataSource();
        this.kieServices = KieServices.Factory.get();
    }

    @Bean
    public KieSession getPersistentKieSession() {
        List<SessioninfoEntity> sessioninfoEntities = iPersistentSessionService.getStoredSessionDetails();

        if (sessioninfoEntities.size() == 0) {
            return newSession();
        } else if (sessioninfoEntities.size() == 1) {
            return persistedSession(sessioninfoEntities.get(0));
        } else {
            // todo other things
            return null;
        }
    }

    @Bean
    public KieServices getKieServices() {
        return this.kieServices;
    }

    @Bean
    public KieContainer getKieContainer() {
        getFileSystem();
        KieRepository kieRepository = kieServices.getRepository();
        kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
        KieBuilder kb = kieServices.newKieBuilder(getFileSystem()).buildAll();
        KieModule kieModule = kb.getKieModule();
        return kieServices.newKieContainer(kieModule.getReleaseId());
    }

    @Bean
    public KieFileSystem getFileSystem() {
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        return kieFileSystem;
    }

    public Environment getEnv() {
        Environment env = kieServices.newEnvironment();
        env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, Persistence.createEntityManagerFactory("org.drools.persistence.jpa"));
        env.set(EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());
        return env;
    }

    private void initDataSource() {
        PoolingDataSource ds = new PoolingDataSource();
        ds.setUniqueName("jdbc/BitronixJTADataSource");
        ds.setClassName("com.mysql.cj.jdbc.MysqlXADataSource");
        ds.setMaxPoolSize(3);
        ds.setAllowLocalTransactions(true);
        ds.getDriverProperties().put("user", "root");
        ds.getDriverProperties().put("password", "1234");
        ds.getDriverProperties().put("URL", "jdbc:mysql://localhost:3306/drool_demo");
        ds.init();
    }

    private KieSession newSession() {
        return kieServices.getStoreServices().newKieSession(getKieContainer().getKieBase(), null, getEnv());
    }

    private KieSession persistedSession(SessioninfoEntity sessioninfoEntity) {
        return kieServices.getStoreServices().loadKieSession(sessioninfoEntity.getId(), getKieContainer().getKieBase(), null, getEnv());
    }
}

容器 releaseId 更新方法:

@Service
public class DroolsUtilityImpl implements IDroolsUtility {

    @Autowired
    private KieFileSystem fileSystem;
    @Autowired
    private KieServices services;
    @Autowired
    private KieContainer container;

    @Override
    public void updateContainer(String rules) {

        fileSystem.write("src/main/resources/rules/rule.drl", rules);
        KieBuilder kb = services.newKieBuilder(fileSystem).buildAll();
        KieModule kieModule = kb.getKieModule();
        container.updateToVersion(kieModule.getReleaseId());
    }

    @Override
    public void viewContainerRules() {

        KieBase kieBase = container.getKieBase();
        for (KiePackage kp : kieBase.getKiePackages()) {
            for (Rule rule : kp.getRules()) {
                System.out.println(rule.getName());
            }
        }
    }
}
英文:

I am trying to add new rules to a singleton KieContainer having session persistence, in a Spring Boot project. I have implemented the programmatic approach for addition of new rules to the KieContainer but the existing rules are getting replaced everytime I update the ReleaseID of the KieContainer. What I want is to preserve the existing rules that is present in the Drools Session and add new rules to that. The updateContainer() function from my utility class is how I am making changes to the KieContainer. Any suggestions mostly welcomed. My implementation is as follows:

Configuration class:

@Configuration
public class DynamicDroolsConfig {

    private KieServices kieServices;

    @Autowired
    private IPersistentSessionService iPersistentSessionService;

    @PostConstruct
    private void init() {
        this.initDataSource();
        this.kieServices = KieServices.Factory.get();
    }

    @Bean
    public KieSession getPersistentKieSession() {
        List&lt;SessioninfoEntity&gt; sessioninfoEntities = iPersistentSessionService.getStoredSessionDetails();

        if (sessioninfoEntities.size() == 0) {
            return newSession();
        } else if (sessioninfoEntities.size() == 1) {
            return persistedSession(sessioninfoEntities.get(0));
        } else {
            // todo other things
            return null;
        }
    }

    @Bean
    public KieServices getKieServices() {
        return this.kieServices;
    }

    @Bean
    public KieContainer getKieContainer() {
        getFileSystem();
        KieRepository kieRepository = kieServices.getRepository();
        kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
        KieBuilder kb = kieServices.newKieBuilder(getFileSystem()).buildAll();
        KieModule kieModule = kb.getKieModule();
        return kieServices.newKieContainer(kieModule.getReleaseId());
    }

    @Bean
    public KieFileSystem getFileSystem() {
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        return kieFileSystem;
    }

    public Environment getEnv() {
        Environment env = kieServices.newEnvironment();
        env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, Persistence.createEntityManagerFactory(&quot;org.drools.persistence.jpa&quot;));
        env.set(EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());
        return env;
    }

    private void initDataSource() {
        PoolingDataSource ds = new PoolingDataSource();
        ds.setUniqueName(&quot;jdbc/BitronixJTADataSource&quot;);
        ds.setClassName(&quot;com.mysql.cj.jdbc.MysqlXADataSource&quot;);
        ds.setMaxPoolSize(3);
        ds.setAllowLocalTransactions(true);
        ds.getDriverProperties().put(&quot;user&quot;, &quot;root&quot;);
        ds.getDriverProperties().put(&quot;password&quot;, &quot;1234&quot;);
        ds.getDriverProperties().put(&quot;URL&quot;, &quot;jdbc:mysql://localhost:3306/drool_demo&quot;);
        ds.init();
    }

    private KieSession newSession() {
        return kieServices.getStoreServices().newKieSession(getKieContainer().getKieBase(), null, getEnv());
    }

    private KieSession persistedSession(SessioninfoEntity sessioninfoEntity) {
        return kieServices.getStoreServices().loadKieSession(sessioninfoEntity.getId(), getKieContainer().getKieBase(), null, getEnv());
    }
}

Container releaseId updation method:

@Service
public class DroolsUtilityImpl implements IDroolsUtility {

    @Autowired
    private KieFileSystem fileSystem;
    @Autowired
    private KieServices services;
    @Autowired
    private KieContainer container;

    @Override
    public void updateContainer(String rules) {

//        System.out.println(&quot;drl:\n&quot; + rules);
        fileSystem.write(&quot;src/main/resources/rules/rule.drl&quot;, rules);
        KieBuilder kb = services.newKieBuilder(fileSystem).buildAll();
        KieModule kieModule = kb.getKieModule();
        container.updateToVersion(kieModule.getReleaseId());
    }

    @Override
    public void viewContainerRules() {

        KieBase kieBase = container.getKieBase();
        for (KiePackage kp : kieBase.getKiePackages()) {
            for (Rule rule : kp.getRules()) {
                System.out.println(rule.getName());
            }
        }
    }
}

答案1

得分: 1

我会尝试重新生成pom并增加发布编号。有点类似于这个例子:

  KieServices ks = KieServices.Factory.get();
  ReleaseId releaseId = ks.newReleaseId("org.kie", "hello-world", "1.0");
  KieFileSystem kfs = ks.newKieFileSystem()
      .generateAndWritePomXML(releaseId)
      .write("src/main/resources/KBase1/org/pkg1/r1.drl", createDrl("R1"))
      .write("src/main/resources/KBase1/org/pkg2/r2.drl", createDrl("R2"))
      .writeKModuleXML(createKieProjectWithPackages(ks, "org.pkg1").toXML());
  ks.newKieBuilder(kfs).buildAll();

摘自:
https://www.codota.com/web/assistant/code/rs/5c65b1cf1095a5000171b19f#L199

英文:

I would try to regenerate the pom and increase release Id. A bit like in this example :

  KieServices ks = KieServices.Factory.get();
ReleaseId releaseId = ks.newReleaseId(&quot;org.kie&quot;, &quot;hello-world&quot;, &quot;1.0&quot;);
KieFileSystem kfs = ks.newKieFileSystem()
.generateAndWritePomXML( releaseId )
.write( &quot;src/main/resources/KBase1/org/pkg1/r1.drl&quot;, createDrl( &quot;R1&quot; ) )
.write( &quot;src/main/resources/KBase1/org/pkg2/r2.drl&quot;, createDrl( &quot;R2&quot; ) )
.writeKModuleXML( createKieProjectWithPackages( ks, &quot;org.pkg1&quot; ).toXML() );
ks.newKieBuilder( kfs ).buildAll();

taken from
https://www.codota.com/web/assistant/code/rs/5c65b1cf1095a5000171b19f#L199

huangapple
  • 本文由 发表于 2020年10月21日 01:57:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/64450848.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定