import java.util.List;
import org.drools.core.event.DebugRuleRuntimeEventListener;
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.Message;
import org.kie.api.io.Resource;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.StatelessKieSession;
public class KieSessionFactory {
private static KieSession kieSession;
private KieSessionFactory() {
}
public static KieSession get() throws Exception {
try {
if (kieSession != null) {
kieSession.dispose();
kieSession = null;
}
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kfs = kieServices.newKieFileSystem();
Resource resource = kieServices.getResources().newClassPathResource("conf/ksession/clock.drl");
resource.setResourceType(ResourceType.DRL);
kfs.write(resource);
KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
if (kieBuilder.getResults().getMessages(Message.Level.ERROR).size() > 0) {
throw new Exception();
}
KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
KieBase kBase = kieContainer.getKieBase();
kieSession = kBase.newKieSession();
return kieSession;
} catch (Exception ex) {
throw ex;
}
}
public static void disposeKieSession() {
if (kieSession != null) {
kieSession.dispose();
kieSession = null;
}
}
public static KieSession newKieSession(List<String> jarFilePath , String drlFilePath) throws Exception {
DroolsClasspathLoader.loadClasspath(jarFilePath) ;
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kfs = kieServices.newKieFileSystem();
Resource resource = kieServices.getResources().newFileSystemResource(drlFilePath);
resource.setResourceType(ResourceType.DRL);
kfs.write(resource);
KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
if (kieBuilder.getResults().getMessages(Message.Level.ERROR).size() > 0) {
throw new Exception();
}
KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
KieBase kBase = kieContainer.getKieBase();
KieSession kieSession = kBase.newKieSession();
kieSession.addEventListener(new DebugRuleRuntimeEventListener());
return kieSession;
}
public static StatelessKieSession newStatelessKieSession(String classPath) throws Exception {
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kfs = kieServices.newKieFileSystem();
Resource resource = kieServices.getResources().newClassPathResource(classPath);
resource.setResourceType(ResourceType.DRL);
kfs.write(resource);
KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
if (kieBuilder.getResults().getMessages(Message.Level.ERROR).size() > 0) {
throw new Exception();
}
KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
KieBase kBase = kieContainer.getKieBase();
StatelessKieSession kiesession = kBase.newStatelessKieSession();
return kiesession;
}
}
import org.kie.internal.KnowledgeBase;
public class KnowledgeBaseCacheValue{
private KnowledgeBase knowledgeBase ;
private Class<?> clz ;
private String ruleCheck ;
private Integer drlVersion ;
public KnowledgeBase getKnowledgeBase() {
return knowledgeBase;
}
public void setKieSession(KnowledgeBase knowledgeBase) {
this.knowledgeBase = knowledgeBase;
}
public Class<?> getClz() {
return clz;
}
public void setClz(Class<?> clz) {
this.clz = clz;
}
public String getRuleCheck() {
return ruleCheck;
}
public void setRuleCheck(String ruleCheck) {
this.ruleCheck = ruleCheck;
}
public Integer getDrlVersion() {
return drlVersion;
}
public void setDrlVersion(Integer drlVersion) {
this.drlVersion = drlVersion;
}
public void setKnowledgeBase(KnowledgeBase knowledgeBase) {
this.knowledgeBase = knowledgeBase;
}
public KnowledgeBaseCacheValue(KnowledgeBase knowledgeBase, Class<?> clz, String ruleCheck , Integer drlVersion) {
super();
this.knowledgeBase = knowledgeBase;
this.clz = clz;
this.ruleCheck = ruleCheck;
this.drlVersion = drlVersion ;
}
public KnowledgeBaseCacheValue(){
}
}
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
public class PcsfCacheQuartz implements InitializingBean{
private static final Logger logger = LoggerFactory.getLogger(PcsfCacheQuartz.class);
private static String drlFilePath = PropertiesUtils.getProperty("drl.file.path");
private static String mavenJarFilePath = PropertiesUtils.getProperty("maven.jar.file.path");
private static ConcurrentHashMap<Integer, KnowledgeBaseCacheValue> KnowledgeBaseCacheMap;
private static ConcurrentHashMap<Integer, DroolsCallCache> droolsCallCacheMap ;
public void afterPropertiesSet() throws Exception {
KnowledgeBaseCacheMap = new ConcurrentHashMap<Integer, KnowledgeBaseCacheValue>() ;
DroolsPomDao droolsPomDao = new DroolsPomDaoImpl() ;
List<DroolsPom> droolsPoms = droolsPomDao.findAllDroolsPom() ;
if(! droolsPoms.isEmpty()){
for(DroolsPom droolsPom : droolsPoms){
PcsfAppUtils.deletePath((mavenJarFilePath + File.separator + droolsPom.getPomId()).replace("\\", "/")) ;
}
}
droolsCallCacheMap = new ConcurrentHashMap<Integer, DroolsCallCache>() ;
refreshCache() ;
}
public static KnowledgeBaseCacheValue getKnowledgeBase(Integer ruleId) throws Exception{
return KnowledgeBaseCacheMap.get(ruleId) ;
}
public static DroolsCallCache getDroolsCallCache(Integer ruleId) throws Exception{
return droolsCallCacheMap.get(ruleId) ;
}
public static boolean KnowledgeBaseCacheContainsRuleId(Integer ruleId){
if(KnowledgeBaseCacheMap == null){
return false ;
}
return KnowledgeBaseCacheMap.containsKey(ruleId) ;
}
public static boolean CallCacheContainsRuleId(Integer ruleId){
if(droolsCallCacheMap == null){
return false ;
}
return droolsCallCacheMap.containsKey(ruleId) ;
}
private static void removeKnowledgeBaseCacheRuleByRuleId(Integer ruleId){
if(KnowledgeBaseCacheMap.containsKey(ruleId)){
KnowledgeBaseCacheValue toDelKnowledgeBaseCacheValue = KnowledgeBaseCacheMap.get(ruleId) ;
KnowledgeBaseCacheMap.remove(ruleId) ;
toDelKnowledgeBaseCacheValue = null ;
}
}
private static void refreshCache(){
refrshCalls() ;
DroolsPomDao droolsPomDao = new DroolsPomDaoImpl() ;
List<DroolsPom> droolsPoms = droolsPomDao.findAllDroolsPom() ;
refreshPomDownload(droolsPoms) ;
refreshRules() ;
}
private static void refrshCalls(){
DroolsCallDao droolsCallDao = new DroolsCallDaoImpl() ;
Map<Integer , DroolsCallCache> droolsCallCache = droolsCallDao.findAllLastMonthDroolsCallCaches() ;
if(! droolsCallCache.isEmpty()){
droolsCallCacheMap = new ConcurrentHashMap<Integer, DroolsCallCache>() ;
droolsCallCacheMap.putAll(droolsCallCache) ;
}
}
private static void refreshPomDownload(List<DroolsPom> droolsPoms){
if(droolsPoms == null || droolsPoms.isEmpty()){
return ;
}
logger.info("droolsPoms=" + droolsPoms) ;
for(DroolsPom droolsPom : droolsPoms){
if(! droolsPom.getJarPaths().isEmpty()){
if(! PcsfAppUtils.isExistsFilePaths(mavenJarFilePath , droolsPom.getJarPaths())){
try {
Params param = new Params(droolsPom.getPomGroupId(), droolsPom.getPomArtifactId() , droolsPom.getPomVersion(), (mavenJarFilePath + File.separator + droolsPom.getPomId()).replace("\\", "/")) ;
MavenJarUtils.DownLoad(param) ;
} catch (Exception e) {
logger.error("Cache Jar包下载失败"+e.getMessage());
}
}
}
}
}
private static void refreshRules(){
DroolsRuleDao droolsRuleDao = new DroolsRuleDaoImpl() ;
List<DroolsRule> droolsRules = droolsRuleDao.findAllDroolsRule() ;
if(droolsRules == null || droolsRules.isEmpty()){
return ;
}
for(DroolsRule rule : droolsRules){
Integer ruleId = rule.getRuleId() ;
if(! rule.getDeploy()){
removeKnowledgeBaseCacheRuleByRuleId(ruleId) ;
continue ;
}
try {
if(KnowledgeBaseCacheMap.containsKey(ruleId)){
if(Ints.compare(KnowledgeBaseCacheMap.get(ruleId).getDrlVersion() , rule.getDrlVersion()) == 0){
continue ;
}
}
File file = new File((drlFilePath + File.separator + "pcsf" + rule.getRuleId()).replace("\\", "/")) ;
if(!file.exists() && !file.isDirectory()){
file.mkdirs();
}
String drlPath = (drlFilePath + File.separator + "pcsf" + rule.getRuleId() + File.separator + rule.getDrlVersion() + ".drl").replace("\\", "/");
File drlFile = new File(drlPath) ;
if(! drlFile.exists()){
DroolsRuleDetailDao ruleDetailDao = new DroolsRuleDetailDaoImpl();
List<DroolsRuleDetail> ruleDetails = ruleDetailDao.findRuleDetailsByRuleId(ruleId);
DrlAutoGenerate.autoGenerate(ruleDetails, rule , drlPath);
}
KnowledgeBaseCacheValue kieSessionByRuleId = getKnowledgeBaseCacheValueByRuleId(rule);
removeKnowledgeBaseCacheRuleByRuleId(ruleId) ;
KnowledgeBaseCacheMap.put(ruleId, kieSessionByRuleId) ;
}catch (Exception e) {
logger.error(e.getMessage()) ;
removeKnowledgeBaseCacheRuleByRuleId(ruleId) ;
}
}
List<Integer> used = Lists.newArrayList(KnowledgeBaseCacheMap.keySet()) ;
logger.info("used = " + used) ;
}
@SuppressWarnings("deprecation")
private static KnowledgeBaseCacheValue getKnowledgeBaseCacheValueByRuleId(DroolsRule rule) throws Exception{
Class<?> clz = null ;
KnowledgeBase kbase = null ;
DroolsPomDao droolsPomDao = new DroolsPomDaoImpl() ;
DroolsPom droolsPom = droolsPomDao.findDroolsPomByRuleId(rule.getRuleId()) ;
List<String> lastJarPaths = droolsPom.getJarPaths() ;
if(! PcsfAppUtils.isExistsFilePaths(mavenJarFilePath, lastJarPaths)){
throw new Exception("getKnowledgeBaseCacheValueByRuleId 找不到" + lastJarPaths) ;
}
String drlPath = (drlFilePath + File.separator + "pcsf" + rule.getRuleId() + File.separator + rule.getDrlVersion() + ".drl").replace("\\", "/");
File drlFile = new File(drlPath) ;
if(! drlFile.exists()){
throw new Exception("getKnowledgeBaseCacheValueByRuleId 找不到"+ drlPath) ;
}
if(Strings.isNullOrEmpty(rule.getRuleJavabeanClassname())){
throw new Exception("getKnowledgeBaseCacheValueByRuleId rule="+ rule.getRuleId() + "beanClassname为空") ;
}
List<String> jarPaths = Lists.newArrayList() ;
for (String jarPath : lastJarPaths) {
jarPaths.add((mavenJarFilePath + File.separator + jarPath).replace("\\", "/")) ;
}
try {
KieSession kSession = KieSessionFactory.newKieSession(jarPaths , drlPath) ;
kSession.dispose() ;
DroolsClasspathLoader.loadClasspath(jarPaths) ;
clz = DroolsClasspathLoader.classloader.loadClass(rule.getRuleJavabeanClassname());
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newFileResource(drlPath) , ResourceType.DRL);
kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
} catch (Exception e) {
throw new Exception("根据ruleId=" + rule.getRuleId() + "获取KnowledgeBase失败"+e.getMessage()) ;
}
logger.info("根据ruleId=" + rule.getRuleId() + "刷新KnowledgeBase成功!");
return new KnowledgeBaseCacheValue(kbase, clz , rule.getRuleCheck() , rule.getDrlVersion()) ;
}
public static ConcurrentHashMap<Integer, KnowledgeBaseCacheValue> getKnowledgeBaseCache() {
return KnowledgeBaseCacheMap ;
}
}
import java.util.List;
import org.kie.internal.runtime.StatefulKnowledgeSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DroolsExecuteAtomServiceImpl implements PcsfDroolsExecuteAtomService{
private static final Logger logger = LoggerFactory.getLogger(ApiController.class);
@Autowired
private DroolsCallAsyncService droolsCallAsyncService ;
public DroolsResponse executeRulesPcsf(List paramList, String ruleId, String checkId) {
Integer fireRules = -1 ;
StatefulKnowledgeSession ksession = null ;
try {
Integer rid = Integer.valueOf(ruleId) ;
droolsCallAsyncService.callDroolsByRuleId(rid) ;
KnowledgeBaseCacheValue cacheValue = PcsfCacheQuartz.getKnowledgeBase(rid) ;
if(cacheValue == null || !cacheValue.getRuleCheck().equals(checkId)){
return new DroolsResponse("failed" , paramList) ;
}
ksession = cacheValue.getKnowledgeBase().newStatefulKnowledgeSession();
for(int i = 0 ; i < paramList.size() ; i++){
ksession.insert(paramList.get(i)) ;
}
fireRules = ksession.fireAllRules() ;
}catch (Exception e) {
logger.error(e.getMessage()) ;
return new DroolsResponse("failed" , paramList) ;
}finally{
if(ksession != null){
ksession.dispose();
}
}
return new DroolsResponse("success", paramList, ruleId, checkId, fireRules) ;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.0.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<context:component-scan base-package="com.ceair"/>
<task:annotation-driven/>
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<task:executor id="pcsf_calls_save" pool-size="20" queue-capacity="1000" rejection-policy="CALLER_RUNS" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="page/app/html/" />
<property name="suffix" value=".html" />
</bean>
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"
p:supportedMediaTypes="*/*" />
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
<bean id="propertyConfigurer" class="com....utils.PropertiesUtils">
<property name="locations">
<list>
<value> classpath:app.properties </value>
</list>
</property>
</bean>
<bean id="SpringQtzJob" class="com...PcsfCacheQuartz"/>
<bean id="SpringQtzJobMethod" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="SpringQtzJob"/>
</property>
<property name="targetMethod">
<value>refreshCache</value>
</property>
</bean>
<bean id="CronTriggerBean" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="SpringQtzJobMethod"></property>
<property name="cronExpression" value="0 0/10 * * * ?"></property>
</bean>
<bean id="SpringJobSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="CronTriggerBean"/>
</list>
</property>
</bean>
<!-- <dubbo:application name="pcsf_drools"/>
<dubbo:registry protocol="zookeeper" address="${zk_address}"/>
<dubbo:service interface="com...PcsfDroolsExecuteAtomService"
ref="pcsfDroolsService" />
<dubbo:protocol name="dubbo" port="20880" />
<bean id="pcsfDroolsService" class="com...DroolsExecuteAtomServiceImpl"/>
-->
</beans>