packages文件夹可以删除吗


packages文件夹可以删除吗  

一、背景

二、预备知识

1. 如何动态构建kmodule.xml文件

动态构建kmodule.xml文件是实施Drools规则动态管理的重要步骤。通过编程方式生成kmodule.xml,我们可以动态地添加、更新或删除规则。

2. kmodule.xml的加载

KieFileSystem是Drools中的一个关键组件,它负责加载kmodule.xml文件。通过kieServices.newKieFileSystem()方法可以创建一个KieFileSystem对象,然后使用kieFileSystem.writeKModuleXML()方法写入kmodule.xml的内容。

3. drl规则内容的加载

使用kieFileSystem.write()方法,我们可以将drl规则内容写入到虚拟的文件系统中。然后,通过KieBuilder进行构建,并获取构建结果。如果构建过程中有错误,可以通过Results对象获取错误信息。

三、注意事项

1. KieFileSystem的缓存问题

从上面的过程我们可以看到,drl规则内容是通过KieFileSystem加载的。如果我们不缓存KieFileSystem对象,每次加载新的规则内容时,之前的规则内容可能会丢失。我们需要对KieFileSystem进行缓存。

2. 路径解析

我们写入的路径如"src/main/resources/rules/rule01/1.drl",其中"src/main/resources"是固定写法,"rules/rule01"是根据kmodule.xml中的配置动态变化的,而"1.drl"则是规则文件的名字。

四、动态构建KieContainer

如果我们需要每次都创建一个新的KieContainer来覆盖旧的,那么需要确保在覆盖之前销毁旧的KieContainer对象,并处理可能正在运行的规则任务。这种做法可能会导致问题,特别是在系统中已经创建了KieSession并正在处理规则时。通常建议缓存和重复使用KieContainer对象。

五、疑问解答

1. KieContainer是否可以每次都创建新的并用新的覆盖旧的?

答:不建议这样做,因为覆盖旧的KieContainer可能需要销毁现有的KieSession,这可能会导致正在处理的规则出现问题。

2. 如何获取ReleaseId?

答:可以通过kieServices.getRepository().getDefaultReleaseId()方法获取ReleaseId。

3. updateToKieModule的作用是什么?

注意事项:

1. KieFileSystem 必须保持单例状态,即使用同一个实例。

2. KieContainer 也需要保持单例,确保使用同一个实例。

3. 通过 updateToKieModule 方法实现动态更新。

4. 模拟数据库操作,实现规则的增删改查。

服务实现:

在一个 Drools 规则管理服务的实现中,我们有一个 DroolsManager 类来处理规则的增删改查以及规则的执行。这个类使用一个 DroolsRuleMap 来模拟数据库保存规则。当添加或更新规则时,除了更新内存中的规则映射表,还需要调用 DroolsManager 的 addOrUpdateRule 方法将规则写入到 KieModule 中。删除规则时,先从规则映射表中移除,然后调用删除规则的方法从 KieModule 中删除对应规则。

控制层:

在控制层中,我们提供了对应的接口来操作规则。通过 POST 请求添加规则,通过 GET 请求查询所有规则,通过 DELETE 请求删除规则,通过 GET 请求触发规则执行。这些接口的请求数据格式均为 JSON 格式。

测试规则的动态添加:

1. 添加规则:通过 POST 请求向 /drools/rule/add 接口发送规则数据,规则数据包括规则ID、KieBase名称、包名和规则内容。接收到请求后,服务层会验证规则数据,然后将其添加到模拟数据库的映射表中,并调用 DroolsManager 的 addOrUpdateRule 方法将规则写入到 KieModule 中。

规则示例:

plaintext

package rules.rule01

global java.lang.StringBuilder resultInfo

rule "rule-01"

when

$i: Integer()

then

resultInfo.append(drools.getRule().getPackageName()).append(".").append(drools.getRule().getName()).append("执行了,前端传递的参数:").append($i);

end

2. 运行规则:通过 GET 请求向 /drools/rule/fireRule 接口传递 KieBase 名称和参数,服务层会创建 KieSession,插入参数并执行所有规则,然后返回执行结果。

测试运行:

通过 curl 命令向 /drools/rule/fireRule 接口发送 GET 请求,传递 KieBase 名称和参数,可以看到动态加载的规则被执行,并返回执行结果。

原先的规则是这样的:

package rules.rule01

存在一个全局的java.lang.StringBuilder对象名为resultInfo。

规则定义为"rule-01",当接收到一个Integer类型的参数时,将规则的包名、规则名、以及传递的参数追加到resultInfo中。

package rules.rule01

依然保留全局的java.lang.StringBuilder对象resultInfo。

规则"rule-01"的触发条件更为严格,现在要求接收的Integer参数的值必须大于3。满足条件时,才会执行之前的规则动作,即将规则的包名、规则名以及传递的参数追加到resultInfo中。

如何操作呢?通过以下步骤:

curl --location --request POST 'localhost:8080/drools/rule/update'

--header 'Content-Type: application/json'

--data-raw '{...规则内容...}'

  packages文件夹可以删除吗