001package top.cenze.rule.utils; 002 003import cn.hutool.core.collection.CollectionUtil; 004import lombok.extern.slf4j.Slf4j; 005import org.drools.core.base.RuleNameStartsWithAgendaFilter; 006import org.kie.api.KieBase; 007import org.kie.api.KieServices; 008import org.kie.api.builder.*; 009import org.kie.api.runtime.KieContainer; 010import org.kie.api.runtime.KieSession; 011import top.cenze.rule.dto.RuleBaseData; 012 013import java.util.List; 014import java.util.Map; 015 016/** 017 * @desc: 规则管理工具 018 * @author: chengze 019 * @createByDate: 2023/8/8 17:30 020 */ 021@Slf4j 022public class KieUtil { 023 // 规则文件虚拟加载目录路径 024 private static final String KIE_PACKAGE_PATH = "src/main/resources/rules/"; 025 026 private static final KieServices kieServices = KieServices.Factory.get(); 027 // 创建kie文件系统 028 private static final KieFileSystem kieFileSystem = kieServices.newKieFileSystem(); 029 private static KieContainer kieContainer; 030 private static KieBase kieBase; 031 032 public static KieFileSystem getKieFileSystem() { 033 return kieFileSystem; 034 } 035 036 public static KieContainer getKieContainer() { 037 return kieContainer; 038 } 039 040 public static void setKieContainer(KieContainer kieContainer) { 041 KieUtil.kieContainer = kieContainer; 042 } 043 044 public static KieServices getKieServices() { 045 return kieServices; 046 } 047 048 public static KieBase getKieBase() { 049 return kieBase; 050 } 051 052 public static void setKieBase(KieBase kieBase) { 053 KieUtil.kieBase = kieBase; 054 } 055 056 /** 057 * 批量重载规则 058 * @param lstRule 059 */ 060 public static void reloadRules(List<RuleBaseData> lstRule) { 061 if (CollectionUtil.isEmpty(lstRule)) { 062 return; 063 } 064 065 for (RuleBaseData rule : lstRule) { 066 log.info("rule name: {}", rule.getRuleName()); 067 String drlFile = KIE_PACKAGE_PATH + rule.getRuleName() + ".drl"; 068 kieFileSystem.delete(drlFile); 069 kieFileSystem.write(drlFile, rule.getRuleContent()); 070 } 071 072 KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem); 073 kieBuilder.buildAll(); 074 Results results = kieBuilder.getResults(); 075 if (results.hasMessages(Message.Level.ERROR)) { 076 throw new IllegalStateException("### load rules error ###"); 077 } 078 079 kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId()); 080 kieBase = kieContainer.getKieBase(); 081 } 082 083// /** 084// * 重载规则 085// * @param lstRule 086// */ 087// public static void reloadRule(List<RuleDTO> lstRule) { 088// // 借助 kieHelper 添加规则 089// KieHelper kieHelper = new KieHelper(); 090// // 从数据库中获取所有的规则 091// if (CollectionUtil.isNotEmpty(lstRule)) { 092// // 循环加载所有的规则 093// for (RuleDTO rule : lstRule) { 094// String content = rule.getRuleContent(); 095// kieHelper.addContent(content, ResourceType.DRL); 096// } 097// } 098// // 校验规则是否异常 099// Results results = kieHelper.verify(); 100// System.out.println("results: " + JSON.toJSONString(results)); 101// if (results.hasMessages(Message.Level.ERROR)) { 102// System.out.println(results.getMessages()); 103// throw new IllegalStateException("### errors ###"); 104// } 105// // 重置容器 106// KieContainer kieContainer = kieHelper.getKieContainer(); 107// KieUtil.setKieContainer(kieContainer); 108// 109// // 重置规则库 110// KieBase kieBase = kieContainer.getKieBase(); 111// KieUtil.setKieBase(kieBase); 112// } 113 114 /** 115 * 执行所有规则 116 * @param obj 117 */ 118 public static void execAll(Object obj) { 119 KieSession kieSession = KieUtil.getKieBase().newKieSession(); 120 kieSession.insert(obj); 121 kieSession.fireAllRules(); 122 kieSession.dispose(); 123 } 124 125 /** 126 * 执行所有规则 127 * @param obj 待插入的Fact 128 * @param mapGlobal 待传入的全局变量 129 */ 130 public static void execAll(Object obj, Map<String, Object> mapGlobal) { 131 KieSession kieSession = KieUtil.getKieBase().newKieSession(); 132 kieSession.insert(obj); 133 if (CollectionUtil.isNotEmpty(mapGlobal)) { 134 for (Map.Entry<String, Object> entry : mapGlobal.entrySet()) { 135 kieSession.setGlobal(entry.getKey(), entry.getValue()); 136 } 137 } 138 kieSession.fireAllRules(); 139 kieSession.dispose(); 140 } 141 142 /** 143 * 执行指定名称的规则 144 * drl规则文件中 rule 项对应的值 145 * @param obj 待插入的Fact 146 * @param ruleName 规则名(用于匹配包含此字符串的规则) 147 */ 148 public static void execByRuleName(Object obj, String ruleName) { 149 KieSession kieSession = KieUtil.getKieBase().newKieSession(); 150 kieSession.insert(obj); 151 kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter(ruleName)); 152 kieSession.dispose(); 153 } 154 155 /** 156 * 执行指定名称的规则 157 * drl规则文件中 rule 项对应的值 158 * @param obj 待插入的Fact 159 * @param ruleName 规则名(用于匹配包含此字符串的规则) 160 * @param mapGlobal 待传入的全局变量 161 */ 162 public static void execByRuleName(Object obj, String ruleName, Map<String, Object> mapGlobal) { 163 KieSession kieSession = KieUtil.getKieBase().newKieSession(); 164 kieSession.insert(obj); 165 if (CollectionUtil.isNotEmpty(mapGlobal)) { 166 for (Map.Entry<String, Object> entry : mapGlobal.entrySet()) { 167 kieSession.setGlobal(entry.getKey(), entry.getValue()); 168 } 169 } 170 kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter(ruleName)); 171 kieSession.dispose(); 172 } 173}