【Drools】(二)基于业务需求动态生成 DRL 规则文件:事实与动作定义详解

【Drools】(二)基于业务需求动态生成 DRL 规则文件:事实与动作定义详解

在现代业务规则管理系统中,灵活高效地生成和管理规则至关重要。通过上一部分的DRT 规则模板(请参考(一)基于业务需求动态生成 DRT 规则模板:事实与动作定义详解)结合业务上的动作定义和事实定义,自动生成 DRL(Drools Rule Language)规则文件,可以根据业务需求自定义和调整规则,从而提高业务的灵活性和响应速度。本文将详细介绍如何根据业务需求动态生成 DRL 规则文件,并结合示例界面图和代码进行说明。

drools介绍,请参考: 探索Drools:Java世界的规则引擎

图示示例说明

下图数据是根据事实定义和动作定义,自动初始化数据,业务人员可自行定义,主要包含了规则信息和规则设置两个部分:

  • 规则信息:包括规则名称、规则分类、规则标识以及是否启用的设置。
  • 规则设置:是否启用左边部分是事实数据,右边部分是动作数据,每一行是一条规则。

生成 DRL 规则文件的代码

以下代码演示了如何根据业务需求动态生成 DRL 规则文件。代码通过读取 JSON 格式的规则定义,过滤和转换数据,然后使用 Drools 提供的 ObjectDataCompiler 来生成 DRL 文件。

代码详解
java 复制代码
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;
    }
}

代码解析

  1. 检查规则启用标志和内容有效性

    • 首先,检查 saveReSetPVO 对象的 enableFlag 是否为启用状态,并确保 defineDetaildrtRuleTemplate 不为空。
  2. 转换和过滤规则定义数据

    • 使用 JacksonUtil.json2bean 将 JSON 格式的规则定义转换为 List<Map<String, Object>>
    • 通过 streamfilter 方法,过滤出 enable_flag 为启用状态的规则。
  3. 处理空值

    • 遍历规则列表,将所有空值转换为字符串 "null",以避免生成规则时出现空值错误。
  4. 生成 DRL 规则文件

    • 将 DRT 模板字符串转换为输入流,使用 Drools 提供的 ObjectDataCompiler 根据模板和数据生成 DRL 规则文件。

业务规则配置示例

根据图示的规则编辑界面,以下是生成的 DRL 规则文件示例:

java 复制代码
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 文件可以根据不同的业务场景进行定制化,提升了业务规则配置的灵活性和效率。

接下来可以学习,(三)基于业务数据动态调用 DRL 规则文件:详细实现与测试指南,形成规则引擎闭环。

相关推荐
MrSYJ12 分钟前
UserDetailService是在什么环节生效的,为什么自定义之后就能被识别
java·spring boot·后端
张志鹏PHP全栈13 分钟前
Rust第一天,安装Visual Studio 2022并下载汉化包
后端
estarlee20 分钟前
公交线路规划免费API接口详解
后端
无责任此方_修行中32 分钟前
从 HTTP 轮询到 MQTT:我们在 AWS IoT Core 上的架构演进与实战复盘
后端·架构·aws
考虑考虑38 分钟前
postgressql更新时间
数据库·后端·postgresql
long3161 小时前
构建者设计模式 Builder
java·后端·学习·设计模式
吐个泡泡v1 小时前
Maven 核心命令详解:compile、exec:java、package 与 IDE Reload 机制深度解析
java·ide·maven·mvn compile
天上掉下来个程小白2 小时前
微服务-01.导入黑马商城
java·微服务·架构
Noii.2 小时前
Spring Boot初级概念及自动配置原理
java·spring boot·后端
探索java2 小时前
Tomcat Server 组件原理
java·后端·tomcat