From e9aa0fabe639d0a012c37134c37f5b3c24ccd554 Mon Sep 17 00:00:00 2001 From: mengyxu Date: Sat, 23 Sep 2023 15:44:36 +0800 Subject: [PATCH] v0.0.0 --- logback.xml | 1 + pom.xml | 29 ++----- .../vip/xumy/drools/conf/DroolsConfig.java | 83 ++++++++++--------- .../xumy/drools/ctrl/CdrRuleController.java | 11 ++- .../vip/xumy/drools/pojo/DroolsBurster.java | 41 ++++----- .../{action => service}/CdrGenerator.java | 13 ++- .../xumy/drools/service/CdrRuleService.java | 15 ++-- .../xumy/drools/service/DroolsApiService.java | 39 --------- src/main/resources/{rules => }/hello.drl | 6 +- src/main/resources/rules/test007.drl | 33 ++++++++ 10 files changed, 138 insertions(+), 133 deletions(-) rename src/main/java/vip/xumy/drools/{action => service}/CdrGenerator.java (95%) delete mode 100644 src/main/java/vip/xumy/drools/service/DroolsApiService.java rename src/main/resources/{rules => }/hello.drl (97%) create mode 100644 src/main/resources/rules/test007.drl diff --git a/logback.xml b/logback.xml index 0c05c5c..4406cac 100644 --- a/logback.xml +++ b/logback.xml @@ -37,6 +37,7 @@ + diff --git a/pom.xml b/pom.xml index 31b55d7..267861d 100644 --- a/pom.xml +++ b/pom.xml @@ -23,8 +23,8 @@ 1.1.9 3.5.1 1.4.6 - 7.74.1.Final - 7.74.1.Final + 8.44.0.Final + 7.74.1.Final @@ -98,34 +98,17 @@ ${mybatis.pagehelper.version} - org.drools - drools-core - ${drools.version} - - - org.drools - drools-compiler - ${drools.version} + drools-mvel + ${kie.version} org.drools - drools-templates - ${drools.version} - - - org.kie - kie-api - ${drools.version} - - - org.kie - kie-spring - ${drools.version} + drools-decisiontables + ${kie.version} - diff --git a/src/main/java/vip/xumy/drools/conf/DroolsConfig.java b/src/main/java/vip/xumy/drools/conf/DroolsConfig.java index 02cfaad..3ffead8 100644 --- a/src/main/java/vip/xumy/drools/conf/DroolsConfig.java +++ b/src/main/java/vip/xumy/drools/conf/DroolsConfig.java @@ -9,28 +9,29 @@ 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.builder.ReleaseId; import org.kie.api.conf.EventProcessingOption; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.KieSessionConfiguration; import org.kie.api.runtime.conf.ClockTypeOption; +import org.kie.internal.conf.MultithreadEvaluationOption; import org.kie.internal.io.ResourceFactory; -import org.kie.spring.KModuleBeanFactoryPostProcessor; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.system.ApplicationHome; -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 org.springframework.stereotype.Component; +@Component @Configuration public class DroolsConfig { private static final String RULES_PATH = "rules/"; - public static final String JAR_ROOT_PATH; public static final String CLASSPATH = "classpath:"; -// private static final String JAVA_ROOT = "src/main/java/"; -// private static final String RESOURCES_ROOT = "src/main/resources/"; + public static final String JAR_ROOT_PATH; + private static KieContainer kieContainer; + private static KieBase kieBase; static { ApplicationHome h = new ApplicationHome(DroolsConfig.class); @@ -38,9 +39,16 @@ public class DroolsConfig { JAR_ROOT_PATH = jarF.getParentFile().getAbsolutePath() + '/'; } - @Bean - @ConditionalOnMissingBean(KieFileSystem.class) - public KieFileSystem kieFileSystem() throws IOException { + public void reloadRules() throws IOException { + if (kieContainer != null) { + kieContainer.dispose(); + kieContainer = null; + kieBase = null; + } + kieBase(); + } + + private KieFileSystem kieFileSystem() throws IOException { KieFileSystem kieFileSystem = getKieServices().newKieFileSystem(); File dir = new File(JAR_ROOT_PATH + RULES_PATH); if (dir.exists()) { @@ -57,6 +65,20 @@ public class DroolsConfig { return kieFileSystem; } + private ReleaseId build() throws IOException { + final KieRepository kieRepository = getKieServices().getRepository(); + // 设置时间格式 + System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss"); + ReleaseId releaseId = kieRepository.getDefaultReleaseId(); + kieRepository.removeKieModule(releaseId); + kieRepository.addKieModule(kieRepository::getDefaultReleaseId); + KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem()); + kieBuilder.buildAll(); + return releaseId; + } + +// private static final String JAVA_ROOT = "src/main/java/"; +// private static final String RESOURCES_ROOT = "src/main/resources/"; // private String getPath(org.kie.api.io.Resource resource) { // String target = resource.getTargetPath() != null ? resource.getTargetPath() : resource.getSourcePath(); // if (target != null) { @@ -72,47 +94,34 @@ public class DroolsConfig { // } // } - @Bean - @ConditionalOnMissingBean(KieContainer.class) public KieContainer kieContainer() throws IOException { - KieServices kieServices = getKieServices(); - final KieRepository kieRepository = kieServices.getRepository(); - // 设置时间格式 - System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss"); - kieRepository.addKieModule(kieRepository::getDefaultReleaseId); - build(); - return kieServices.newKieContainer(kieRepository.getDefaultReleaseId()); + if (kieContainer != null) { + return kieContainer; + } + kieContainer = getKieServices().newKieContainer(build()); + return kieContainer; } - public KieServices getKieServices() { + private KieServices getKieServices() { return KieServices.Factory.get(); } - public void build() throws IOException { - KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem()); - kieBuilder.buildAll(); - } - - @Bean - @ConditionalOnMissingBean(KieBase.class) public KieBase kieBase() throws IOException { - KieBase kieBase = kieContainer().getKieBase(); + if (kieBase != null) { + return kieBase; + } + KieBaseConfiguration baseConf = KieServices.Factory.get().newKieBaseConfiguration(); + baseConf.setOption(EventProcessingOption.STREAM); + baseConf.setOption(MultithreadEvaluationOption.YES); + kieBase = kieContainer().newKieBase(baseConf); return kieBase; } - @Bean - @ConditionalOnMissingBean(KieSession.class) public KieSession kieSession() throws IOException { - KieBaseConfiguration baseConf = KieServices.Factory.get().newKieBaseConfiguration(); - baseConf.setOption(EventProcessingOption.STREAM); KieSessionConfiguration sessConf = KieServices.Factory.get().newKieSessionConfiguration(); sessConf.setOption(ClockTypeOption.get("pseudo")); - return kieContainer().newKieSession(sessConf); + KieSession kieSession = kieBase().newKieSession(sessConf, null); + return kieSession; } - @Bean - @ConditionalOnMissingBean(KModuleBeanFactoryPostProcessor.class) - public KModuleBeanFactoryPostProcessor kiePostProcessor() { - return new KModuleBeanFactoryPostProcessor(); - } } diff --git a/src/main/java/vip/xumy/drools/ctrl/CdrRuleController.java b/src/main/java/vip/xumy/drools/ctrl/CdrRuleController.java index 555ee61..148440f 100644 --- a/src/main/java/vip/xumy/drools/ctrl/CdrRuleController.java +++ b/src/main/java/vip/xumy/drools/ctrl/CdrRuleController.java @@ -16,9 +16,14 @@ public class CdrRuleController { @Autowired private CdrRuleService cdrRuleService; - @GetMapping("test/{loop}") - public void fireAllRules4One(@PathVariable("loop")Integer loop) throws IOException { - cdrRuleService.test(loop); + @GetMapping("{name}/{loop}") + public void fireAllRules4One(@PathVariable("name")String name, @PathVariable("loop")Integer loop) throws IOException { + cdrRuleService.test(name, loop); + } + + @GetMapping("reload") + public void relaodRules() throws IOException { + cdrRuleService.relaodRules(); } } \ No newline at end of file diff --git a/src/main/java/vip/xumy/drools/pojo/DroolsBurster.java b/src/main/java/vip/xumy/drools/pojo/DroolsBurster.java index 5850e87..c9f559a 100644 --- a/src/main/java/vip/xumy/drools/pojo/DroolsBurster.java +++ b/src/main/java/vip/xumy/drools/pojo/DroolsBurster.java @@ -5,47 +5,50 @@ import java.util.concurrent.TimeUnit; import org.drools.core.time.SessionPseudoClock; import org.kie.api.runtime.KieSession; -//@Log4j2 + public class DroolsBurster { private KieSession ks; private SessionPseudoClock clock; private long currentTime; private int burst; private int count; - - public DroolsBurster(KieSession ks, String clockType, int burst) { + + public DroolsBurster(KieSession ks, String clockType, int burst) + { this.ks = ks; - if (clockType == "pseudo") + if(clockType == "pseudo") clock = ks.getSessionClock(); else clock = null; currentTime = 0; - currentTime = System.currentTimeMillis(); - clock.advanceTime(currentTime, TimeUnit.MILLISECONDS); count = 0; this.burst = burst; } - - // 将事件插入KieSession,并根据时间戳(ms)推进时钟,在一定时间间隔触发规则 + + //将事件插入KieSession,并根据时间戳(ms)推进时钟,在一定时间间隔触发规则 public int insert(Object evt, long timestamp) { + if(currentTime == 0) + { + currentTime = timestamp; + clock.advanceTime(timestamp, TimeUnit.MILLISECONDS); + } + ks.insert(evt); - if (count >= burst || timestamp - currentTime > 1000) { - if (clock != null) { - clock.advanceTime(timestamp - currentTime, TimeUnit.MILLISECONDS); + if(count >= burst || timestamp-currentTime>1000) { + if(clock != null) { + clock.advanceTime(timestamp-currentTime, TimeUnit.MILLISECONDS); currentTime = timestamp; } - + count = 0; - int num = ks.fireAllRules(); - return num; + return ks.fireAllRules(); } + count++; return 0; } - - public void dispose() { - if (ks != null) - ks.dispose(); + + public KieSession getKieSession() { + return ks; } - } diff --git a/src/main/java/vip/xumy/drools/action/CdrGenerator.java b/src/main/java/vip/xumy/drools/service/CdrGenerator.java similarity index 95% rename from src/main/java/vip/xumy/drools/action/CdrGenerator.java rename to src/main/java/vip/xumy/drools/service/CdrGenerator.java index c48c1d8..a4edf88 100644 --- a/src/main/java/vip/xumy/drools/action/CdrGenerator.java +++ b/src/main/java/vip/xumy/drools/service/CdrGenerator.java @@ -1,4 +1,4 @@ -package vip.xumy.drools.action; +package vip.xumy.drools.service; import java.text.MessageFormat; import java.util.ArrayList; @@ -7,8 +7,10 @@ import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; +import org.drools.core.base.RuleNameEqualsAgendaFilter; import org.drools.core.time.SessionPseudoClock; import org.kie.api.runtime.KieSession; +import org.kie.api.runtime.rule.AgendaFilter; import lombok.extern.log4j.Log4j2; import vip.xumy.core.utils.DateUtil; @@ -86,13 +88,16 @@ public class CdrGenerator { private int sum; private int loop; private boolean running = false; + private AgendaFilter agendaFilter; + - public CdrGenerator(KieSession ks, int maxNum, int maxTime, int loop) { + public CdrGenerator(KieSession ks, int maxNum, int maxTime, int loop, String name) { this.ks = ks; this.clock = ks.getSessionClock(); this.maxNum = maxNum; this.maxTime = maxTime; this.loop = loop; + this.agendaFilter = new RuleNameEqualsAgendaFilter(name); } public void start() { @@ -133,12 +138,12 @@ public class CdrGenerator { clock.advanceTime(timestamp - currentTime, TimeUnit.MILLISECONDS); currentTime = timestamp; count = 0; - sum += ks.fireAllRules(); + sum += ks.fireAllRules(agendaFilter); } count++; } } - sum += ks.fireAllRules(); + sum += ks.fireAllRules(agendaFilter); ks.dispose(); running = false; long finish = System.currentTimeMillis(); diff --git a/src/main/java/vip/xumy/drools/service/CdrRuleService.java b/src/main/java/vip/xumy/drools/service/CdrRuleService.java index 39efd1f..fec1668 100644 --- a/src/main/java/vip/xumy/drools/service/CdrRuleService.java +++ b/src/main/java/vip/xumy/drools/service/CdrRuleService.java @@ -6,7 +6,7 @@ import org.kie.api.runtime.KieSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import vip.xumy.drools.action.CdrGenerator; +import vip.xumy.drools.conf.DroolsConfig; /** * Ownership belongs to the company @@ -18,11 +18,16 @@ import vip.xumy.drools.action.CdrGenerator; @Service public class CdrRuleService { @Autowired - private DroolsApiService droolsApiService; + private DroolsConfig config; - public void test(Integer loop) throws IOException { - KieSession ks = droolsApiService.createSession(true); - new CdrGenerator(ks, 500, 10000, loop).start(); + public void test(String name, Integer loop) throws IOException { + KieSession ks = config.kieSession(); + CdrGenerator cdrGenerator = new CdrGenerator(ks, 500, 10000, loop, name); + cdrGenerator.start(); + } + + public void relaodRules() throws IOException { + config.reloadRules(); } } diff --git a/src/main/java/vip/xumy/drools/service/DroolsApiService.java b/src/main/java/vip/xumy/drools/service/DroolsApiService.java deleted file mode 100644 index fcaa73f..0000000 --- a/src/main/java/vip/xumy/drools/service/DroolsApiService.java +++ /dev/null @@ -1,39 +0,0 @@ -package vip.xumy.drools.service; - -import java.io.IOException; - -import org.kie.api.KieServices; -import org.kie.api.runtime.KieContainer; -import org.kie.api.runtime.KieSession; -import org.kie.api.runtime.KieSessionConfiguration; -import org.kie.api.runtime.conf.ClockTypeOption; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import vip.xumy.drools.conf.DroolsConfig; - -/** - * Ownership belongs to the company - * - * @author:mengyxu - * @date:2023年9月20日 - */ - -@Service -public class DroolsApiService { - private static final KieSessionConfiguration sessConf; - static { - sessConf = KieServices.Factory.get().newKieSessionConfiguration(); - sessConf.setOption(ClockTypeOption.get("pseudo")); - } - @Autowired - private KieContainer kieContainer; - private DroolsConfig config = new DroolsConfig(); - - public KieSession createSession(boolean reBuild) throws IOException { - if(reBuild) - config.build(); - return kieContainer.newKieSession(sessConf); - } - -} diff --git a/src/main/resources/rules/hello.drl b/src/main/resources/hello.drl similarity index 97% rename from src/main/resources/rules/hello.drl rename to src/main/resources/hello.drl index 3bc277d..ad7065e 100644 --- a/src/main/resources/rules/hello.drl +++ b/src/main/resources/hello.drl @@ -1,4 +1,4 @@ -package rules +package rules.hello import vip.xumy.drools.pojo.CDR import vip.xumy.drools.pojo.RuleSink @@ -58,6 +58,7 @@ rule "test005" //System.out.println("match rule " + drools.getRule().getName() + "\nevent: " + $a + "\nevent: " + $b); end +*/ rule "test006" //no-loop true //lock-on-active true @@ -66,7 +67,7 @@ rule "test006" $b : CDR(msgType==3) //$al : ArrayList(size>1) from collect(CDR(imsi==$b.imsi, this before[1ms, 10s] $b)) //ArrayList(size>0) from collect(CDR(msgType==45, this before[1ms, 20s] $b)) - exists CDR(msgType==45, imsi==$b.imsi, this before[1ms, 10s] $b) + //exists CDR(msgType==45, imsi==$b.imsi, this before[1ms, 10s] $b) then //System.out.println("match rule " + drools.getRule().getName() + "\nevent: " + $a + "\nevent: " + $b); //System.out.println("match rule " + drools.getRule().getName() + " count = " + $al.size() + " event: " + $b); @@ -74,7 +75,6 @@ rule "test006" // System.out.println($al.get(i)); end -*/ //在10s内,出现不同国家发起的两次位置更新并在此之后有短信行为 rule "test007" diff --git a/src/main/resources/rules/test007.drl b/src/main/resources/rules/test007.drl new file mode 100644 index 0000000..283e3d5 --- /dev/null +++ b/src/main/resources/rules/test007.drl @@ -0,0 +1,33 @@ +package rules.hello +import vip.xumy.drools.pojo.CDR +import vip.xumy.drools.pojo.RuleSink + +import java.util.ArrayList; +import java.util.LinkedList; + + +declare CDR + @role(event) + @timestamp(createTime) + @expires(15s) + //@duration(duration) +end + +//在10s内,出现不同国家发起的两次位置更新并在此之后有短信行为 +rule "test007" + no-loop true + lock-on-active true + when + $b : CDR(msgType==44||msgType==45||msgType==46) + //accumulate(CDR(msgType==2, imsi==$b.imsi, this before[0ms, 10s] $b, $this:this, $cn:callerCN), $cnt:count($cn), $al:collectList($this)) + accumulate(CDR(msgType==2, imsi==$b.imsi, this before[1ms, 15s] $b, $this:this, $cn:callerCN, $id:id), $cnt:count($cn), $al:collectList($this), $ids:collectList($id)) + eval($cnt > 1) + then + //System.out.println("match rule " + drools.getRule().getName() + " count = " + $al.size() + " event: " + $b); + //for(int i=0; i<$al.size(); i++) + // System.out.println($al.get(i)); + //sink.sink(drools.getRule().getName(), "has many updatelocation from other CN before sm in 20s", $ids); + + //RuleSink ri = new RuleSink($b.getId(), drools.getRule().getName(), "has many updatelocation from other CN before sm in 10s", $ids); + //sink.add(ri); +end