【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 规则文件:详细实现与测试指南,形成规则引擎闭环。

相关推荐
用户83580861879122 分钟前
撮合引擎 OrderBook 的 100ns 之路:无锁 RingBuffer + 伪共享消除,Go 1.22 下单 op 11ns
后端
用户8818630013626 分钟前
用Node.js写一个简单的API请求日志中间件
后端
用户83580861879132 分钟前
Go 高并发下的“内存刺客“:自研 Size-Class 无锁对象池,把 sync.Pool 的 P99 从 128μs 压到 41μs
后端
货拉拉技术38 分钟前
资损下降 99.96% 的背后— AI 资损防控平台实战
后端
山水洛行3 小时前
AI Agent 智能体记忆:从检索到被治理的数据系统
后端
卷无止境3 小时前
C++20 的概念与约束:让模板编程终于"说人话"
后端
Ai拆代码的曹操3 小时前
一次排查三种连接泄漏模式,再也不怕 HikariCP 连接池爆满了
后端
人活一口气3 小时前
从JVM调优到MCP协议:Java全栈技术体系深度总结与企业级架构实践
java·spring boot
咪库咪库咪3 小时前
Cypher入门
后端