欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

Drools规则引擎入门使用

时间:2023-07-07
文章目录

pom文件配置一.使用@Configuration 配置,在springboot项目启动时加载

1.配置类2.在service中注入kiession使用3.规则文件内容 二.不使用DRL文件,写在字符串中加载规则

1.使用KieHelper加载规则内容2.根据业务规则,动态生成规则内容字符串。

参考项目

https://github.com/leifchen/hello-drools

pom文件配置

7.57.0.Final org.drools drools-bom ${drools.version} pom import org.kie kie-api org.kie kie-spring org.drools drools-compiler runtime

两种使用方式

一.使用@Configuration 配置,在springboot项目启动时加载 1.配置类

package com.newland.edc.pub.metainfo.config;import lombok.extern.slf4j.Slf4j;import org.kie.api.Kiebase;import org.kie.api.KieServices;import org.kie.api.builder.KieBuilder;import org.kie.api.builder.KieFileSystem;import org.kie.api.builder.KieRepository;import org.kie.api.runtime.KieContainer;import org.kie.api.runtime.KieSession;import org.kie.internal.io.ResourceFactory;import org.kie.spring.KModuleBeanFactoryPostProcessor;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.Resource;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import org.springframework.core.io.support.ResourcePatternResolver;import java.io.IOException;@Slf4j@Configurationpublic class DroolsConfiguration { private static final String RULES_PATH = "rules/"; @Bean @ConditionalOnMissingBean(KieFileSystem.class) public KieFileSystem kieFileSystem() { KieFileSystem kieFileSystem = KieServices.Factory.get().newKieFileSystem(); for (Resource ruleFile : getRuleFiles()) { kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_PATH + ruleFile.getFilename(), "UTF-8")); } return kieFileSystem; } @Bean @ConditionalOnMissingBean(KieContainer.class) public KieContainer kieContainer() { System.setProperty("drools.dateformat","yyyy-MM-dd"); KieRepository kieRepository = KieServices.Factory.get().getRepository(); kieRepository.addKieModule(kieRepository::getDefaultReleaseId); KieBuilder kieBuilder = KieServices.Factory.get().newKieBuilder(kieFileSystem()); kieBuilder.buildAll(); return KieServices.Factory.get().newKieContainer(kieRepository.getDefaultReleaseId()); } @Bean @ConditionalOnMissingBean(Kiebase.class) public Kiebase kiebase() { return kieContainer().getKiebase(); } @Bean @ConditionalOnMissingBean(KieSession.class) public KieSession kieSession() { return kieContainer().newKieSession(); } @Bean @ConditionalOnMissingBean(KModuleBeanFactoryPostProcessor.class) public KModuleBeanFactoryPostProcessor kModuleBeanFactoryPostProcessor(){ return new KModuleBeanFactoryPostProcessor(); } private Resource[] getRuleFiles() { Resource[] resources = new Resource[0]; ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver(); try { resources = resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "** private String generateRuleString(StandardRuleBean ruleBean) { StandardRuleBean standardRule = this.getStandardRule(ruleBean.getRuleId()); //获取获取启停配置详情 List actionStrategyDetail = this.getActionStrategyDetail(ruleBean.getRuleId()); //查询规则操作符 List typeIdList = new ArrayList<>(); typeIdList.add("8002"); List operatorValueList = this.mdiDicCommonDao.getDicValueList(typeIdList); StringBuilder ruleSB = new StringBuilder(); //根据设计规则详情,生成正则表达式提取数据标准值进行匹配 rulevalueType 1 的是自定义 StringBuilder pattern = new StringBuilder(); pattern.append("^"); //限制开头 List keywordList = new ArrayList<>(); String tableNameInstance = ""; //表名示例 for (StandardRuleDetailBean bean : standardRule.getRulevalueList() ) { if (1 == bean.getRulevalueType()) { pattern.append(bean.getRulevalue()); tableNameInstance = tableNameInstance + bean.getRulevalue(); } else { pattern.append("([A-Za-z0-9]+)"); keywordList.add(bean.getRulevalue()); if ("A_CLASS_COMMENT".equalsIgnoreCase(bean.getRulevalue())) { tableNameInstance += "分层名称"; } else if ("A_PATH_COMMENT".equalsIgnoreCase(bean.getRulevalue())) { tableNameInstance += "分域名称"; }else if ("A_LEXICON".equalsIgnoreCase(bean.getRulevalue())) { tableNameInstance += "词汇库"; }else if ("A_2".equalsIgnoreCase(bean.getRulevalue())) { tableNameInstance += "数据周期"; } } } pattern.append("$");//限制结尾 // 用于匹配的数据标准列表 String keywordStr = "String[] keywordList = {""; String join = String.join("","", keywordList); keywordStr += join; keywordStr += ""}"; ruleSB.append("package rulesn" + "n" + "n" + "import com.newland.edc.pub.metainfo.mdi.entity.model.*;n" + "import com.newland.edc.pub.metainfo.standard.code.model.*;n" + "import java.util.Listn" + "import java.util.Mapn" + "import java.util.regex.Matchern" + "import java.util.regex.Patternn" + "import java.lang.Stringn" + "import java.util.HashMapn" + "import org.apache.commons.lang3.StringUtilsn" + "import java.util.Arraysn" + "import com.newland.edc.pub.metainfo.util.metaConstn" + "import java.util.ArrayListn" + "n" + "global List> errListn" + "global EntityBean entityn" + "global List codeListn" + "global List hierarchyListn" + "global List domainListn" + "global List dataCycleListn" + "global org.slf4j.Logger logn" + "n" + "//检查物理表名n"); ruleSB.append("rule "checkStandardCodeEntityNameKeyWord_" + ruleBean.getRuleId() + """); ruleSB.append("n whenn" + " eval(1 == "); ruleSB.append(ruleBean.getIsApply() == null ? 0 : ruleBean.getIsApply()); ruleSB.append(") //启用状态"); ruleSB.append(""); ruleSB.append(" n $entity:EntityBean( "); List whenList = new ArrayList<>(); String when = ""; whenList.add("n tt rootTenantId matches "" + standardRule.getRootTenantId() + """); if (null != actionStrategyDetail && actionStrategyDetail.size() > 0) { for (ConfigurationSwitchBean bean : actionStrategyDetail ) { // 等于操作符 1 为单值匹配 // 稽核时设置 数据周期(entityDesc)、分域名称(pathId )、分层名称(entityComment) 的 中文名,用于作用策略的校验 if ("1".equals(bean.getRuleOperator())) { when = "n tt "; if ("A_10".equalsIgnoreCase(bean.getAttrId())) { // 资源类型 when = when + "resourceType"; } else if ("A_PATH_COMMENT".equalsIgnoreCase(bean.getAttrId())) { // 分域中文名 when = when + "pathId"; } else if ("A_CLASS_COMMENT".equalsIgnoreCase(bean.getAttrId())) { // 分层中文名 when = when + "entityComment"; } else if ("A_2".equalsIgnoreCase(bean.getAttrId())) { // 数据周期 when = when + "entityDesc"; } when = when + " matches "" + bean.getAttrValue().trim().replace(" ", "") + "" //等于 "; whenList.add(when); } else { //其他操作符 非1 为多值匹配 // 2 包含 3 不包含 4 开头 5 结尾 String[] arrValueList = bean.getAttrValue().split("\$"); String matches = "("; List itemList = new ArrayList<>(); for (String str : arrValueList ) { String tempStr = ""; if ("A_10".equalsIgnoreCase(bean.getAttrId())) { // 资源类型 tempStr = tempStr + "resourceType"; } else if ("A_PATH_COMMENT".equalsIgnoreCase(bean.getAttrId())) { // 分域中文名 tempStr = tempStr + "pathId"; } else if ("A_CLASS_COMMENT".equalsIgnoreCase(bean.getAttrId())) { // 分层中文名 tempStr = tempStr + "entityComment"; } else if ("A_2".equalsIgnoreCase(bean.getAttrId())) { // 数据周期 tempStr = tempStr + "entityDesc"; } // 2 包含 3 不包含 4 开头 5 结尾 if ("2".equals(bean.getRuleOperator())) { tempStr = tempStr + " matches ".*" + str + ".*""; } else if ("3".equals(bean.getRuleOperator())) { tempStr = tempStr + " not matches ".*" + str + ".*""; } else if ("4".equals(bean.getRuleOperator())) { tempStr = tempStr + " matches "" + str + ".*""; } else if ("5".equals(bean.getRuleOperator())) { tempStr = tempStr + " matches ".*" + str + """; } itemList.add(tempStr); } matches = matches + String.join(" || ", itemList); if ("2".equals(bean.getRuleOperator())) { matches = matches + ") //包含"; } else if ("3".equals(bean.getRuleOperator())) { matches = matches + ") //不包含"; } else if ("4".equals(bean.getRuleOperator())) { matches = matches + ") // 开头"; } else if ("5".equals(bean.getRuleOperator())) { matches = matches + ") // 结尾"; } whenList.add(matches); } } } ruleSB.append(String.join("n ttt &&", whenList)); ruleSB.append(" n )"); ruleSB.append(" n thenn" + " "); // 规则执行内容 ruleSB.append(" n tt" + keywordStr + " ;n Pattern p= Pattern.compile("" + pattern.toString() + ""); n" + " Matcher matcher =p.matcher(entity.getEntityName());n " + " log.info("解析的正则:【{}】,待解析的字符串:【{}】",""+pattern.toString()+"",entity.getEntityName());n " + " log.info("数据标准列表:{}",Arrays.toString(keywordList));n " + " if (!matcher.find() ) {n" + " Map errMap= new HashMap<>();n" + " errMap.put("type","base");n" + " errMap.put("name","");n" + " errMap.put("keyword","");n" + " errMap.put("ruleName","" + standardRule.getRuleName() + "");n" + " errMap.put("err","表名不符合【"+tableNameInstance+"】");n" + " errList.add(errMap);n" + " } else {n" + " for(int i = 1; i <= matcher.groupCount(); i++) {n" + " log.info("待匹配的值:{},对应的数据标准编码:{} ",matcher.group(i),keywordList[i-1] ); n" + " if ( "A_CLASS_COMMENT".equalsIgnoreCase(keywordList[i-1]) ) {n" + " //分层判断n" + " log.info("进入分层判断:{} ",matcher.group(i) ); n" + " matcheWithStandardCode( matcher.group(i),"" + standardRule.getRuleName() + "","分层名称英文简称",hierarchyList,entity.getEntityName(), errList);n" + " } else if ( "A_PATH_COMMENT".equalsIgnoreCase(keywordList[i-1]) ){n" + " //分域判断n" + " log.info("进入分域判断:{} ",matcher.group(i) ); n" + " matcheWithStandardCode( matcher.group(i),"" + standardRule.getRuleName() + "","分域名称英文简称",domainList,entity.getEntityName(), errList);n" + " } else if ( "A_2".equalsIgnoreCase(keywordList[i-1]) ){n" + " //数据周期n" + " log.info("进入数据周期判断:{} ",matcher.group(i) ); n" + " matcheWithStandardCode( matcher.group(i),"" + standardRule.getRuleName() + "","数据周期英文简称",dataCycleList,entity.getEntityName(), errList);n" + " } else {n" + " log.info("进入词汇判断:{} ",matcher.group(i) ); n" + " //词汇判断n" + " matcheWithStandardCode( matcher.group(i),"" + standardRule.getRuleName() + "","词汇英文简称",codeList,entity.getEntityName(), errList);n" + " }n" + " }n" + " }n" + " "); ruleSB.append("n" + "end"); return ruleSB.toString(); }

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。