1

I am creating a spring boot app with Gradle and 7.20 drools version.We are loading drools knowledge base from an external resource file place at path drl_file_path.Below is my configuration code.

@Configuration
public class DroolConfig {
    KieServices kieServices = KieServices.Factory.get();
    @Bean
    public KieFileSystem kieFileSystem() throws IOException {
        KieFileSystem kieFileSystem =kieServices.newKieFileSystem();
        kieFileSystem.write(ResourceFactory.newFileResource(new File("drl_file_path")));
        return kieFileSystem;
    }

    @Bean
    public KieContainer kieContainer() throws IOException{
        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem());
        kieBuilder.buildAll();
        KieModule kieModule = kieBuilder.getKieModule();
        KieContainer kieContainer = kieServices.newKieContainer(kieModule.getReleaseId());
        KieScanner kScanner = kieServices.newKieScanner(kieContainer);
        kScanner.start( 10000L );
        return kieContainer;
    }

    @Bean
    public KieScanner kieScanner() throws IOException{
        return kieServices.newKieScanner(kieContainer());
    }
}

There is a chance we have to update drools rule, and we want to update drools knowledge base without restarting the server, we are using KieScanner.sacnNow() which is not working, what is the key point I am missing.Below is code to reload and apply drools rule-

@Component
public class DroolComponent {
    @Autowired private KieContainer kieContainer;
    @Autowired private KieScanner kieScanner;

    public Customer reloadDroolsAndApply(Customer customer) {
        kieScanner.scanNow();
        //above scanning not applying updated rules. 
        KieSession kieSession = kieContainer.newKieSession();
        kieSession.insert(customer);
        kieSession.fireAllRules();
        kieSession.dispose();
        return customer;
    }
}
TheCurious
  • 593
  • 1
  • 4
  • 29

1 Answers1

0

You Can Use the below method to get a new container for Drools.

private  KieContainer loadContainerFromString() throws IOException{
    long startTime = System.currentTimeMillis();
    KieServices ks = KieServices.Factory.get();
    KieRepository kr = ks.getRepository();
    KieFileSystem kfs = ks.newKieFileSystem();

    InputStream stream = null;
    String drl = null;
    String RULE_PATH = "src/main/resources/";
    SpreadsheetCompiler converter = new SpreadsheetCompiler();

    File file = new File("src/main/resources/finance.xls");
    FileInputStream fIP = new FileInputStream(file);
    if(file.isFile() && file.exists()) {
        System.out.println("finance.xls file open successfully.");
    }
    Workbook workbook = new HSSFWorkbook(fIP);

    for (Sheet sheet : workbook) {
        System.out.println("Loading Sheet " + sheet.getSheetName());
        stream = new FileInputStream("src/main/resources/finance.xls");
        drl = converter.compile(stream, sheet.getSheetName());
        System.out.println("Drool drl added ::: " + drl);
        String DRL_FILE = RULE_PATH + sheet.getSheetName() + ".drl";
        System.out.println("Drool file added ::: " + DRL_FILE);
        kfs.write(DRL_FILE, ResourceFactory.newReaderResource(new StringReader(drl)));
        stream.close();
        break;
    }

    KieBuilder kb = ks.newKieBuilder(kfs);
    kb.buildAll();
    if (kb.getResults().hasMessages(Message.Level.ERROR)) {
        throw new RuntimeException("Build Errors:\n" + kb.getResults().toString());
    }
    long endTime = System.currentTimeMillis();
    System.out.println("Time to build rules : " + (endTime - startTime)  + " ms" );
    startTime = System.currentTimeMillis();
    KieContainer kContainer = ks.newKieContainer(kr.getDefaultReleaseId());
    endTime = System.currentTimeMillis();
    System.out.println("Time to load container: " + (endTime - startTime)  + " ms" );

    return kContainer;
}

Make a Static variable to assigned and use container.