数据库存储drools规则并使用
·
使用数据库存储drools规则
config
package com.kittlen.cloud.config;
import com.kittlen.cloud.entities.DroolsInfo;
import com.kittlen.cloud.service.DroolsInfoService;
import lombok.extern.slf4j.Slf4j;
import org.drools.compiler.kie.builder.impl.KieFileSystemImpl;
import org.drools.core.io.impl.InputStreamResource;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.List;
/**
* @author kittlen
* @version 1.0
* @date 2021/9/3 0003
*/
@Configuration
@Slf4j
public class KieConfig {
@Autowired
DroolsInfoService droolsInfoService;
protected KieFileSystem kieFileSystem() {
KieFileSystem kieFileSystem = getKieServices().newKieFileSystem();
List<DroolsInfo> all = droolsInfoService.getAll();
all.forEach(a -> {
//该目录文件为虚拟目录,不需要实际存在,**后缀一定要带.drl**
String path="src/main/resources/rules/" + a.getId() + ".drl";
kieFileSystem.write(path, a.getContent().getBytes());
});
return kieFileSystem;
}
public KieContainer kieContainer() {
final KieRepository kieRepository = getKieServices().getRepository();
kieRepository.addKieModule(() -> kieRepository.getDefaultReleaseId());
KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem());
kieBuilder.buildAll();
return getKieServices().newKieContainer(kieRepository.getDefaultReleaseId());
}
private KieServices getKieServices() {
return KieServices.Factory.get();
}
}
package com.kittlen.cloud.config;
import org.kie.api.KieBase;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
/**
* @author kittlen
* @version 1.0
* @date 2021/9/22 0022
*/
@Configuration
public class KieBeanConfig {
@Resource
KieConfig kieConfig;
@Bean
public MyKieContext myKieContext() {
KieContainer kieContainer = kieConfig.kieContainer();
return new MyKieContext(kieContainer);
}
}
bean
package com.kittlen.cloud.config;
import lombok.extern.slf4j.Slf4j;
import myException.KTNException;
import org.kie.api.KieBase;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.FactHandle;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author kittlen
* @version 1.0
* @date 2021/9/7 0007
*/
@Slf4j
public class MyKieContext {
private KieSession kieSession;
private KieBase kieBase;
private KieContainer kieContainer;
private List<FactHandle> factHandleRecord = new ArrayList<>();
public MyKieContext(KieSession kieSession, KieBase kieBase, KieContainer kieContainer) {
this.kieSession = kieSession;
this.kieBase = kieBase;
this.kieContainer = kieContainer;
}
public MyKieContext(KieContainer kieContainer) {
if (kieContainer != null) {
this.kieContainer = kieContainer;
this.kieSession = kieContainer.newKieSession();
this.kieBase = kieContainer.getKieBase();
}
}
public KieSession getKieSession() {
return kieSession;
}
private void setKieSession(KieSession kieSession) {
this.kieSession = kieSession;
}
public KieBase getKieBase() {
return kieBase;
}
private void setKieBase(KieBase kieBase) {
this.kieBase = kieBase;
}
public KieContainer getKieContainer() {
return kieContainer;
}
private void setKieContainer(KieContainer kieContainer) {
this.kieContainer = kieContainer;
}
public FactHandle insert(Object o) {
FactHandle insert = this.kieSession.insert(o);
factHandleRecord.add(insert);
return insert;
}
public void delete(FactHandle factHandle) {
try {
this.kieSession.delete(factHandle);
factHandleRecord.remove(factHandle);
} catch (Exception e) {
log.error("移除FactHandle时出现异常,异常为:{}", e.getMessage());
}
}
public void clean() {
if (this.kieSession != null) {
factHandleRecord.forEach(f -> {
try {
this.kieSession.delete(f);
} catch (Exception e) {
log.error("移除FactHandle时出现异常,异常为:{}", e.getMessage());
}
});
factHandleRecord.clear();
}
}
/**
* 匹配规则
*
* @return
*/
public int fireAllRules() {
return this.kieSession.fireAllRules();
}
/**
* 更新规则
*
* @param kieSession
* @param kieBase
* @param kieContainer
*/
public void update(KieSession kieSession, KieBase kieBase, KieContainer kieContainer) {
dispose();
this.kieSession = kieSession;
this.kieBase = kieBase;
this.kieContainer = kieContainer;
}
/**
* 更新规则
*
* @param kieContainer
*/
public void update(KieContainer kieContainer) {
if (kieContainer == null) {
throw new KTNException("kieContainer 不能为空");
}
update(kieContainer.newKieSession(), kieContainer.getKieBase(), kieContainer);
}
/**
* 清除规则
*/
public void dispose() {
if (this.kieSession != null) {
this.clean();
this.kieSession.dispose();
}
if (this.kieContainer != null) {
this.kieContainer.dispose();
}
}
public boolean isNullDrools() {
return kieBase == null;
}
/**
* 获取当前规则中所有的包和方法
*
* @return key 包名,value 方法名
*/
public Map<String, List<String>> droolsBaseInfo() {
Map<String, List<String>> map = new HashMap<>();
if (isNullDrools()) {
return map;
}
this.kieBase.getKiePackages().forEach(c -> {
String packageName = c.getName();
List<String> list = new ArrayList<>();
c.getRules().forEach(r -> list.add(r.getName()));
if (!list.isEmpty()) {
map.put(packageName, list);
}
});
return map;
}
}
注意insert时产生的FactHandle 不会被gc释放,在规则使用完毕时需释放规则,可通过delete(FactHandle factHandle)||clean()释放
entity
package com.kittlen.cloud.entities;
import lombok.Data;
import java.io.Serializable;
/**
* @author kittlen
* @version 1.0
* @date 2021/9/3 0003
*/
@Data
public class DroolsInfo implements Serializable {
private String id;
private String content;
}
重新加载规则
package com.kittlen.cloud.controller;
import com.kittlen.cloud.config.KieConfig;
import com.kittlen.cloud.config.MyKieContext;
import com.kittlen.cloud.service.DroolsInfoService;
import entities.Result;
import lombok.extern.slf4j.Slf4j;
import org.kie.api.KieBase;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 重新加载规则
*
* @author kittlen
* @version 1.0
* @date 2021/9/1 0001
*/
@Slf4j
@RestController
@RequestMapping("/kieReloading")
public class KieReloadingController {
@Autowired
MyKieContext myKieContext;
@Autowired
DroolsInfoService droolsInfoService;
@Autowired
KieConfig kieConfig;
/**
* 重新加载规则
*
* @return
*/
@RequestMapping("/reloading")
public Result reloading() {
try {
KieContainer kieContainer = kieConfig.kieContainer();
myKieContext.update(kieContainer);
return Result.ok();
} catch (Exception e) {
log.error("重载kie异常,异常为:{}", e.getMessage());
return Result.error("重新加载规则失败");
}
}
}
规则添加分类,不同的分类执行不同规则
在原基础上添加MyKieContexts
bean
package com.kittlen.cloud.config;
import org.kie.api.runtime.rule.FactHandle;
import java.io.Serializable;
import java.util.Map;
import java.util.Objects;
/**
* @author kittlen
* @version 1.0
* @date 2021/9/7 0007
*/
public class MyKieContexts implements Serializable {
private Map<String, MyKieContext> contexts;
public MyKieContexts(Map<String, MyKieContext> contexts) {
this.contexts = contexts;
}
public MyKieContexts() {
}
public Map<String, MyKieContext> getContexts() {
return contexts;
}
public void setContexts(Map<String, MyKieContext> contexts) {
this.contexts = contexts;
}
public MyKieContext get(String key) {
return this.contexts.get(key);
}
public FactHandle insert(String key, Object o) {
MyKieContext myKieContext = get(key);
return myKieContext == null ? null : myKieContext.insert(o);
}
public int fireAllRules(String key) {
MyKieContext myKieContext = get(key);
return myKieContext == null ? 0 : myKieContext.fireAllRules();
}
public void cover(String key, MyKieContext myKieContext) {
MyKieContext oldMyKieContext = this.contexts.get(key);
if (oldMyKieContext != null) {
oldMyKieContext.dispose();
}
this.contexts.put(key, myKieContext);
}
}
config
package com.kittlen.cloud.config;
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.internal.utils.ServiceRegistryImpl;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author kittlen
* @version 1.0
* @date 2021/9/22 0022
*/
@Component
public class KieConfig {
private KieServices kieServices;
public KieConfig() {
kieServices = KieServices.Factory.get();
}
protected KieFileSystem kieFileSystem(List<String> drools) {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
for (int i = 0; i < drools.size(); i++) {
//该目录文件为虚拟目录,不需要实际存在,**后缀一定要带.drl**
String path = "src/main/resources/rules/" + i + ".drl";
kieFileSystem.write(path, drools.get(i).getBytes());
}
return kieFileSystem;
}
protected KieContainer kieContainer(List<String> drools) {
final KieRepository kieRepository = kieServices.getRepository();
kieRepository.addKieModule(() -> kieRepository.getDefaultReleaseId());
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem(drools));
kieBuilder.buildAll();
return kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
}
public MyKieContext myKieContext(List<String> drools) {
KieContainer kieContainer = kieContainer(drools);
return new MyKieContext(kieContainer);
}
}
package com.kittlen.cloud.config;
import com.kittlen.cloud.entities.DroolsInfo;
import com.kittlen.cloud.service.DroolsInfoService;
import lombok.extern.slf4j.Slf4j;
import myException.KTNException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author kittlen
* @version 1.0
* @date 2021/9/3 0003
*/
@Slf4j
@Configuration
public class KieBeanConfig {
@Autowired
DroolsInfoService droolsInfoService;
@Resource
KieConfig KieConfig;
@Bean
public MyKieContexts myKieContexts() {
try {
List<DroolsInfo> allDrools = droolsInfoService.getAll();
Map<String, List<String>> mapDrools = new HashMap<>();
allDrools.forEach(p -> {
List<String> drools = mapDrools.get(p.getType());
if (drools == null) {
List<String> list = new ArrayList<>();
list.add(p.getContent());
mapDrools.put(p.getType(), list);
} else {
drools.add(p.getContent());
}
});
Map<String, MyKieContext> map = new HashMap<>();
for (String key : mapDrools.keySet()) {
log.info("添加type为:{}的规则",key);
map.put(key, KieConfig.myKieContext(mapDrools.get(key)));
}
return new MyKieContexts(map);
} catch (Exception e) {
log.error("初始化MyKieContexts时异常,异常为:{}", e.getMessage());
throw new KTNException(e);
}
}
}
重新加载规则
package com.kittlen.cloud.controller;
import com.kittlen.cloud.config.MyKieContexts;
import com.kittlen.cloud.config.KieConfig;
import com.kittlen.cloud.entities.DroolsInfo;
import com.kittlen.cloud.service.DroolsInfoService;
import entities.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* 重新加载规则
*
* @author kittlen
* @version 1.0
* @date 2021/9/1 0001
*/
@Slf4j
@RestController
@RequestMapping("/kieReloading")
public class KieReloadingController {
@Autowired
MyKieContexts myKieContexts;
@Autowired
DroolsInfoService droolsInfoService;
@Autowired
KieConfig KieConfig;
/**
* 重新加载规则
*
* @return
*/
@RequestMapping("/reloading")
public Result reloading(String type) {
try {
List<DroolsInfo> byType = droolsInfoService.getByType(type);
List<String> drools = new ArrayList<>();
byType.forEach(d -> drools.add(d.getContent()));
myKieContexts.cover(type, KieConfig.myKieContext(drools));
return Result.ok();
} catch (Exception e) {
log.error("重载kie异常,异常为:{}", e.getMessage());
return Result.error("重新加载规则失败");
}
}
}
entity
package com.kittlen.cloud.entities;
import lombok.Data;
import java.io.Serializable;
/**
* @author kittlen
* @version 1.0
* @date 2021/9/3 0003
*/
@Data
public class DroolsInfo implements Serializable {
private String id;
private String content;
private String type;
}
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)