I'm working on a system where we're using a top-level KieModule which includes a set of other "child" KieModules. Only the child modules actually contain rules. The application retrieves the KieModules from a local Nexus server where they have been deployed with a Snapshot version.
We're using version 8.44.0.Final of Drools.
After the application is started, I can see that it retrieves the modules from repository and that the correct rules are fired when expected. However, the problem I'm seeing is that the rules are not being updated when new versions of the KieModules are deployed, despite the use of KieScanner to monitor Nexus. I've added a listener to the KieScanner so I can see that it is detecting the updated KieModules when they have been re-deployed.
If the application is restarted, I can see that the updated rules are fired, which I guess indicates that the problem isn't at the Nexus level.
To illustrate our problem, I've created a basic KieModule 'kieModuleA' which contains one very simple rule. The rule will fire and output a string when an AtomicBoolean fact exists whose value is 'true'.
kieModuleA DRL File
package com.example
import java.util.concurrent.atomic.AtomicBoolean;
dialect "mvel"
rule "A - AtomicBoolean Is True"
when
AtomicBoolean(get() == true)
then
System.out.println("========== A - AtomicBoolean Is True =============");
end
kieModuleA kmodule.xml
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="kieModuleA" packages="com.example">
<ksession name="ksession-kieModuleA"/>
</kbase>
</kmodule>
I then have a top-level module 'kieModuleCombine' which includes 'kieModuleA'.
kieModuleCombine kmodule.xml
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="kieModuleCombine" packages="com.example" includes="kieModuleA">
<ksession name="ksession-kieModuleCombine" default="true"/>
</kbase>
</kmodule>
The following is used to test:
@Test
public void test() throws InterruptedException
{
KieServices kieServices = KieServices.Factory.get();
ReleaseId releaseId = kieServices.newReleaseId("com.example", "kieModuleCombine", "0.0.1-SNAPSHOT");
final KieContainer container = kieServices.newKieContainer(releaseId);
KieScanner kScanner = kieServices.newKieScanner(container);
runSession(container);
// Start the KieScanner
kScanner.start(1000);
// Add a listener to the KieScanner
kScanner.addListener(new KieScannerEventListener()
{
public void onKieScannerUpdateResultsEvent(KieScannerUpdateResultsEvent updateResults)
{
System.out.println(new Date() + " : Updated");
runSession(container);
}
public void onKieScannerStatusChangeEvent(KieScannerStatusChangeEvent statusChange)
{
if (statusChange.getStatus() == KieScanner.Status.UPDATING)
{
System.out.println(new Date() + " : Updating");
}
}
});
// Loop to keep alive
while (true)
{
Thread.sleep(5000);
System.out.println("Running session");
runSession(container);
}
}
private void runSession(final KieContainer container)
{
KieSession session = container.newKieSession();
session.insert(new AtomicBoolean(true));
session.fireAllRules();
session.dispose();
}
If I modify the rule (e.g. change the output message) or copy the existing rule (with a different name) and then rebuild and deploy the KieModuleA while the test-code is still running, I see the messages from the KieScanner listener which would seem to indicate that the KieScanner has processed the updated module. However, the output for any new sessions created after the update do not include the updated message or new rule:
Running session
========== A - AtomicBoolean Is True =============
Running session
========== A - AtomicBoolean Is True =============
Running session
========== A - AtomicBoolean Is True =============
Running session
========== A - AtomicBoolean Is True =============
Running session
========== A - AtomicBoolean Is True =============
Mon Oct 23 22:44:40 BST 2023 : Updating
Mon Oct 23 22:44:41 BST 2023 : Updated
========== A - AtomicBoolean Is True =============
Running session
========== A - AtomicBoolean Is True =============
Running session
========== A - AtomicBoolean Is True =============
If I modify the dependencies of the test code to use KieModuleA directly instead of KieModuleCombine (and add the 'default="true"' to the KieModuleA kmodule.xml), then everything works as expected.
I would have thought that what I'm doing isn't that unusual, so I'm pretty confident I must be doing something wrong. Any assistance or suggestions would be gratefully received.
Thanks