Version 5.5.0.Final (Guvnor and libraries)
Tomcat 6
Goal: We would like to change rules on-the-fly in Guvnor so they become
immediately effective in a web application running in Tomcat.
The function below is used to connect go Guvnor. It works fine in a
standalone Java program, but in the web application the updates in Guvnor
have no effect.
Does anybody have experience with this scenario?
Is there something wrong with the function used to connect to Guvnor?
Additional observation: Instead of loading the rules from Guvnor I have
tried loading them from a file, with refresh. The file is found the first
time when Drools starts, so the path is correct. When I change the rules
file in Eclipse the updated file is auto-deployed to Tomcat. Indeed Drools
realizes a change, /but fails to load the file with the following error:
Caused by: java.io.FileNotFoundException: 'org/somewhere/Rules.drl' cannot
be opened because it does not exist
at org.drools.io.impl.ClassPathResource.getURL(ClassPathResource.java:165)
at
org.drools.io.impl.ClassPathResource.getLastModified(ClassPathResource.java:177)/
Is it possible that Drools uses different methods for loading rules
initially and when an update is detected? Why would the file be found the
first time, but not after an update?
Function connecting to Guvnor with refresh
/**
* Creates a StatefulKnowledgeSession that accesses Guvnor using the
resource specification in
* the provided changeset. Changes in the rules in Guvnor are detected
on-the-fly (scanner interval).
* "Build package" in Guvnor is required to activate changed rules.
* <p>
* TODO Services are started that detect changes in the Guvnor rules. They
should be shutdown when an application
* terminates. This should be imlemented in a production environment.
*
* @param pathChangeSet String with the location of the rules file. If your
rules file is in a top directory
* (for example src/main/rules), then the path is "changeset.xml".
If it is in a package
* org.somewhere, then the string is "org/somewhere/changeset.xml".
* @param scannerIntervalSeconds int, seconds between rescan of the rules
file
* @return StatefulKnowledgeSession
*/
public static StatefulKnowledgeSession
createStatefulKnowledgeSessionWithGuvnor(String pathChangeSet, int
scannerIntervalSeconds) {
final ResourceChangeScannerConfiguration sconf =
ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
sconf.setProperty("drools.resource.scanner.interval",
Integer.toString(scannerIntervalSeconds));
ResourceFactory.getResourceChangeScannerService().configure(sconf);
ResourceFactory.getResourceChangeScannerService().start();
ResourceFactory.getResourceChangeNotifierService().start();
final KnowledgeAgentConfiguration knowlegdeAgentConfiguration =
KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
knowlegdeAgentConfiguration.setProperty("drools.agent.newInstance",
"false"); // keeps the session
final KnowledgeAgent kagent =
KnowledgeAgentFactory.newKnowledgeAgent("MyKnowledgeAgent",
knowlegdeAgentConfiguration);
final Resource changeset =
ResourceFactory.newClassPathResource(pathChangeSet);
kagent.applyChangeSet(changeset);
return kagent.getKnowledgeBase().newStatefulKnowledgeSession();
}
Function connecting to rules file with refresh
/**
* Creates a StatefulKnowledgeSession that uses the specified rules file.
* Changes in the rules file are detected on-the-fly (scanner interval).
* <p>
* TODO Services are started that detect changes in the rules file. They
should be shutdown when an application
* terminates. This should be imlemented in a production environment.
*
* @param pathRulesFile String with the location of the rules file. If your
rules file is in a top directory
* (for example src/main/rules), then the path is "rules.drl". If it
is in a package
* ch.sbb.eventhub, then the string is "ch/sbb/eventhub/rules.drl".
* @param scannerIntervalSeconds int, seconds between rescan of the rules
file
* @return StatefulKnowledgeSession
*/
public static StatefulKnowledgeSession
createStatefulKnowledgeSessionWithFile(String pathRulesFile, int
scannerIntervalSeconds) {
final ResourceChangeScannerConfiguration sconf =
ResourceFactory.getResourceChangeScannerService().newResourceChangeScannerConfiguration();
sconf.setProperty("drools.resource.scanner.interval",
Integer.toString(scannerIntervalSeconds));
sconf.setProperty("drools.agent.newInstance", "false"); // not
needed
ResourceFactory.getResourceChangeScannerService().configure(sconf);
ResourceFactory.getResourceChangeScannerService().start();
ResourceFactory.getResourceChangeNotifierService().start();
final KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource(pathRulesFile),
ResourceType.DRL);
final KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (final KnowledgeBuilderError error : errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
final KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
final KnowledgeAgentConfiguration knowlegdeAgentConfiguration =
KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
knowlegdeAgentConfiguration.setProperty("drools.agent.scanResources",
"true"); // not neeeded
knowlegdeAgentConfiguration.setProperty("drools.agent.scanDirectories",
"true"); // not needed
knowlegdeAgentConfiguration.setProperty("drools.agent.newInstance",
"false"); // required!
final KnowledgeAgent kagent =
KnowledgeAgentFactory.newKnowledgeAgent("From File", kbase,
knowlegdeAgentConfiguration);
return kagent.getKnowledgeBase().newStatefulKnowledgeSession();
}
--
View this message in context:
http://drools.46999.n3.nabble.com/Dynamic-refresh-from-Guvnor-in-Web-Appl...
Sent from the Drools: User forum mailing list archive at
Nabble.com.