xxl-job-rest

This commit is contained in:
王永亮
2023-03-08 14:29:26 +08:00
parent a6f0b9ece9
commit 760582618f
43 changed files with 1021 additions and 93 deletions
@@ -0,0 +1,16 @@
package com.wyl.delayqueue.system;
import java.util.ArrayList;
import java.util.List;
public class HeapOOM {
static class OOMObject {
}
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<OOMObject>();
while (true) {
list.add(new OOMObject());
}
}
}
@@ -0,0 +1,27 @@
package com.wyl.delayqueue.system;
public class SynchronizedObjectLock implements Runnable {
static SynchronizedObjectLock instance = new SynchronizedObjectLock();
@Override
public void run() {
// 同步代码块形式——锁为this,两个线程使用的锁是一样的,线程1必须要等到线程0释放了该锁后,才能执行
synchronized (this) {
System.out.println("我是线程" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "结束");
}
}
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
}
}
@@ -4,10 +4,14 @@ import com.wyl.delayqueue.system.entity.DelayMessage;
import com.wyl.delayqueue.system.entity.Message;
import org.junit.jupiter.api.Test;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.concurrent.DelayQueue;
public class SystemDayTest {
ThreadLocal<String> tmp = new ThreadLocal<>();
ThreadLocal<String> tmp1 = new ThreadLocal<>();
@Test
public void test() throws InterruptedException {
@@ -23,15 +27,15 @@ public class SystemDayTest {
DelayMessage<Message> messageDelayMessage = new DelayMessage<>();
messageDelayMessage.setData(message);
messageDelayMessage.setDelayTime(LocalDateTime.now()
.plusSeconds(10));
.plusSeconds(10));
DelayMessage<Message> messageDelayMessage1 = new DelayMessage<>();
messageDelayMessage1.setData(message1);
messageDelayMessage1.setDelayTime(LocalDateTime.now()
.plusSeconds(20));
.plusSeconds(20));
DelayMessage<Message> messageDelayMessage2 = new DelayMessage<>();
messageDelayMessage2.setData(message2);
messageDelayMessage2.setDelayTime(LocalDateTime.now()
.plusSeconds(30));
.plusSeconds(30));
DelayQueue<DelayMessage<Message>> delayQueue = new DelayQueue<>();
delayQueue.add(messageDelayMessage);
delayQueue.add(messageDelayMessage1);
@@ -40,10 +44,27 @@ public class SystemDayTest {
while (true) {
DelayMessage<Message> take = delayQueue.take();
System.out.println(take);
if (delayQueue.size()==0){
if (delayQueue.size() == 0) {
break;
}
}
}
@Test
public void test01() {
LocalDateTime today_end = LocalDateTime.of(LocalDate.now().minusDays(1), LocalTime.MAX).minusNanos(999999999L);
LocalDateTime today_start = LocalDateTime.of(LocalDate.now().minusDays(1), LocalTime.MIN);
System.out.println(today_end);
System.out.println(today_start);
}
@Test
public void test02() {
new Thread(() -> {
tmp.set("123");
tmp1.set("wyl");
String s = tmp.get();
}).start();
}
}
@@ -2,12 +2,18 @@ package com.wyl.chain.handler;
import com.wyl.chain.Handler;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.RejectedExecutionException;
/**
* 第二处理器
* @ClassName: SecondHandler
* @Date: 2022/4/24 10:03 下午
*
* @author wangyl
* @version V1.0
* @ClassName: SecondHandler
* @Date: 2022/4/24 10:03 下午
*/
public class SecondHandler implements Handler {
@Override
@@ -23,5 +29,72 @@ public class SecondHandler implements Handler {
System.out.println("无需第二处理");
return false;
}
public static void main(String[] args) {
List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
list.add("7");
list.add("8");
list.add("9");
list.add("10");
list.add("11");
list.add("12");
CountDownLatch countDownLatch = new CountDownLatch(test(list.size()));
int a = 0;
for (int i = 0; i < list.size(); i++) {
for (int j = i; j < list.size(); j++) {
try {
int finalI = i;
int finalJ = j;
ZimeitiPool.getPool().execute(new Runnable() {
@Override
public void run() {
//业务代码
System.out.println("i " + list.get(finalI) + "j " + list.get(finalJ));
System.out.println("j " + list.get(finalJ) + "i " + list.get(finalI));
countDownLatch.countDown();
}
});
} catch (final RejectedExecutionException e) {
try {
i = i - 1;
System.out.println("线程队列满了,sleep 5s . current queue size:"
+ ZimeitiPool.getPool().getQueue().size() + ",active:"
+ ZimeitiPool.getPool().getActiveCount());
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
countDownLatch.countDown();
}
} catch (Exception e) {
e.printStackTrace();
countDownLatch.countDown();
}
a++;
}
}
try {
countDownLatch.await();
System.out.println(a);
System.out.println(111);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static int test(Integer size) {
int a = 0;
for (int i = 1; i < size + 1; i++) {
a = a + i;
}
System.out.println(a);
return a;
}
}
@@ -0,0 +1,48 @@
package com.wyl.chain.handler;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @description: 多线程
* @author: zhao.wang
* @date: 15:28
* @param:
* @param: null
* @return:
* @return: null
**/
public class ZimeitiPool {
private static ThreadPoolExecutor pool = null; //线程池
private static BlockingQueue<Runnable> workQueue = null; //阻塞队列
private static int corePoolSize = 25; //核心线程数
private static int maxinumPoolSize = 400;//最大线程数
private static long keepAliveTime = 10 * 1000L;//生存时间
private final static AtomicInteger threadsNumber = new AtomicInteger(1);
private static int workQueueSize = 50000; //阻塞队列容量
public static ThreadPoolExecutor getPool() {
if (pool == null) {
workQueue = new LinkedBlockingQueue<>(workQueueSize);
pool = new ThreadPoolExecutor(corePoolSize, maxinumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS,
workQueue);
pool.setThreadFactory(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "zimeiti-pool-" + threadsNumber.getAndIncrement());
return t;
}
});
}
return pool;
}
}
@@ -0,0 +1,24 @@
package concurrent;
import java.util.HashMap;
class Solution {
public static int lengthOfLongestSubstring(String s) {
if (s.length() == 0) return 0;
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int max = 0;
int left = 0;
for (int i = 0; i < s.length(); i++) {
if (map.containsKey(s.charAt(i))) {
left = Math.max(left, map.get(s.charAt(i)) + 1);
}
map.put(s.charAt(i), i);
max = Math.max(max, i - left + 1);
}
return max;
}
public static void main(String[] args) {
int i = lengthOfLongestSubstring("123");
}
}
@@ -1,29 +1,29 @@
package concurrent.ttl.context;
import com.alibaba.ttl.TransmittableThreadLocal;
/**
* @author: wangyl
* @date: 2022/8/7
* @description: 上线文存储
*/
public class ContextUtil {
static TransmittableThreadLocal<String> transmittableThreadLocal = new TransmittableThreadLocal<>();
static ThreadLocal<String> threadLocal = new ThreadLocal<>();
public static String getTransmittableThreadLocal() {
return transmittableThreadLocal.get();
}
public static void setTransmittableThreadLocal(String value) {
transmittableThreadLocal.set(value);
}
public static String getThreadLocal() {
return threadLocal.get();
}
public static void setThreadLocal(String value) {
threadLocal.set(value);
}
}
//package concurrent.ttl.context;
//
//import com.alibaba.ttl.TransmittableThreadLocal;
//
///**
// * @author: wangyl
// * @date: 2022/8/7
// * @description: 上线文存储
// */
//public class ContextUtil {
// static TransmittableThreadLocal<String> transmittableThreadLocal = new TransmittableThreadLocal<>();
// static ThreadLocal<String> threadLocal = new ThreadLocal<>();
//
// public static String getTransmittableThreadLocal() {
// return transmittableThreadLocal.get();
// }
//
// public static void setTransmittableThreadLocal(String value) {
// transmittableThreadLocal.set(value);
// }
//
// public static String getThreadLocal() {
// return threadLocal.get();
// }
//
// public static void setThreadLocal(String value) {
// threadLocal.set(value);
// }
//}
@@ -1,6 +1,5 @@
package concurrent.ttl.task;
import concurrent.ttl.context.ContextUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.Callable;
@@ -16,8 +15,6 @@ public class CallableTask implements Callable<String> {
*/
@Override
public String call() throws Exception {
log.info("ThreadLocal 的值为{}", ContextUtil.getThreadLocal());
log.info("TransmittableThreadLocal 的值为{}", ContextUtil.getTransmittableThreadLocal());
return "null";
}
}
@@ -1,6 +1,5 @@
package concurrent.ttl.task;
import concurrent.ttl.context.ContextUtil;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@@ -19,8 +18,6 @@ public class RunnableTask implements Runnable {
*/
@Override
public void run() {
log.info("ThreadLocal 的值为{}", ContextUtil.getThreadLocal());
log.info("TransmittableThreadLocal 的值为{}", ContextUtil.getTransmittableThreadLocal());
}
}
@@ -0,0 +1,32 @@
package concurrent.Synchronized;
import org.junit.jupiter.api.Test;
import java.util.concurrent.Callable;
public class SynchronizedObjectLock implements Runnable {
static SynchronizedObjectLock instance = new SynchronizedObjectLock();
@Override
public void run() {
// 同步代码块形式——锁为this,两个线程使用的锁是一样的,线程1必须要等到线程0释放了该锁后,才能执行
synchronized (this) {
System.out.println("我是线程" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "结束");
}
}
@Test
public void synchronizedObjectTest() {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
}
}
@@ -0,0 +1,33 @@
package com.wyl.file.sequence;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
class Solution {
public static int lengthOfLongestSubstring(String s) {
if (s.length() < 0) {
return 0;
}
Map<Character, Integer> map = new HashMap<>();
int start = 0;
int max = 0;
for (int i = 0; i < s.length(); i++) {
int c = s.charAt(i);
Integer integer = map.get(c);
if (Objects.isNull(integer)) {
} else {
start = Math.max(start, integer + 1);
}
max = Math.max(max, i - start + 1);
// map.put(c, i);
}
return max;
}
public static void main(String[] args) {
int i = lengthOfLongestSubstring("tmmzuxt");
System.out.println(i);
}
}
@@ -49,9 +49,22 @@ public class RedissonTest {
@Test
public void RedisLockTest() throws InterruptedException {
for (int i = 0; i < 100; i++){
for (int i = 0; i < 100; i++) {
new RedisLock().start();
}
Thread.sleep(1000000);
}
@Test
public void test() throws InterruptedException {
System.out.println("Progress:");
for (int i = 1; i <= 100; i++) {
System.out.print(i + "%");
// Thread.sleep(100);
for (int j = 0; j < String.valueOf(i).length(); j++) {
System.out.print("\b");
}
}
System.out.println();
}
}
+10
View File
@@ -21,6 +21,16 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-web</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
@@ -0,0 +1,37 @@
package com.wyl.spring.boot.common.filter;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
@Service("Filter1")
public class Filter1 implements SalarySalaryFiler {
/**
* 这些都可以进行数据库配置
*/
public static final BigDecimal start = new BigDecimal("200");
/**
* 这些都可以进行数据库配置
*/
public static final BigDecimal end = new BigDecimal("400");
/**
* 这些都可以进行数据库配置
*/
@Override
public Integer getShort() {
return 1;
}
@Override
public void doFilter(String param, MyFilterChain filterChain, Integer index) {
System.out.println("Filter1");
if (param.equals("1")) {
System.out.println("请输入支付密码");
return;
}
filterChain.doFilter(param, filterChain, index);
}
}
@@ -0,0 +1,24 @@
package com.wyl.spring.boot.common.filter;
import org.springframework.stereotype.Service;
@Service("Filter2")
public class Filter2 implements SalarySalaryFiler {
@Override
public Integer getShort() {
return 2;
}
@Override
public void doFilter(String param, MyFilterChain filterChain, Integer index) {
System.out.println("Filter2");
if (param.equals("2")) {
System.out.println("请发生短信验证码");
return;
}
filterChain.doFilter(param, filterChain, index);
}
}
@@ -0,0 +1,24 @@
package com.wyl.spring.boot.common.filter;
import org.springframework.stereotype.Service;
@Service("Filter3")
public class Filter3 implements SalarySalaryFiler {
@Override
public Integer getShort() {
return 3;
}
@Override
public void doFilter(String param, MyFilterChain filterChain, Integer index) {
System.out.println("Filter3");
if (param.equals("3")) {
System.out.println("扫脸");
return;
}
filterChain.doFilter(param, filterChain, index);
}
}
@@ -0,0 +1,43 @@
package com.wyl.spring.boot.common.filter;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service("MyFilterChain")
public class MyFilterChain implements SalarySalaryFiler, ApplicationContextAware {
private static List<SalarySalaryFiler> prepareFilterList;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
Map<String, SalarySalaryFiler> serviceMap = applicationContext.getBeansOfType(SalarySalaryFiler.class);
prepareFilterList = new ArrayList<>(serviceMap.values());
prepareFilterList = prepareFilterList.stream()
.sorted(Comparator.comparing(SalarySalaryFiler::getShort))
.collect(Collectors.toList());
}
@Override
public Integer getShort() {
return 0;
}
@Override
public void doFilter(String param, MyFilterChain filterChain, Integer index) {
index = index + 1;
if (index < prepareFilterList.size()) {
prepareFilterList.get(index).doFilter(param, filterChain, index);
} else {
System.out.println("直接支付");
}
}
}
@@ -0,0 +1,8 @@
package com.wyl.spring.boot.common.filter;
public interface SalarySalaryFiler {
Integer getShort();
void doFilter(String param, MyFilterChain filterChain, Integer index);
}
@@ -7,8 +7,10 @@ import java.util.List;
public interface LogTestService {
void test();
void testSPEL(Order order);
void testSPEL(Boolean order);
void testSPELList(List<Order> orders);
String testSPELResult(List<Order> orders);
}
@@ -1,24 +1,27 @@
package com.wyl.spring.boot.common.service.impl;
import com.wyl.spring.boot.common.aop.annotation.LogTest;
import com.wyl.spring.boot.common.service.LogTestService;
import com.wyl.spring.boot.common.spel.annotation.SpelTest;
import com.wyl.spring.boot.common.spel.bean.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class LogTestServiceImpl implements LogTestService {
@Override
// @LogTest
@Transactional
public void test() {
System.out.println("testLog");
}
@SpelTest(spel = "{#order.id}")
public void testSPEL(Order order) {
@SpelTest(spel = "123{#order?'真':'假'}")
public void testSPEL(Boolean order) {
System.out.println(123);
}
@@ -27,4 +30,11 @@ public class LogTestServiceImpl implements LogTestService {
public void testSPELList(List<Order> orders) {
System.out.println();
}
@Override
@SpelTest(spel = "{#abc}")
public String testSPELResult(List<Order> orders) {
String abc = "123";
return abc;
}
}
@@ -1 +1,3 @@
auth.should.skip.url[0] =1
auth.should.skip.url[1] =2
auth.should.skip.url[2] =3
@@ -34,7 +34,7 @@ class SpringBootCommonApplicationTests {
Order order = new Order();
order.setId(123);
order.setName("wyl");
logTestService.testSPEL(order);
logTestService.testSPEL(false);
}
@Test
@@ -53,4 +53,20 @@ class SpringBootCommonApplicationTests {
}
@Test
void SpelResultTest() {
Order order1 = new Order();
order1.setId(1);
order1.setName("wyl1");
Order order2 = new Order();
order2.setId(2);
order2.setName("wyl2");
Order order3 = new Order();
order3.setId(3);
order3.setName("wyl3");
List<Order> orders = Arrays.asList(order1, order2, order3);
logTestService.testSPELResult(orders);
}
}
+38 -3
View File
@@ -11,12 +11,47 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-boot-drools</artifactId>
<name>spring-boot-drools</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<drools.version>7.47.0.Final</drools.version>
</properties>
<dependencyManagement>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>7.47.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>7.47.0.Final</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>7.47.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,12 @@
package com.wyl.spring.drools;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootCommonApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootCommonApplication.class, args);
}
}
@@ -0,0 +1,72 @@
package com.wyl.spring.drools.config;
import lombok.Data;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.*;
import org.kie.api.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
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;
/**
* 配置Drools的服务类,方便在Rest接口中调用。 该类负责加载具体的drl规则文件, 不再需要kmodule.xml配置文件了。
*/
@Configuration
@Data
public class DroolsAutoConfiguration {
public static final String RULES_PATH = "rules/com/ai/prd/";
public static final String RULE_BASE_PATH = "src/main/resources/";
@Bean
@ConditionalOnMissingBean(KieFileSystem.class)
public KieFileSystem kieFileSystem(KieServices kieServices) throws IOException {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
for (Resource file : getRuleFiles()) {
kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_PATH + file.getFilename(), "UTF-8"));
}
return kieFileSystem;
}
private Resource[] getRuleFiles() throws IOException {
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
return resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "**/*.*");
}
@Bean
@ConditionalOnMissingBean(KieContainer.class)
public KieContainer kieContainer(KieServices kieServices) throws IOException {
final KieRepository kieRepository = kieServices.getRepository();
kieRepository.addKieModule(new KieModule() {
@Override
public ReleaseId getReleaseId() {
return kieRepository.getDefaultReleaseId();
}
});
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem(kieServices));
kieBuilder.buildAll();
return kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
}
@Bean
public KieServices kieServices() {
return KieServices.Factory.get();
}
@Bean
@ConditionalOnMissingBean(KieBase.class)
public KieBase kieBase(KieServices kieServices) throws IOException {
return kieContainer(kieServices).getKieBase();
}
}
@@ -0,0 +1,24 @@
package com.wyl.spring.drools.controller;
import com.wyl.spring.drools.entity.Person;
import com.wyl.spring.drools.generator.RuleExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("rule/person")
public class PersonRuleController {
@Autowired
private RuleExecutor ruleExecutor;
@PostMapping("one")
public void fireAllRules4One(@RequestBody Person person) {
ruleExecutor.execute(person);
}
}
@@ -0,0 +1,28 @@
package com.wyl.spring.drools.controller;
import com.wyl.spring.drools.entity.RuleDTO;
import com.wyl.spring.drools.generator.RuleGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("rule")
public class RuleContreller {
@Autowired
RuleGenerator ruleGenerator;
@PostMapping("add")
public void add(@RequestBody RuleDTO ruleDTO) {
ruleGenerator.generateRules(List.of(ruleDTO));
}
@PostMapping("del")
public void del() {
ruleGenerator.removeRules();
}
}
@@ -0,0 +1,19 @@
package com.wyl.spring.drools.entity;
import lombok.Data;
@Data
public class Person {
/**
* 用户名称
*/
private String name;
/**
* 会员等级
*/
private int level;
/**
* 消费金额
*/
private long amount;
}
@@ -0,0 +1,28 @@
package com.wyl.spring.drools.entity;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
public class RuleDTO {
String ruleName;
Integer level;
Integer minAmount;
Integer maxAmount;
Integer score;
String ruleText;
public Map<String, Object> toMap() {
Map<String, Object> ruleMap = new HashMap<>();
ruleMap.put("ruleName", ruleName);
ruleMap.put("level", level);
ruleMap.put("minAmount", minAmount);
ruleMap.put("maxAmount", maxAmount);
ruleMap.put("score", score);
return ruleMap;
}
}
@@ -0,0 +1,29 @@
package com.wyl.spring.drools.generator;
import com.wyl.spring.drools.entity.Person;
import lombok.extern.slf4j.Slf4j;
import org.kie.api.KieServices;
import org.kie.api.builder.KieRepository;
import org.kie.api.builder.ReleaseId;
import org.kie.api.runtime.StatelessKieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 规则执行器
*/
@Slf4j
@Component
public class RuleExecutor {
@Autowired
private KieServices kieServices;
public void execute(Person person) {
KieRepository repository = kieServices.getRepository();
ReleaseId defaultReleaseId = repository.getDefaultReleaseId();
StatelessKieSession statelessKieSession = kieServices.newKieContainer(defaultReleaseId).getKieBase().newStatelessKieSession();
statelessKieSession.execute(person);
return;
}
}
@@ -0,0 +1,121 @@
package com.wyl.spring.drools.generator;
import com.wyl.spring.drools.config.DroolsAutoConfiguration;
import com.wyl.spring.drools.entity.RuleDTO;
import lombok.extern.slf4j.Slf4j;
import org.drools.compiler.kie.builder.impl.InternalKieModule;
import org.drools.compiler.kie.builder.impl.KieContainerImpl;
import org.drools.template.ObjectDataCompiler;
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.builder.Results;
import org.kie.api.runtime.KieContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @author: wangyl
* @date: 2023/1/31
* @description: 规则生成
*/
@Slf4j
@Component
public class RuleGenerator {
@Autowired
KieServices kieServices;
@Autowired
KieContainer kieContainer;
@Autowired
KieFileSystem kieFileSystem;
/**
* 根据传递进来的参数对象生规则
*
* @param ruleDTOs
*/
public void generateRules(List<RuleDTO> ruleDTOs) {
ruleDTOs.forEach(o -> {
String s = applyRuleTemplate(o);
o.setRuleText(s);
log.info("规则引擎加载规则,id={}", o.getRuleName());
});
//规则的加载
createOrRefreshDrlInMemory(ruleDTOs);
}
/**
* @author: wangyl
* @date: 2023/2/1
* @description:
*/
public void removeRules() {
KieBase kieBase = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId()).getKieBase();
kieBase.removeRule("rules.com.ai.prd", "wyl01");
String file = DroolsAutoConfiguration.RULE_BASE_PATH + DroolsAutoConfiguration.RULES_PATH + "wyl01.drl";
kieFileSystem.delete(file);
buildKieContainer();
}
/**
* 通过模板生成规则字符串
*
* @param ruleDTO
* @return java.lang.String
* @Date 2023/1/31
* @Author wangyl
*/
private String applyRuleTemplate(RuleDTO ruleDTO) {
Map<String, Object> data = ruleDTO.toMap();
ObjectDataCompiler objectDataCompiler = new ObjectDataCompiler();
return objectDataCompiler.compile(Arrays.asList(data), Thread.currentThread().getContextClassLoader().getResourceAsStream("template/template.drt"));
}
/**
* 根据String格式的Drl生成Maven结构的规则
*
* @param rules
*/
private void createOrRefreshDrlInMemory(List<RuleDTO> rules) {
for (RuleDTO str : rules) {
kieFileSystem.write(DroolsAutoConfiguration.RULE_BASE_PATH + DroolsAutoConfiguration.RULES_PATH + str.getRuleName() + ".drl", str.getRuleText());
log.info("生成规则内容:\n{}", str.getRuleText());
}
KieBuilder kb = kieServices.newKieBuilder(kieFileSystem).buildAll();
if (kb.getResults().hasMessages(Message.Level.ERROR)) {
log.error("create rule in kieFileSystem Error", kb.getResults());
throw new IllegalArgumentException("生成规则文件失败");
}
}
private void buildKieContainer() {
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
// 通过KieBuilder构建KieModule下所有的KieBase
kieBuilder.buildAll();
// 获取构建过程中的结果
Results results = kieBuilder.getResults();
// 获取错误信息
List<Message> messages = results.getMessages(Message.Level.ERROR);
if (null != messages && !messages.isEmpty()) {
for (Message message : messages) {
log.error(message.getText());
}
throw new RuntimeException("加载规则出现异常");
}
// KieContainer只有第一次时才需要创建,之后就是使用这个
if (null == kieContainer) {
kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
} else {
// 实现动态更新
((KieContainerImpl) kieContainer).updateToKieModule((InternalKieModule) kieBuilder.getKieModule());
}
}
}
@@ -0,0 +1,17 @@
package com.wyl.spring.drools.service;
import com.wyl.spring.drools.entity.Person;
import org.drools.core.definitions.rule.impl.RuleImpl;
/**
* 触发Person相关的规则后的处理类
*
* @author yuwen
*/
public class PersonRuleAction {
public static void doParse(Person person, RuleImpl rule, Integer score) {
System.out.println(rule.getName());
System.out.println("用户:" + person.getName() + "积分增加" + score);
}
}
@@ -0,0 +1,14 @@
package rules.com.ai.prd
import com.wyl.spring.drools.entity.Person
import com.wyl.spring.drools.service.PersonRuleAction
// 根据名字匹配指定的人
rule "1"
when
$p : Person( level==1 && amount >= 100 && amount < 1000)
then
PersonRuleAction.doParse($p, drools.getRule(),1);
System.out.println("Rule name is [" + drools.getRule().getName() + "]");
System.out.println("Rule package is [" + drools.getRule().getPackageName() + "]");
end
@@ -0,0 +1,25 @@
template header
ruleName
level
minAmount
maxAmount
score
package rules.com.ai.prd
import com.wyl.spring.drools.entity.Person
import com.wyl.spring.drools.service.PersonRuleAction
template "judge condition"
rule "@{ruleName}"
when
$p : Person( level==@{level} && amount >= @{minAmount} && amount < @{maxAmount})
then
PersonRuleAction.doParse($p, drools.getRule(),@{score});
System.out.println("Rule name is [" + drools.getRule().getName() + "]");
System.out.println("Rule package is [" + drools.getRule().getPackageName() + "]");
end
end template
@@ -1,5 +0,0 @@
package com.wyl.example.service;
public interface Service {
void test();
}
@@ -1,8 +0,0 @@
package com.wyl.example.service;
public class ServiceTest implements Service{
@Override
public void test() {
}
}
@@ -0,0 +1,44 @@
package com.wyl.spring.drools;
import com.wyl.spring.drools.controller.PersonRuleController;
import com.wyl.spring.drools.controller.RuleContreller;
import com.wyl.spring.drools.entity.Person;
import com.wyl.spring.drools.entity.RuleDTO;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@SpringBootTest
public class PersonRuleControllerTest {
@Autowired
PersonRuleController controller;
@Autowired
RuleContreller ruleContreller;
@Test
public void testadd() {
List<RuleDTO> ruleDTOS = new ArrayList<>();
RuleDTO ruleDTO = new RuleDTO();
ruleDTO.setRuleName("123");
ruleDTO.setLevel(2);
ruleDTO.setMinAmount(1000);
ruleDTO.setMaxAmount(2000);
ruleDTO.setScore(2);
RuleDTO ruleDTO1 = new RuleDTO();
ruleDTO1.setRuleName("456");
ruleDTO1.setLevel(4);
ruleDTO1.setMinAmount(2000);
ruleDTO1.setMaxAmount(3000);
ruleDTO1.setScore(3);
ruleDTOS.add(ruleDTO);
ruleDTOS.add(ruleDTO1);
// ruleContreller.add(ruleDTOS);
}
}
+2 -2
View File
@@ -22,8 +22,8 @@
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
@@ -4,10 +4,10 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class IBSApplication {
public class RabbitmqApplication {
public static void main(String[] args) {
SpringApplication.run(IBSApplication.class, args);
SpringApplication.run(RabbitmqApplication.class, args);
}
}
@@ -1,10 +1,5 @@
package com.wyl.spring.rabbitmq.conf;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@@ -12,24 +7,24 @@ public class RabbitMQConfig {
//配置direct交换机
@Bean
public DirectExchange directExchange() {
return new DirectExchange("exchange.topic.shop.goodscenter.change");
}
// @Bean
// public DirectExchange directExchange() {
// return new DirectExchange("exchange.topic.shop.goodscenter.change");
// }
//配置direct队列
@Bean
public Queue directQueue() {
return new Queue("wyl.test");
}
//将direct队列绑定到交换机上
@Bean
public Binding directBinding(Queue directQueue, DirectExchange directExchange) {
// 参数 1 为需要绑定的队列
// 参数 2 为需要绑定的交换机
// 参数 3绑定时的RoutingKey
return BindingBuilder.bind(directQueue).to(directExchange).with("route.goodscenter.goods_basic_change");
}
// //配置direct队列
// @Bean
// public Queue directQueue() {
// return new Queue("wyl.test");
// }
//
// //将direct队列绑定到交换机上
// @Bean
// public Binding directBinding(Queue directQueue, DirectExchange directExchange) {
// // 参数 1 为需要绑定的队列
// // 参数 2 为需要绑定的交换机
// // 参数 3绑定时的RoutingKey
// return BindingBuilder.bind(directQueue).to(directExchange).with("route.goodscenter.goods_basic_change");
// }
}
@@ -5,4 +5,4 @@ spring.rabbitmq.port=5672
spring.rabbitmq.listener.simple.acknowledge-mode=MANUAL
spring.rabbitmq.listener.direct.acknowledge-mode=MANUAL
spring.rabbitmq.publisher-confirm-type=CORRELATED
spring.rabbitmq.publisher-returns=true
spring.rabbitmq.publisher-returns=true
@@ -0,0 +1,21 @@
//package com.wyl.spring.rabbitmq;
//
//import org.apache.ibatis.annotations.Mapper;
//import org.junit.runner.RunWith;
//import org.mybatis.spring.annotation.MapperScan;
//import org.springframework.boot.test.context.SpringBootTest;
//import org.springframework.cloud.openfeign.EnableFeignClients;
//import org.springframework.context.annotation.ComponentScan;
//import org.springframework.test.context.junit4.SpringRunner;
//
//@RunWith(SpringRunner.class)
//@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseTest.Application.class)
//public class BaseTest {
//
// @MapperScan(value = "com.asura.ibs.mapper", annotationClass = Mapper.class, lazyInitialization = "true")
// @ComponentScan(value = "com.asura.ibs")
// @EnableFeignClients(basePackages = "com.asura.ibs.api")
// public static class Application {
//
// }
//}
@@ -1,7 +1,7 @@
package com.wyl.spring.rabbitmq;
import com.wyl.spring.rabbitmq.send.SendServiceImpl;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;