(二)基于业务需求动态生成 DRL 规则文件:事实与动作定义详解
在现代业务规则管理系统中,灵活高效地生成和管理规则至关重要。通过上一部分的DRT 规则模板(请参考
:(一)基于业务需求动态生成 DRT 规则模板:事实与动作定义详解)结合业务上的动作定义和事实定义,自动生成 DRL(Drools Rule Language)规则文件,可以根据业务需求自定义和调整规则,从而提高业务的灵活性和响应速度。本文将详细介绍如何根据业务需求动态生成 DRL 规则文件,并结合示例界面图和代码进行说明。
图示示例说明
下图数据是根据事实定义和动作定义,自动初始化数据,业务人员可自行定义,主要包含了规则信息和规则设置两个部分:
- 规则信息:包括规则名称、规则分类、规则标识以及是否启用的设置。
- 规则设置:是否启用左边部分是事实数据,右边部分是动作数据,每一行是一条规则。
生成 DRL 规则文件的代码
以下代码演示了如何根据业务需求动态生成 DRL 规则文件。代码通过读取 JSON 格式的规则定义,过滤和转换数据,然后使用 Drools 提供的 ObjectDataCompiler
来生成 DRL 文件。
代码详解
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import org.drools.template.ObjectDataCompiler;/*** DroolsRuleUtil 类用于根据业务需求动态生成 DRL 规则文件。*/
public class DroolsRuleUtil {/*** 生成 DRL 规则文件。** @param saveReSetPVO 保存规则设置的对象* @return 生成的 DRL 规则字符串*/public static String generateDroolsDrl(SaveReSetPVO saveReSetPVO) {// 检查规则启用标志、规则定义详情和 DRT 模板是否有效if (Objects.equals(saveReSetPVO.getEnableFlag(), ConstantsRe.YES)&& StringUtils.isNotBlank(saveReSetPVO.getDefineDetail())&& StringUtils.isNotBlank(saveReSetPVO.getDrtRuleTemplate())) {// 将 JSON 格式的规则定义转换为 List<Map<String, Object>>List<Map<String, Object>> dataList = JacksonUtil.json2bean(saveReSetPVO.getDefineDetail(),new TypeReference<List<Map<String, Object>>>() {});// 过滤出启用的规则dataList = dataList.stream().filter(e -> Objects.equals(ConvertUtil.createInteger(e.get("enable_flag")), ConstantsRe.YES)).collect(Collectors.toList());if (CollectionUtils.isNotEmpty(dataList)) {// 将空值转换为 "null"for (Map<String, Object> map : dataList) {for (Map.Entry<String, Object> entry : map.entrySet()) {if (StringUtils.isBlank(ConvertUtil.createString(entry.getValue()))) {map.replace(entry.getKey(), "null");}}}// 将 DRT 模板字符串转换为输入流InputStream inputStream = new ByteArrayInputStream(saveReSetPVO.getDrtRuleTemplate().getBytes());// 使用 ObjectDataCompiler 根据模板和数据生成 DRL 规则文件return new ObjectDataCompiler().compile(dataList, inputStream);} else {// 如果数据列表为空,返回 nullreturn null;}}// 如果启用标志、规则定义详情或 DRT 模板无效,返回 nullreturn null;}
}
代码解析
-
检查规则启用标志和内容有效性:
- 首先,检查
saveReSetPVO
对象的enableFlag
是否为启用状态,并确保defineDetail
和drtRuleTemplate
不为空。
- 首先,检查
-
转换和过滤规则定义数据:
- 使用
JacksonUtil.json2bean
将 JSON 格式的规则定义转换为List<Map<String, Object>>
。 - 通过
stream
和filter
方法,过滤出enable_flag
为启用状态的规则。
- 使用
-
处理空值:
- 遍历规则列表,将所有空值转换为字符串
"null"
,以避免生成规则时出现空值错误。
- 遍历规则列表,将所有空值转换为字符串
-
生成 DRL 规则文件:
- 将 DRT 模板字符串转换为输入流,使用 Drools 提供的
ObjectDataCompiler
根据模板和数据生成 DRL 规则文件。
- 将 DRT 模板字符串转换为输入流,使用 Drools 提供的
业务规则配置示例
根据图示的规则编辑界面,以下是生成的 DRL 规则文件示例:
package org.drools
import com.xinyuan.re.utils.DateUtils
declare SuppliersNumberFactPVOpurchaseMethod: StringprojectStage: StringsuppliersNumber: Integer
end
declare SubmitTaskVerifyMessagestate: inttext: String
endrule "re_openbid_supplier_count_0"when $suppliers_number_fact_p_v_o : SuppliersNumberFactPVO(("00380002,00380024,00380020,00380003" == "null" || purchaseMethod memberOf "00380002,00380024,00380020,00380003") && ("1" == "null" || projectStage == 1 ) && ("3" == "null" || suppliersNumber < 3));$submit_task_verify_message : SubmitTaskVerifyMessage();then $submit_task_verify_message.setState(2);$submit_task_verify_message.setText("招标的项目,投标人数量少于3个不得开标");
endrule "re_openbid_supplier_count_1"when $suppliers_number_fact_p_v_o : SuppliersNumberFactPVO(("00380002,00380003,00380020,00380024" == "null" || purchaseMethod memberOf "00380002,00380003,00380020,00380024") && ("2" == "null" || projectStage == 2 ) && ("3" == "null" || suppliersNumber < 3));$submit_task_verify_message : SubmitTaskVerifyMessage();then $submit_task_verify_message.setState(2);$submit_task_verify_message.setText("资审阶段的项目,申请人数量少于3个不得开启");
end
结论
通过以上代码和示例,我们可以根据业务需求动态生成 DRL 规则文件。动态生成的 DRL 文件可以根据不同的业务场景进行定制化,提升了业务规则配置的灵活性和效率。
下一步可以进一步完善规则引擎闭环,包括基于 DRT 规则模板动态配置生成 DRL 规则文件,以及基于业务需求动态调用 DRL 规则文件。通过这些步骤,可以实现更加灵活和高效的业务规则管理系统。