Drools 6.4 KieScanner : How create and add Jar with rules in Maven?

谁都会走 提交于 2019-12-03 20:55:19

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.

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.

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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!