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<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());
}
}
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("drl:\n" + 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 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("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();
taken from https://www.codota.com/web/assistant/code/rs/5c65b1cf1095a5000171b19f#L199