JBoss Drools中提供了一个类KieScanner,可以支持从Maven存储库动态的加载并更新规则。官方给出的例子没有很好的证明这一能力,笔者经过几天研究,成功实验出了如何达到动态更新的效果,整理出来供大家参考。相关的源代码可以从Gitee下载。
程序结构和运行目标
如图所示,演示项目共包含四个项目:
- my-dynamic-rule: 父项目
- my-kjar: 一个kjar项目,其中包含了kmodule.xml文件和Drools规则.drl文件
- my-dynamic-engine: 一个Spring Boot项目,规则引擎运行于此,对外提供Rest服务
- my-model: 一个简单Java项目,包含my-kjar和my-dynamic-engine项目依赖的模型POJO
规则引擎服务my-dynamic-engine中并不包含规则,服务启动时,将从Maven存储库中拉取my-kjar项目,并加载其中的规则。启动以后,规则引擎服务将不停的监视Maven存储库中的my-kjar是否更新,如果更新则更新其中新的规则,规则引起服务本身不需重新启动。
my-kjar项目
my-kjar项目是一个kjar项目,其中包含了kmodule.xml文件和Drools规则.drl文件。kjar项目是指引入了kie-maven-plugin插件,并指定打包为kjar,在打包的过程中,插件会校验以drl定义的规则是否可以正常编译。设置kjar项目的方法如下:
<packaging>kjar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.kie</groupId>
<artifactId>kie-maven-plugin</artifactId>
<version>7.6.0.Final</version>
<extensions>true</extensions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.kie</groupId>
<artifactId>
kie-maven-plugin
</artifactId>
<versionRange>
[7.6.0.Final,)
</versionRange>
<goals>
<goal>generateModel</goal>
<goal>build</goal>
<goal>injectreactive</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
my-dynamic-engine项目
my-dynamic-engine是一个Spring Boot项目,可以动态加载规则的关键在于,在KieContainter容器上注册了一个KieScanner:
@PostConstruct
public void setUp() {
KieServices ks = KieServices.Factory.get();
ReleaseId releaseId = ks.newReleaseId("my-group", "my-kjar", "LATEST");
kContainer = ks.newKieContainer(releaseId);
KieScanner kScanner = ks.newKieScanner(kContainer);
// Start the KieScanner polling the Maven repository every 10 seconds
kScanner.start(10000L);
}
程序运行
1. 将my-dynamic-rule, my-model, my-kjar项目安装到Maven本地存储库
2. 使用mvn clean package打包my-dynamic-engine项目,并启动
3. 在浏览器中访问http://localhost:8080/dynamic-rule,可见规则引擎执行的结果:
4. 修改my-kjar项目中的Hal1.drl,如
5. 重新执行mvn install安装my-kjar项目,从规则引擎日志中可见规则已经更新
6. 在浏览器中访问http://localhost:8080/dynamic-rule,可见规则引擎执行的结果已经更新:
使用远程Maven存储库
以上的例子适合于开发环境,如果运行于运行时环境,则需要配置连接远程Maven存储库。Kie-ci依赖在规则引擎中引入了内嵌的Maven客户端,启动时会合并以下三个位置的Maven settings.xml配置文件:
- The Maven install: $M2_HOME/conf/settings.xml (配置M2_HOME为环境变量)
- A user’s install: ${user.home}/.m2/settings.xml
- Folder location specified by the system property kie.maven.settings.custom
作者已经使用Nexus测试了远程Maven存储库,遇到一个问题,受Maven本地缓存的影响,更新远程Maven存储库中的kjar以后,需要手动删除本地kjar所在的目录。尝试配置了updatePolicy,但还是不能自动抓取远程最新的kjar。
参考资料
https://docs.jboss.org/drools/release/7.6.0.Final/drools-docs/html_single/index.html#_kiescanner