(二)基于业务需求动态生成 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 {
// 如果数据列表为空,返回 null
return null;
}
}
// 如果启用标志、规则定义详情或 DRT 模板无效,返回 null
return 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 SuppliersNumberFactPVO
purchaseMethod: String
projectStage: String
suppliersNumber: Integer
end
declare SubmitTaskVerifyMessage
state: int
text: String
end
rule "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个不得开标");
end
rule "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 规则文件。通过这些步骤,可以实现更加灵活和高效的业务规则管理系统。