问题
I am a beginner with Drools and Maven and I am facing a problem to load rules with KieScanner.
The aim of the project is to be able to dynamically load rules in a permanent KieSession. I wonder if it is possible to manage rules with the KieFileSystem (not sure it is possible without a dispose of the session and starting another one leading to the lack of the previous inserted facts), but the good way is to use KieScanner.
It seems this requires the creation of a Jar containing the rules and having a Maven ID (ReleaseId), but I could not find detailed documentation about creation of these Jar files.
Which files shall be included in such a Jar ? DRL files, Pom.xml and manifest.mf ?
Where can this Jar file be added ? According to documentation it should not be added in the classpath when the detection of new issues of that file is necessary : "once a module is on the classpath, no other version may be loaded dynamically".
Is a Maven command needed ?
Can someone give me information on those points or give me a link where creation and deployment of such a Jar and its management in a KieScanner is described ? Thanks a lot.
回答1:
Here is an example of a stateless kiesession
using a kjar from a maven repository (code is in scala, but i am sure you'll get the idea of you primarily program in Java)
private val services = KieServices.Factory.get
private val releaseId = services.newReleaseId("com.piedpiper", "demo", "[1.0,2)")
private val kieContainer = services.newKieContainer(releaseId)
val kScanner = services.newKieScanner(kieContainer)
kScanner.start(2000L)
val kieSession = kieContainer.newStatelessKieSession("SimpleSession")
@tailrec
def check() {
val (aName, aAge) = scala.io.StdIn.readf2("{0} {1,number}")
val applicant = Applicant(name = aName.asInstanceOf[String], age = aAge.asInstanceOf[Long].toInt, pass = false)
kieSession.execute(applicant)
println(s"valid is ${applicant.pass}")
check()
}
check()
This looks for a kjar using maven with the gav com.piedpiper:demo:[1.0,2)
(iow any version from 1.0
to 2
(non-inclusive). It checks every two seconds if a new version within that range is available.
The kjar contains the knowledge resources, the kmodule.xml
etc (a proper kjar with the compiled rules using the kie-maven-plugin
plugin-extension ). In this case it also contains the fact model (i would normally separate that out in a different maven artefact.)
The rule used in the example above is
rule "Is of valid age"
when
$a : Applicant( age > 13, pass==false )
then
modify($a){
pass = true
}
end
When changing the rule to for example > 15
, it takes 2 seconds to become operational.
回答2:
Thanks a lot for your response raphaëλ. But my problem was rather building the jar before being able to use it in Java code.
This is how I could solve my problem.
Creation of a kjar file with the rules :
- the file must contain :
- file kmodule.xml in directory META-INF
- file MANIFEST.MF in directory META-INF (not sure this is necessary...)
- DRL files in same path than the one defined by their package (I have put the DRL files without compiling them before and they have been fired as expected)
- a file pom.xml should be present for Maven but this has failed and I had to use an external pom.xml
command :
jar cvmf META-INF\MANIFEST.MF example-rules.jar META-INF* rules*
Example of file kmodule.xml :
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
<kbase name="base1" default="true" packages="rules">
<ksession name="session1" type="stateful" ="true"/>
</kbase>
</kmodule>
File MANIFEST.MF :
Manifest-Version: 1.0
Add kjar to Maven repository :
command :
mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=example-rules.jar -DpomFile=pom_jar.xml
file pom_jar.xml is used to define Maven references, example of such a file :
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId> test.example</groupId> <artifactId>example-rules</artifactId> <version>0.0.1-SNAPSHOT</version> <name>example-rules</name> <!-- Output to jar format --> <packaging>jar</packaging> </project>
Any comment is welcome.
回答3:
Here is an example to use MemoryFileSystem to create KJar and use it to create KieContainer
Input:
- releaseId - Could be TimeStamp and UUID
- ruleContentList - DRL file stringified list
public static final String IN_MEM_RULE_PATH = "src/main/resources/";
public static final String RULE_RESOURCE_TYPE = "drl";
public static byte[] createKJar(ReleaseId releaseId, List<String> ruleContentList) {
KieServices kieServices = KieServiceProvider.get();
KieFileSystem kfs = kieServices.newKieFileSystem();
kfs.generateAndWritePomXML(releaseId);
ruleContentList.forEach(drl -> kfs.write(IN_MEM_RULE_PATH + drl.hashCode() + "." + RULE_RESOURCE_TYPE, drl));
KieBuilder kb = kieServices.newKieBuilder(kfs).buildAll();
if (kb.getResults().hasMessages(Message.Level.ERROR)) {
for (Message result : kb.getResults().getMessages()) {
log.info("Error: " + result.getText());
}
throw new RegnatorException("Unable to create KJar for requested conditions resources", RegnatorError.ErrorCode.UNDEFINED);
}
InternalKieModule kieModule = (InternalKieModule) kieServices.getRepository().getKieModule(releaseId);
byte[] jar = kieModule.getBytes();
return jar;
}
来源:https://stackoverflow.com/questions/38458460/drools-6-4-kiescanner-how-create-and-add-jar-with-rules-in-maven