From c6c56d024dfa5c5657d2ef84a76bfe1c6dd951e7 Mon Sep 17 00:00:00 2001 From: icanci Date: Mon, 12 Dec 2022 12:48:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E4=B8=8E=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/admin-biz/pom.xml | 12 + .../cn/icanci/ddk/admin/biz/package-info.java | 5 + .../ddk/admin/biz/service/EnvService.java | 14 + .../admin/biz/service/IDGeneratorService.java | 22 + .../biz/service/impl/EnvServiceImpl.java | 30 ++ .../service/impl/IDGeneratorServiceImpl.java | 38 ++ .../icanci/ddk/admin/biz/utils/EnvUtils.java | 33 ++ .../icanci/ddk/admin/biz/utils/IDHolder.java | 40 ++ admin/admin-dal/pom.xml | 40 ++ .../ddk/admin/dal/mapper/DdkGroupMapper.java | 12 + .../mybatis/mapper/DdkGroupMapper.xml | 6 + admin/admin-views/pom.xml | 132 ++++++ .../ddk/admin/views/AdminViewApplication.java | 19 + .../src/main/resources/application.yml | 32 ++ .../admin-views/src/main/resources/log4j2.xml | 63 +++ admin/admin-web/pom.xml | 7 + common/pom.xml | 18 + .../common/client/AbstractRetryClient.java | 44 ++ .../cn/icanci/ddk/common/client/Client.java | 120 ++++++ .../ddk/common/client/RemoteException.java | 116 +++++ .../common/client/http/HttpClientImpl.java | 98 +++++ .../ddk/common/enums/LogOperatorTypeEnum.java | 8 + .../ddk/common/enums/ModuleTypeEnum.java | 9 + .../cn/icanci/ddk/common/model/TextValue.java | 67 +++ .../ddk/common/model/config/AppConfigVO.java | 64 +++ .../icanci/ddk/common/model/config/AppVO.java | 53 +++ .../ddk/common/model/config/BaseVO.java | 113 +++++ .../ddk/common/model/config/GroupVO.java | 41 ++ .../common/model/config/NoticeConfigVO.java | 64 +++ .../ddk/common/model/config/RegisterVO.java | 81 ++++ .../ddk/common/model/config/TeamVO.java | 53 +++ .../ddk/common/model/log/LogOperateVO.java | 94 +++++ .../cn/icanci/ddk/common/package-info.java | 5 + .../java/cn/icanci/ddk/common/result/R.java | 154 +++++++ .../icanci/ddk/common/result/ResultCodes.java | 22 + .../ddk/common/result/ResultMessages.java | 11 + .../cn/icanci/ddk/common/utils/DateUtils.java | 90 ++++ .../icanci/ddk/common/utils/FieldUtils.java | 28 ++ .../cn/icanci/ddk/common/utils/IPUtils.java | 54 +++ .../ddk/common/utils/PropertiesUtil.java | 53 +++ pom.xml | 396 ++++++++++++++++++ spi/pom.xml | 7 + .../spi/event/AbstractEventDispatcher.java | 77 ++++ .../cn/icanci/ddk/spi/event/BaseEvent.java | 18 + .../ddk/spi/event/BaseEventListener.java | 47 +++ .../ddk/spi/event/DefaultEventDispatcher.java | 137 ++++++ .../icanci/ddk/spi/event/EventDispatcher.java | 24 ++ .../cn/icanci/ddk/spi/event/EventHandler.java | 25 ++ .../ddk/spi/event/ListenerComparator.java | 14 + .../java/cn/icanci/ddk/spi/package-info.java | 5 + 50 files changed, 2715 insertions(+) create mode 100644 admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/package-info.java create mode 100644 admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/EnvService.java create mode 100644 admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/IDGeneratorService.java create mode 100644 admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/impl/EnvServiceImpl.java create mode 100644 admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/impl/IDGeneratorServiceImpl.java create mode 100644 admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/utils/EnvUtils.java create mode 100644 admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/utils/IDHolder.java create mode 100644 admin/admin-dal/src/main/java/cn/icanci/ddk/admin/dal/mapper/DdkGroupMapper.java create mode 100644 admin/admin-dal/src/main/resources/mybatis/mapper/DdkGroupMapper.xml create mode 100644 admin/admin-views/src/main/java/cn/icanci/ddk/admin/views/AdminViewApplication.java create mode 100644 admin/admin-views/src/main/resources/application.yml create mode 100644 admin/admin-views/src/main/resources/log4j2.xml create mode 100644 common/src/main/java/cn/icanci/ddk/common/client/AbstractRetryClient.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/client/Client.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/client/RemoteException.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/client/http/HttpClientImpl.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/enums/LogOperatorTypeEnum.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/enums/ModuleTypeEnum.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/model/TextValue.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/model/config/AppConfigVO.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/model/config/AppVO.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/model/config/BaseVO.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/model/config/GroupVO.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/model/config/NoticeConfigVO.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/model/config/RegisterVO.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/model/config/TeamVO.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/model/log/LogOperateVO.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/package-info.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/result/R.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/result/ResultCodes.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/result/ResultMessages.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/utils/DateUtils.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/utils/FieldUtils.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/utils/IPUtils.java create mode 100644 common/src/main/java/cn/icanci/ddk/common/utils/PropertiesUtil.java create mode 100644 spi/src/main/java/cn/icanci/ddk/spi/event/AbstractEventDispatcher.java create mode 100644 spi/src/main/java/cn/icanci/ddk/spi/event/BaseEvent.java create mode 100644 spi/src/main/java/cn/icanci/ddk/spi/event/BaseEventListener.java create mode 100644 spi/src/main/java/cn/icanci/ddk/spi/event/DefaultEventDispatcher.java create mode 100644 spi/src/main/java/cn/icanci/ddk/spi/event/EventDispatcher.java create mode 100644 spi/src/main/java/cn/icanci/ddk/spi/event/EventHandler.java create mode 100644 spi/src/main/java/cn/icanci/ddk/spi/event/ListenerComparator.java create mode 100644 spi/src/main/java/cn/icanci/ddk/spi/package-info.java diff --git a/admin/admin-biz/pom.xml b/admin/admin-biz/pom.xml index dd7ccde..1fc9e84 100644 --- a/admin/admin-biz/pom.xml +++ b/admin/admin-biz/pom.xml @@ -16,4 +16,16 @@ 8 + + + cn.icanci.ddk + ddk-admin-dal + ${project.version} + + + cn.icanci.ddk + ddk-common + ${project.version} + + \ No newline at end of file diff --git a/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/package-info.java b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/package-info.java new file mode 100644 index 0000000..642c251 --- /dev/null +++ b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/package-info.java @@ -0,0 +1,5 @@ +/** + * @author icanci + * @since 1.0 Created in 2022/12/11 17:32 + */ +package cn.icanci.ddk.admin.biz; \ No newline at end of file diff --git a/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/EnvService.java b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/EnvService.java new file mode 100644 index 0000000..fbf231a --- /dev/null +++ b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/EnvService.java @@ -0,0 +1,14 @@ +package cn.icanci.ddk.admin.biz.service; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/12 08:28 + */ +public interface EnvService { + /** + * 获取当前的环境信息 + * + * @return 返回当前的环境信息 + */ + String getEnv(); +} diff --git a/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/IDGeneratorService.java b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/IDGeneratorService.java new file mode 100644 index 0000000..5e14a8f --- /dev/null +++ b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/IDGeneratorService.java @@ -0,0 +1,22 @@ +package cn.icanci.ddk.admin.biz.service; + +/** + * @author icanci + * @since 1.0 Created in 2022/10/30 08:43 + */ +public interface IDGeneratorService { + /** + * 生成唯一id + * + * @param prefix 前缀 + * @return id + */ + String generateBySnowFlake(String prefix); + + /** + * 生成唯一id,以DDK为开头 + * + * @return id + */ + String generateBySnowFlakeForDdk(); +} diff --git a/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/impl/EnvServiceImpl.java b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/impl/EnvServiceImpl.java new file mode 100644 index 0000000..6b1adca --- /dev/null +++ b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/impl/EnvServiceImpl.java @@ -0,0 +1,30 @@ +package cn.icanci.ddk.admin.biz.service.impl; + +import cn.icanci.ddk.admin.biz.service.EnvService; +import cn.icanci.ddk.admin.biz.utils.EnvUtils; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.stereotype.Service; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/12 08:29 + */ +@Service("envService") +public class EnvServiceImpl implements EnvService, BeanPostProcessor { + @Value("${rec.env}") + private String env; + + @Override + public String getEnv() { + return env; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + EnvUtils.setEnvService(this); + return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName); + } +} diff --git a/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/impl/IDGeneratorServiceImpl.java b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/impl/IDGeneratorServiceImpl.java new file mode 100644 index 0000000..cf5b495 --- /dev/null +++ b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/service/impl/IDGeneratorServiceImpl.java @@ -0,0 +1,38 @@ +package cn.icanci.ddk.admin.biz.service.impl; + +import cn.hutool.core.lang.Snowflake; +import cn.icanci.ddk.admin.biz.service.IDGeneratorService; +import cn.icanci.ddk.admin.biz.utils.IDHolder; + +import org.apache.commons.lang3.RandomUtils; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.stereotype.Service; + +/** + * 分布式ID生成器 + * + * @author icanci + * @since 1.0 Created in 2022/10/30 08:43 + */ +@Service +public class IDGeneratorServiceImpl implements IDGeneratorService, InitializingBean { + /** 雪花序列号生成算法 */ + private static final Snowflake SNOW_FLAKE = new Snowflake(RandomUtils.nextInt(1, 9), RandomUtils.nextInt(1, 9)); + + private static final String DDK_PREFIX = "DDK"; + + @Override + public String generateBySnowFlake(String prefix) { + return prefix + SNOW_FLAKE.nextId(); + } + + @Override + public String generateBySnowFlakeForDdk() { + return generateBySnowFlake(DDK_PREFIX); + } + + @Override + public void afterPropertiesSet() throws Exception { + IDHolder.setIdGeneratorService(this); + } +} diff --git a/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/utils/EnvUtils.java b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/utils/EnvUtils.java new file mode 100644 index 0000000..ddf1324 --- /dev/null +++ b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/utils/EnvUtils.java @@ -0,0 +1,33 @@ +package cn.icanci.ddk.admin.biz.utils; + +import cn.icanci.ddk.admin.biz.service.EnvService; +import cn.icanci.ddk.admin.biz.service.impl.EnvServiceImpl; + +import org.apache.commons.lang3.StringUtils; + +/** + * 环境标识 + * + * @author icanci + * @since 1.0 Created in 2022/11/12 08:26 + */ +public class EnvUtils { + + private static final String DEFAULT_ENV = "test"; + + private static EnvService envService; + + private static String currEnv; + + public static String getEnv() { + if (StringUtils.isBlank(currEnv)) { + String env = envService.getEnv(); + currEnv = StringUtils.isBlank(env) ? DEFAULT_ENV : env; + } + return currEnv; + } + + public static void setEnvService(EnvServiceImpl envService) { + EnvUtils.envService = envService; + } +} diff --git a/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/utils/IDHolder.java b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/utils/IDHolder.java new file mode 100644 index 0000000..9344b37 --- /dev/null +++ b/admin/admin-biz/src/main/java/cn/icanci/ddk/admin/biz/utils/IDHolder.java @@ -0,0 +1,40 @@ +package cn.icanci.ddk.admin.biz.utils; + +import cn.icanci.ddk.admin.biz.service.IDGeneratorService; + +/** + * Id 生成器 + * + * @author icanci + * @since 1.0 Created in 2022/11/11 14:18 + */ +public class IDHolder { + /** 分布式id服务 */ + private static IDGeneratorService idGeneratorService; + + private static final String DEFAULT_PREFIX = "REC"; + + public static void setIdGeneratorService(IDGeneratorService idGeneratorService) { + IDHolder.idGeneratorService = idGeneratorService; + } + + /** + * 通过雪花算法生成唯一id + * + * @param prefix 前缀 + * @return id + */ + public static String generateNoBySnowFlake(String prefix) { + return idGeneratorService.generateBySnowFlake(prefix); + } + + /** + * 通过雪花算法生成唯一id,默认 REC + * + * @return id + */ + public static String generateNoBySnowFlakeDefaultPrefix() { + return idGeneratorService.generateBySnowFlake(DEFAULT_PREFIX); + } + +} diff --git a/admin/admin-dal/pom.xml b/admin/admin-dal/pom.xml index 406eccd..9739d89 100644 --- a/admin/admin-dal/pom.xml +++ b/admin/admin-dal/pom.xml @@ -16,4 +16,44 @@ 8 + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + + + org.springframework.boot + spring-boot-starter-jdbc + + + mysql + mysql-connector-java + + + org.springframework + spring-context + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + + + true + src/main/resources + + mybatis/** + + + + \ No newline at end of file diff --git a/admin/admin-dal/src/main/java/cn/icanci/ddk/admin/dal/mapper/DdkGroupMapper.java b/admin/admin-dal/src/main/java/cn/icanci/ddk/admin/dal/mapper/DdkGroupMapper.java new file mode 100644 index 0000000..73db839 --- /dev/null +++ b/admin/admin-dal/src/main/java/cn/icanci/ddk/admin/dal/mapper/DdkGroupMapper.java @@ -0,0 +1,12 @@ +package cn.icanci.ddk.admin.dal.mapper; + +import org.apache.ibatis.annotations.Mapper; + +/** + * @author icanci + * @since 1.0 Created in 2022/12/11 17:22 + */ +@Mapper +public interface DdkGroupMapper { + +} diff --git a/admin/admin-dal/src/main/resources/mybatis/mapper/DdkGroupMapper.xml b/admin/admin-dal/src/main/resources/mybatis/mapper/DdkGroupMapper.xml new file mode 100644 index 0000000..b7f1df5 --- /dev/null +++ b/admin/admin-dal/src/main/resources/mybatis/mapper/DdkGroupMapper.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/admin/admin-views/pom.xml b/admin/admin-views/pom.xml index 0a84e90..84e3ba4 100644 --- a/admin/admin-views/pom.xml +++ b/admin/admin-views/pom.xml @@ -16,4 +16,136 @@ 8 + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + cn.icanci.ddk + ddk-admin-web + ${project.version} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + cn.icanci.rec.admin.views.AdminViewApplication + + + + + repackage + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + woff + woff2 + eot + ttf + svg + + + + + + + + true + src/main/resources + + static/** + **/*.yml + **/*.xml + + + vueboot/** + + + + \ No newline at end of file diff --git a/admin/admin-views/src/main/java/cn/icanci/ddk/admin/views/AdminViewApplication.java b/admin/admin-views/src/main/java/cn/icanci/ddk/admin/views/AdminViewApplication.java new file mode 100644 index 0000000..5e48947 --- /dev/null +++ b/admin/admin-views/src/main/java/cn/icanci/ddk/admin/views/AdminViewApplication.java @@ -0,0 +1,19 @@ +package cn.icanci.ddk.admin.views; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +/** + * @author icanci + * @since 1.0 Created in 2022/12/11 17:09 + */ +@ComponentScan(basePackages = { "cn.icanci.ddk" }) +@MapperScan(basePackages = { "cn.icanci.ddk.admin.dal.mapper" }) +@SpringBootApplication +public class AdminViewApplication { + public static void main(String[] args) { + SpringApplication.run(AdminViewApplication.class, args); + } +} diff --git a/admin/admin-views/src/main/resources/application.yml b/admin/admin-views/src/main/resources/application.yml new file mode 100644 index 0000000..d509024 --- /dev/null +++ b/admin/admin-views/src/main/resources/application.yml @@ -0,0 +1,32 @@ +server: + tomcat: + uri-encoding: UTF-8 + port: 9999 + servlet: + context-path: / + +logging: + config: classpath:log4j2.xml + +spring: + datasource: + driverClassName: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3306/ddk?useUnicode=true&characterEncoding=utf-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC + username: root + password: root + servlet: + multipart: + max-file-size: 10MB + max-request-size: 10MB + resources: + static-locations: classpath:static/,file:static/ + mvc: + static-path-pattern: /** + +mybatis: + # 指定别名设置的包为所有entity + type-aliases-package: cn.icanci.ddk.admin.dal.mapper.model + configuration: + map-underscore-to-camel-case: true # 驼峰命名规范 + mapper-locations: # mapper映射文件位置 + - classpath:mybatis/mapper/*.xml \ No newline at end of file diff --git a/admin/admin-views/src/main/resources/log4j2.xml b/admin/admin-views/src/main/resources/log4j2.xml new file mode 100644 index 0000000..9c6f19f --- /dev/null +++ b/admin/admin-views/src/main/resources/log4j2.xml @@ -0,0 +1,63 @@ + + + + + ./logs + + %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %c{1.}#%M(%L) %msg%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/admin/admin-web/pom.xml b/admin/admin-web/pom.xml index 882c405..dd38f0c 100644 --- a/admin/admin-web/pom.xml +++ b/admin/admin-web/pom.xml @@ -16,4 +16,11 @@ 8 + + + cn.icanci.ddk + ddk-admin-biz + ${project.version} + + \ No newline at end of file diff --git a/common/pom.xml b/common/pom.xml index 72f7ce5..86a0ead 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -16,4 +16,22 @@ 8 + + + org.apache.commons + commons-lang3 + + + org.apache.commons + commons-collections4 + + + com.google.guava + guava + + + commons-io + commons-io + + \ No newline at end of file diff --git a/common/src/main/java/cn/icanci/ddk/common/client/AbstractRetryClient.java b/common/src/main/java/cn/icanci/ddk/common/client/AbstractRetryClient.java new file mode 100644 index 0000000..ff90a93 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/client/AbstractRetryClient.java @@ -0,0 +1,44 @@ +package cn.icanci.ddk.common.client; + +import java.util.concurrent.*; + +/** + * 自动重试客户端 + * + * @author icanci + * @since 1.0 Created in 2022/11/14 22:16 + */ +public abstract class AbstractRetryClient implements Client { + + protected static final ThreadPoolExecutor HTTP_POOL = new ThreadPoolExecutor(40, // + 120, // + 60L, // + TimeUnit.SECONDS, // + new LinkedBlockingQueue<>(2000), // + runnable -> new Thread(runnable, "AbstractRetryClient Pool-" + runnable.hashCode()), // + (r, executor) -> { + throw new RuntimeException("AbstractRetryClient Pool is EXHAUSTED!"); + }); + + @Override + public V call(RpcRequest request, Class clazz) throws RemoteException { + return retry(request, clazz, 0, request.getRetry()); + } + + private V retry(RpcRequest request, Class clazz, int retryCount, int retry) throws RemoteException { + try { + return doExecute(request, clazz); + } catch (RemoteException | ExecutionException | InterruptedException e) { + throw new RemoteException(e); + } catch (TimeoutException e) { + while (retryCount < retry) { + retryCount++; + return retry(request, clazz, retry, retryCount); + } + throw new RemoteException(e.getMessage(), e); + } + } + + protected abstract V doExecute(RpcRequest request, Class clazz) throws ExecutionException, InterruptedException, TimeoutException; + +} diff --git a/common/src/main/java/cn/icanci/ddk/common/client/Client.java b/common/src/main/java/cn/icanci/ddk/common/client/Client.java new file mode 100644 index 0000000..232adaf --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/client/Client.java @@ -0,0 +1,120 @@ +package cn.icanci.ddk.common.client; + +import cn.hutool.http.Method; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/14 22:14 + */ +public interface Client { + /** + * 远程调用 + * + * @param request http 请求 + * @param clazz 应答类型 + * @param 应答类型 + * @return 应答数据 + * @throws RemoteException 远程调用异常 + */ + V call(RpcRequest request, Class clazz) throws RemoteException; + + class RpcRequest { + /** + * 请求路径 + */ + private String url; + /** + * 请求对象 + */ + private Object body; + /** + * 请求头 + */ + private Map headers; + /** + * 执行的方法 + */ + private Method method; + /** + * 请求超时时间 + */ + private long readTimeOut; + /** + * 超时时间单位 + */ + private TimeUnit timeUnit; + /** + * 重试次数 + */ + private int retry; + + public RpcRequest(String url, Object body, Map headers, Method method, long readTimeOut, TimeUnit timeUnit, int retry) { + this.url = url; + this.body = body; + this.headers = headers; + this.method = method; + this.readTimeOut = readTimeOut; + this.timeUnit = timeUnit; + this.retry = retry; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public Object getBody() { + return body; + } + + public void setBody(Object body) { + this.body = body; + } + + public Map getHeaders() { + return headers; + } + + public void setHeaders(Map headers) { + this.headers = headers; + } + + public Method getMethod() { + return method; + } + + public void setMethod(Method method) { + this.method = method; + } + + public long getReadTimeOut() { + return readTimeOut; + } + + public void setReadTimeOut(long readTimeOut) { + this.readTimeOut = readTimeOut; + } + + public TimeUnit getTimeUnit() { + return timeUnit; + } + + public void setTimeUnit(TimeUnit timeUnit) { + this.timeUnit = timeUnit; + } + + public int getRetry() { + return retry; + } + + public void setRetry(int retry) { + this.retry = retry; + } + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/client/RemoteException.java b/common/src/main/java/cn/icanci/ddk/common/client/RemoteException.java new file mode 100644 index 0000000..5bde981 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/client/RemoteException.java @@ -0,0 +1,116 @@ +package cn.icanci.ddk.common.client; + +import java.security.PrivilegedActionException; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/14 22:15 + */ +public class RemoteException extends RuntimeException { + /** 序列化版本 */ + private static final long serialVersionUID = -850230685842125442L; + + private int code = -1; + + /** + * Constructs a new exception with the specified detail message. The + * cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param code error code + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public RemoteException(int code, String message) { + super(message); + this.code = code; + } + + /** + * Constructs a new exception with the specified detail message. The + * cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public RemoteException(String message) { + super(message); + } + + /** + * Constructs a new exception with the specified detail message and + * cause.

Note that the detail message associated with + * {@code cause} is not automatically incorporated in + * this exception's detail message. + * + * @param code error code + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public RemoteException(int code, String message, Throwable cause) { + super(message, cause); + this.code = code; + } + + /** + * Constructs a new exception with the specified detail message and + * cause.

Note that the detail message associated with + * {@code cause} is not automatically incorporated in + * this exception's detail message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public RemoteException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new exception with the specified cause and a detail + * message of (cause==null ? null : cause.toString()) (which + * typically contains the class and detail message of cause). + * This constructor is useful for exceptions that are little more than + * wrappers for other throwables (for example, {@link + * PrivilegedActionException}). + * + * @param code error code + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public RemoteException(int code, Throwable cause) { + super(cause); + this.code = code; + } + + /** + * Constructs a new exception with the specified cause and a detail + * message of (cause==null ? null : cause.toString()) (which + * typically contains the class and detail message of cause). + * This constructor is useful for exceptions that are little more than + * wrappers for other throwables (for example, {@link + * PrivilegedActionException}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.4 + */ + public RemoteException(Throwable cause) { + super(cause); + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/client/http/HttpClientImpl.java b/common/src/main/java/cn/icanci/ddk/common/client/http/HttpClientImpl.java new file mode 100644 index 0000000..9fbb3be --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/client/http/HttpClientImpl.java @@ -0,0 +1,98 @@ +package cn.icanci.ddk.common.client.http; + +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONUtil; +import cn.icanci.ddk.common.client.AbstractRetryClient; +import cn.icanci.ddk.common.client.Client; + +import java.util.Map; +import java.util.concurrent.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Maps; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/14 22:14 + */ +@SuppressWarnings("all") +public class HttpClientImpl extends AbstractRetryClient { + + private static final Logger logger = LoggerFactory.getLogger(HttpClientImpl.class); + + private static final long DEFAULT_TIMEOUT = 3; + private static final TimeUnit DEFAULT_TIMEUNIT = TimeUnit.SECONDS; + + public static Client getInstance() { + return HttpClientImplHolder.CLIENT_IMPL; + } + + private static final class HttpClientImplHolder { + private static final HttpClientImpl CLIENT_IMPL = new HttpClientImpl(); + } + + /** + * Do execute v. + * + * @param request the request + * @param clazz the clazz + * @return the v + */ + @Override + protected V doExecute(RpcRequest request, Class clazz) throws ExecutionException, InterruptedException, TimeoutException { + FutureTask task = new FutureTask(new HttpCallRunner(request, clazz)); + HTTP_POOL.execute(task); + return task.get(request.getReadTimeOut(), request.getTimeUnit()); + } + + /** + * 请求执行器 + * + * @param 泛型 + */ + private static class HttpCallRunner implements Callable { + private final RpcRequest request; + private final Class clazz; + + public HttpCallRunner(RpcRequest request, Class clazz) { + this.request = request; + this.clazz = clazz; + } + + @Override + public V call() throws Exception { + switch (request.getMethod()) { + case GET: + return doGet(request, clazz); + case POST: + return doPost(request, clazz); + default: + throw new IllegalAccessException("Un Support Http Method:" + request.getMethod()); + } + } + + private V doGet(RpcRequest request, Class clazz) { + Map body = Maps.newHashMap(); + if (request.getBody() instanceof Map) { + body = (Map) request.getBody(); + } + String getBody = HttpUtil.createGet(request.getUrl()) // + .addHeaders(request.getHeaders())// + .form(body)// + .execute().body(); + logger.info("[{}][HttpCallRunner][doGet] request:{},resp:{}", Thread.currentThread().getName(), JSONUtil.toJsonStr(request), getBody); + return JSONUtil.toBean(getBody, clazz); + } + + private V doPost(RpcRequest request, Class clazz) { + String postBody = HttpUtil.createPost(request.getUrl()) // + .addHeaders(request.getHeaders())// + .body(JSONUtil.toJsonStr(request.getBody()))// + .execute().body(); + logger.info("[{}][HttpCallRunner][doPost] request:{},resp:{}", Thread.currentThread().getName(), JSONUtil.toJsonStr(request), postBody); + return JSONUtil.toBean(postBody, clazz); + } + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/enums/LogOperatorTypeEnum.java b/common/src/main/java/cn/icanci/ddk/common/enums/LogOperatorTypeEnum.java new file mode 100644 index 0000000..0d51d86 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/enums/LogOperatorTypeEnum.java @@ -0,0 +1,8 @@ +package cn.icanci.ddk.common.enums; + +/** + * @author icanci + * @since 1.0 Created in 2022/12/11 17:37 + */ +public enum LogOperatorTypeEnum { +} diff --git a/common/src/main/java/cn/icanci/ddk/common/enums/ModuleTypeEnum.java b/common/src/main/java/cn/icanci/ddk/common/enums/ModuleTypeEnum.java new file mode 100644 index 0000000..524bc86 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/enums/ModuleTypeEnum.java @@ -0,0 +1,9 @@ +package cn.icanci.ddk.common.enums; + +/** + * @author icanci + * @since 1.0 Created in 2022/12/11 17:37 + */ +public enum ModuleTypeEnum { + +} diff --git a/common/src/main/java/cn/icanci/ddk/common/model/TextValue.java b/common/src/main/java/cn/icanci/ddk/common/model/TextValue.java new file mode 100644 index 0000000..35b9675 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/model/TextValue.java @@ -0,0 +1,67 @@ +package cn.icanci.ddk.common.model; + +import java.io.Serializable; +import java.util.List; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/12 16:38 + */ +public class TextValue implements Serializable { + private static final long serialVersionUID = -3727976523289870284L; + + private String label; + private Object value; + private T data; + private List list; + + public TextValue(String label, Object value) { + this.label = label; + this.value = value; + } + + public TextValue(String label, Object value, T data) { + this.label = label; + this.value = value; + this.data = data; + } + + public TextValue(String label, Object value, T data, List list) { + this.label = label; + this.value = value; + this.data = data; + this.list = list; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/model/config/AppConfigVO.java b/common/src/main/java/cn/icanci/ddk/common/model/config/AppConfigVO.java new file mode 100644 index 0000000..1aa9a40 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/model/config/AppConfigVO.java @@ -0,0 +1,64 @@ +package cn.icanci.ddk.common.model.config; + +import java.util.StringJoiner; + +/** + * @author icanci + * @since 1.0 Created in 2022/12/11 17:44 + */ +public class AppConfigVO extends BaseVO { + /** + * 配置名称 + */ + private String appConfigName; + /** + * 配置值 + */ + private String appConfigValue; + /** + * 配置类型 + */ + private String appConfigType; + /** + * 项目关联uuid + */ + private String appUuid; + + public String getAppConfigName() { + return appConfigName; + } + + public void setAppConfigName(String appConfigName) { + this.appConfigName = appConfigName; + } + + public String getAppConfigValue() { + return appConfigValue; + } + + public void setAppConfigValue(String appConfigValue) { + this.appConfigValue = appConfigValue; + } + + public String getAppConfigType() { + return appConfigType; + } + + public void setAppConfigType(String appConfigType) { + this.appConfigType = appConfigType; + } + + public String getAppUuid() { + return appUuid; + } + + public void setAppUuid(String appUuid) { + this.appUuid = appUuid; + } + + @Override + public String toString() { + return new StringJoiner(",").add("appConfigName=" + appConfigName).add("appConfigValue=" + appConfigValue).add("appConfigType=" + appConfigType).add("appUuid=" + appUuid) + .toString(); + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/model/config/AppVO.java b/common/src/main/java/cn/icanci/ddk/common/model/config/AppVO.java new file mode 100644 index 0000000..7fae76f --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/model/config/AppVO.java @@ -0,0 +1,53 @@ +package cn.icanci.ddk.common.model.config; + +import java.util.StringJoiner; + +/** + * 项目组项目 + * + * @author icanci + * @since 1.0 Created in 2022/12/11 17:42 + */ +public class AppVO extends BaseVO { + /** + * 项目id,全局唯一 + */ + private String appUniqueId; + /** + * 项目名字 + */ + private String appName; + /** + * 项目组关联uuid + */ + private String teamUuid; + + public String getAppUniqueId() { + return appUniqueId; + } + + public void setAppUniqueId(String appUniqueId) { + this.appUniqueId = appUniqueId; + } + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + } + + public String getTeamUuid() { + return teamUuid; + } + + public void setTeamUuid(String teamUuid) { + this.teamUuid = teamUuid; + } + + @Override + public String toString() { + return new StringJoiner(",").add("appUniqueId=" + appUniqueId).add("appName=" + appName).add("teamUuid=" + teamUuid).toString(); + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/model/config/BaseVO.java b/common/src/main/java/cn/icanci/ddk/common/model/config/BaseVO.java new file mode 100644 index 0000000..7fae4b1 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/model/config/BaseVO.java @@ -0,0 +1,113 @@ +package cn.icanci.ddk.common.model.config; + +import java.util.Date; +import java.util.StringJoiner; + +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 基础模型 + * + * @author icanci + * @since 1.0 Created in 2022/12/11 17:37 + */ +public class BaseVO { + /** + * 数据库id + */ + private Long id; + + /** + * 雪花算法随机UUID + */ + private String uuid; + + /** + * 功能描述 + */ + private String desc; + + /** + * 创建时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 更新时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** + * 状态 0有效,1无效 + */ + private int isDelete; + + /** + * 环境 + */ + private String env; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public int getIsDelete() { + return isDelete; + } + + public void setIsDelete(int isDelete) { + this.isDelete = isDelete; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + @Override + public String toString() { + return new StringJoiner(",").add("id=" + id).add("uuid=" + uuid).add("desc=" + desc).add("createTime=" + createTime).add("updateTime=" + updateTime) + .add("isDelete=" + isDelete).add("env=" + env).toString(); + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/model/config/GroupVO.java b/common/src/main/java/cn/icanci/ddk/common/model/config/GroupVO.java new file mode 100644 index 0000000..ebd45a8 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/model/config/GroupVO.java @@ -0,0 +1,41 @@ +package cn.icanci.ddk.common.model.config; + +import java.util.StringJoiner; + +/** + * 事业群 + * + * @author icanci + * @since 1.0 Created in 2022/12/11 17:39 + */ +public class GroupVO extends BaseVO { + /** + * 事业群组id,唯一 + */ + private String groupId; + /** + * 事业群组名字 + */ + private String groupName; + + public String getGroupId() { + return groupId; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + @Override + public String toString() { + return new StringJoiner(",").add("groupId=" + groupId).add("groupName=" + groupName).toString(); + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/model/config/NoticeConfigVO.java b/common/src/main/java/cn/icanci/ddk/common/model/config/NoticeConfigVO.java new file mode 100644 index 0000000..c574a01 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/model/config/NoticeConfigVO.java @@ -0,0 +1,64 @@ +package cn.icanci.ddk.common.model.config; + +import java.util.StringJoiner; + +/** + * @author icanci + * @since 1.0 Created in 2022/12/11 17:46 + */ +public class NoticeConfigVO extends BaseVO { + /** + * 通知配置名称 + */ + private String noticeConfigName; + /** + * 通知配置资源 + */ + private String noticeConfigResource; + /** + * 测试配置值,可选;因为可能通过配置值进行特殊处理 + */ + private String noticeTestValue; + /** + * 项目关联uuid,多个以,分割 + */ + private String appUuids; + + public String getNoticeConfigName() { + return noticeConfigName; + } + + public void setNoticeConfigName(String noticeConfigName) { + this.noticeConfigName = noticeConfigName; + } + + public String getNoticeConfigResource() { + return noticeConfigResource; + } + + public void setNoticeConfigResource(String noticeConfigResource) { + this.noticeConfigResource = noticeConfigResource; + } + + public String getNoticeTestValue() { + return noticeTestValue; + } + + public void setNoticeTestValue(String noticeTestValue) { + this.noticeTestValue = noticeTestValue; + } + + public String getAppUuids() { + return appUuids; + } + + public void setAppUuids(String appUuids) { + this.appUuids = appUuids; + } + + @Override + public String toString() { + return new StringJoiner(",").add("noticeConfigName=" + noticeConfigName).add("noticeConfigResource=" + noticeConfigResource).add("noticeTestValue=" + noticeTestValue) + .add("appUuids=" + appUuids).toString(); + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/model/config/RegisterVO.java b/common/src/main/java/cn/icanci/ddk/common/model/config/RegisterVO.java new file mode 100644 index 0000000..7323569 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/model/config/RegisterVO.java @@ -0,0 +1,81 @@ +package cn.icanci.ddk.common.model.config; + +import java.util.Date; +import java.util.StringJoiner; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/22 21:35 + */ +public class RegisterVO extends BaseVO { + /** + * SDK 服务ip地址 + */ + private String clientAddress; + /** + * SDK 服务端口地址 + */ + private Integer clientPort; + /** + * SDK 服务服务唯一标识 + */ + private String appUniqueId; + /** + * 服务注册时间 + */ + private Date registerTime; + /** + * 上次注册更新时间 + */ + private Date lastUpdateTime; + + public String getClientAddress() { + return clientAddress; + } + + public void setClientAddress(String clientAddress) { + this.clientAddress = clientAddress; + } + + public int getClientPort() { + return clientPort; + } + + public void setClientPort(int clientPort) { + this.clientPort = clientPort; + } + + public void setClientPort(Integer clientPort) { + this.clientPort = clientPort; + } + + public String getAppUniqueId() { + return appUniqueId; + } + + public void setAppUniqueId(String appUniqueId) { + this.appUniqueId = appUniqueId; + } + + public Date getRegisterTime() { + return registerTime; + } + + public void setRegisterTime(Date registerTime) { + this.registerTime = registerTime; + } + + public Date getLastUpdateTime() { + return lastUpdateTime; + } + + public void setLastUpdateTime(Date lastUpdateTime) { + this.lastUpdateTime = lastUpdateTime; + } + + @Override + public String toString() { + return new StringJoiner(",").add("clientAddress=" + clientAddress).add("clientPort=" + clientPort).add("appUniqueId=" + appUniqueId).add("registerTime=" + registerTime) + .add("lastUpdateTime=" + lastUpdateTime).toString(); + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/model/config/TeamVO.java b/common/src/main/java/cn/icanci/ddk/common/model/config/TeamVO.java new file mode 100644 index 0000000..77fe373 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/model/config/TeamVO.java @@ -0,0 +1,53 @@ +package cn.icanci.ddk.common.model.config; + +import java.util.StringJoiner; + +/** + * 项目组 + * + * @author icanci + * @since 1.0 Created in 2022/12/11 17:40 + */ +public class TeamVO extends BaseVO { + /** + * 项目组id,唯一 + */ + private String teamId; + /** + * 项目组名字 + */ + private String teamName; + /** + * 事业群关联uuid + */ + private String groupUuid; + + public String getTeamId() { + return teamId; + } + + public void setTeamId(String teamId) { + this.teamId = teamId; + } + + public String getTeamName() { + return teamName; + } + + public void setTeamName(String teamName) { + this.teamName = teamName; + } + + public String getGroupUuid() { + return groupUuid; + } + + public void setGroupUuid(String groupUuid) { + this.groupUuid = groupUuid; + } + + @Override + public String toString() { + return new StringJoiner(",").add("teamId=" + teamId).add("teamName=" + teamName).add("groupUuid=" + groupUuid).toString(); + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/model/log/LogOperateVO.java b/common/src/main/java/cn/icanci/ddk/common/model/log/LogOperateVO.java new file mode 100644 index 0000000..beff918 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/model/log/LogOperateVO.java @@ -0,0 +1,94 @@ +package cn.icanci.ddk.common.model.log; + +import cn.icanci.ddk.common.enums.LogOperatorTypeEnum; +import cn.icanci.ddk.common.enums.ModuleTypeEnum; + +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * @author icanci + * @since 1.0 Created in 2022/10/30 21:13 + */ +public class LogOperateVO { + /** 编号 */ + private String id; + + /** 操作模块 */ + private ModuleTypeEnum module; + + /** 对象编号 */ + private String targetId; + + /** + * 操作类型 + */ + private LogOperatorTypeEnum operatorType; + + /** 操作内容 */ + private String content; + + /** 创建时间 */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** 环境 */ + String env; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public ModuleTypeEnum getModule() { + return module; + } + + public void setModule(ModuleTypeEnum module) { + this.module = module; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public LogOperatorTypeEnum getOperatorType() { + return operatorType; + } + + public void setOperatorType(LogOperatorTypeEnum operatorType) { + this.operatorType = operatorType; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/package-info.java b/common/src/main/java/cn/icanci/ddk/common/package-info.java new file mode 100644 index 0000000..76beabf --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/package-info.java @@ -0,0 +1,5 @@ +/** + * @author icanci + * @since 1.0 Created in 2022/12/11 16:42 + */ +package cn.icanci.ddk.common; \ No newline at end of file diff --git a/common/src/main/java/cn/icanci/ddk/common/result/R.java b/common/src/main/java/cn/icanci/ddk/common/result/R.java new file mode 100644 index 0000000..a126d4a --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/result/R.java @@ -0,0 +1,154 @@ +package cn.icanci.ddk.common.result; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.StringJoiner; + +/** + * 通用返回结果 + * + * @author icanci + * @since 1.0 Created in 2022/04/04 19:11 + */ +public class R implements Serializable { + private static final long serialVersionUID = -1343013883236338104L; + /** 是否成功 */ + private boolean ok; + /** 错误码 */ + private int code; + /** 错误信息 */ + private String message; + /** 返回前端数据 */ + private Map data = new HashMap<>(); + + public R() { + } + + /** + * Builder + * + * @return Builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * BuilderOK + * + * @return Builder + */ + public static Builder builderOk() { + return new Builder().BuilderOK(); + } + + /** + * BuilderFail + * + * @return Builder + */ + public static Builder builderFail() { + return new Builder().BuilderFail(); + } + + public static class Builder { + /** 是否成功 */ + private boolean ok; + /** 错误码 */ + private int code; + /** 错误信息 */ + private String message; + /** 返回前端数据 */ + private Map data = new HashMap(); + + private Builder() { + + } + + public Builder(boolean ok, int code) { + this.ok = ok; + this.code = code; + } + + private Builder BuilderOK() { + this.ok = true; + this.code = ResultCodes.SUCCESS; + return this; + } + + private Builder BuilderFail() { + this.ok = false; + this.code = ResultCodes.FAIL_SYSTEM; + return this; + } + + public Builder message(String val) { + message = val; + return this; + } + + public Builder code(Integer val) { + code = val; + return this; + } + + public Builder data(String key, Object value) { + data.put(key, value); + return this; + } + + public Builder data(Map map) { + data = map; + return this; + } + + public R build() { + return new R(this); + } + } + + private R(Builder builder) { + this.ok = builder.ok; + this.code = builder.code; + this.message = builder.message; + this.data = builder.data; + } + + public boolean isOk() { + return ok; + } + + public void setOk(boolean ok) { + this.ok = ok; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + + @Override + public String toString() { + return new StringJoiner(",").add("ok=" + ok).add("code=" + code).add("message=" + message).add("data=" + data).toString(); + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/result/ResultCodes.java b/common/src/main/java/cn/icanci/ddk/common/result/ResultCodes.java new file mode 100644 index 0000000..4153654 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/result/ResultCodes.java @@ -0,0 +1,22 @@ +package cn.icanci.ddk.common.result; + +/** + * code集合 + * + * @author icanci + * @since 1.0 Created in 2022/04/04 20:09 + */ +public interface ResultCodes { + /** 成功 */ + int SUCCESS = 200; + /** 400异常 */ + int FAIL_404 = 404; + /** 500异常 */ + int FAIL_500 = 500; + /** 账号异常 */ + int ACCOUNT_ERROR_CODE = 1000; + /** 账号登录超时 */ + int LOGIN_TIME_OUT = 1001; + /** 默认失败原因 */ + int FAIL_SYSTEM = 9999; +} diff --git a/common/src/main/java/cn/icanci/ddk/common/result/ResultMessages.java b/common/src/main/java/cn/icanci/ddk/common/result/ResultMessages.java new file mode 100644 index 0000000..6327558 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/result/ResultMessages.java @@ -0,0 +1,11 @@ +package cn.icanci.ddk.common.result; + +/** + * message集合 + * + * @author icanci + * @since 1.0 Created in 2022/04/04 20:09 + */ +public interface ResultMessages { + String ACCOUNT_ERROR_MESSAGE = "账号%s异常,请重新登录"; +} diff --git a/common/src/main/java/cn/icanci/ddk/common/utils/DateUtils.java b/common/src/main/java/cn/icanci/ddk/common/utils/DateUtils.java new file mode 100644 index 0000000..1c5da79 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/utils/DateUtils.java @@ -0,0 +1,90 @@ +package cn.icanci.ddk.common.utils; + +import cn.hutool.core.date.DateUtil; + +import java.util.Date; + +import org.apache.commons.lang3.StringUtils; + +/** + * 时间工具类 + * + * @author icanci + * @since 1.0 Created in 2022/11/16 23:06 + */ +public final class DateUtils { + + public enum FormatType { + /** YYYY */ + YYYY("yyyy"), + + /** MM_DD */ + MM_DD("MM-dd"), + + /** HH_MM */ + HH_MM("HH:mm"), + + /** HH_MM_SS */ + HH_MM_SS("HH:mm:ss"), + + /** YYYY_MM */ + YYYY_MM("yyyy-MM"), + + /** YYYY_MM_DD */ + YYYY_MM_DD("yyyy-MM-dd"), + + /** YYYY_MM_DD_HH */ + YYYY_MM_DD_HH("yyyy-MM-dd HH"), + + /** YYYY_MM_DD_HH_MM */ + YYYY_MM_DD_HH_MM("yyyy-MM-dd HH:mm"), + + /** YYYY_MM_DD_HH_MM_SS */ + YYYY_MM_DD_HH_MM_SS("yyyy-MM-dd HH:mm:ss"), + + ; + + private final String code; + + public String getCode() { + return code; + } + + FormatType(String code) { + this.code = code; + } + } + + /** + * 转换日期 + * TODO Hutool 的时间格式化是线程安全的,因为每次都创建一个SimpleDateFormat对象,但是性能略差 + * + * @param dateString the time + * @param formatType formatType + * @return date + */ + public static Date parse(String dateString, FormatType formatType) { + if (StringUtils.isBlank(dateString)) { + return null; + } + return DateUtil.parse(dateString, formatType.getCode()); + } + + /** + * 格式化日期 + * + * @param date the time + * @param formatType formatType + * @return date + */ + public static String format(Date date, FormatType formatType) { + if (formatType == null) { + return null; + } + try { + return DateUtil.format(date, formatType.getCode()); + } catch (Exception e) { + return null; + } + } +} \ No newline at end of file diff --git a/common/src/main/java/cn/icanci/ddk/common/utils/FieldUtils.java b/common/src/main/java/cn/icanci/ddk/common/utils/FieldUtils.java new file mode 100644 index 0000000..113f47c --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/utils/FieldUtils.java @@ -0,0 +1,28 @@ +package cn.icanci.ddk.common.utils; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/18 23:26 + */ +public class FieldUtils { + /** + * 获取本类及其父类的字段属性 + * + * @param clazz 当前类对象 + * @return 字段数组 + */ + public static Field[] getAllFields(Class clazz) { + List fieldList = new ArrayList<>(); + while (clazz != null) { + fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()))); + clazz = clazz.getSuperclass(); + } + Field[] fields = new Field[fieldList.size()]; + return fieldList.toArray(fields); + } +} diff --git a/common/src/main/java/cn/icanci/ddk/common/utils/IPUtils.java b/common/src/main/java/cn/icanci/ddk/common/utils/IPUtils.java new file mode 100644 index 0000000..36b1707 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/utils/IPUtils.java @@ -0,0 +1,54 @@ +package cn.icanci.ddk.common.utils; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; + +/** + * ip 地址工具类 + * + * @author icanci + * @since 1.0 Created in 2022/11/20 15:37 + */ +public class IPUtils { + + /** + * 获取主机地址 + */ + public static String getHostIpAddress() { + String realIp = null; + try { + InetAddress address = InetAddress.getLocalHost(); + // 如果是回环网卡地址, 则获取ipv4地址 + if (address.isLoopbackAddress()) { + address = getInet4Address(); + } + realIp = address.getHostAddress(); + } catch (Exception e) { + // no op + } + return realIp; + } + + /** + * 获取IPV4网络配置 + */ + private static InetAddress getInet4Address() throws SocketException { + // 获取所有网卡信息 + Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); + while (networkInterfaces.hasMoreElements()) { + NetworkInterface netInterface = networkInterfaces.nextElement(); + Enumeration addresses = netInterface.getInetAddresses(); + while (addresses.hasMoreElements()) { + InetAddress ip = addresses.nextElement(); + if (ip instanceof Inet4Address) { + return ip; + } + } + } + return null; + } + +} \ No newline at end of file diff --git a/common/src/main/java/cn/icanci/ddk/common/utils/PropertiesUtil.java b/common/src/main/java/cn/icanci/ddk/common/utils/PropertiesUtil.java new file mode 100644 index 0000000..88144f0 --- /dev/null +++ b/common/src/main/java/cn/icanci/ddk/common/utils/PropertiesUtil.java @@ -0,0 +1,53 @@ +package cn.icanci.ddk.common.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/15 21:38 + */ +public class PropertiesUtil { + /** + * The constant confProperties. + */ + private static Properties confProperties; + + /** + * 初始化 + * + * @param classLoader classLoader + * @param sourcePath sourcePath + */ + private static void init(ClassLoader classLoader, String sourcePath) { + if (confProperties == null) { + confProperties = new Properties(); + + try (InputStream in = classLoader.getResourceAsStream(sourcePath)) { + confProperties.load(in); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * Get string. + * + * @param classLoader 类加载器 + * @return the string + */ + public static Map getPropertyMap(ClassLoader classLoader, String sourcePath) { + // 初始化加载 + init(classLoader, sourcePath); + + Map propertyMap = new HashMap<>(); + for (Map.Entry next : confProperties.entrySet()) { + propertyMap.put((String) next.getKey(), (String) next.getValue()); + } + return propertyMap; + } +} diff --git a/pom.xml b/pom.xml index b1116c0..a4e219f 100644 --- a/pom.xml +++ b/pom.xml @@ -15,9 +15,405 @@ spi + DDK + DDK + https://gitee.com/icanci/ddk + + + UTF-8 + + 3.8.1 + 3.0.0-M1 + 3.2.1 + 3.2.0 + 1.6.8 + 1.6 + 3.0.0-M1 + + 1.8 + UTF-8 8 8 + + 4.13.2 + + 1.7.30 + 2.12.1 + 2.13.3 + 2.13.3 + 3.3.4 + + 2.2.2.RELEASE + 2.2.2 + + 3.4 + 2.4 + 4.3 + 19.0 + + 2.11.2 + 1.2.70 + + 1.4.2.Final + 5.4.2 + + 4.1.63.Final + + + + + org.springframework.boot + spring-boot-dependencies + + + org.springframework.boot + spring-boot-starter-logging + + + ${spring.boot.version} + import + pom + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${spring.boot.mybatis.version.version} + + + + org.apache.commons + commons-lang3 + ${commons.lang3.version} + + + commons-io + commons-io + ${commons.io.version} + + + org.apache.commons + commons-collections4 + ${commons.collections4.version} + + + com.google.guava + guava + ${guava.version} + + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + com.alibaba + fastjson + ${fastjson.version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + junit + junit + ${junit.version} + test + + + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + + org.apache.logging.log4j + log4j-slf4j-impl + ${log4j-slf4j-impl.version} + + + + org.apache.logging.log4j + log4j-api + ${log4j-api.version} + + + + org.apache.logging.log4j + log4j-core + ${log4j-core.version} + + + + com.lmax + disruptor + ${disruptor.version} + + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + + cn.hutool + hutool-all + ${hutool.version} + + + io.netty + netty-all + ${netty-all.version} + + + + + + + + org.slf4j + slf4j-api + + + + org.apache.logging.log4j + log4j-slf4j-impl + + + + org.apache.logging.log4j + log4j-api + + + + org.apache.logging.log4j + log4j-core + + + + com.lmax + disruptor + + + org.springframework.boot + spring-boot-starter-log4j2 + + + junit + junit + test + + + com.fasterxml.jackson.core + jackson-core + + + com.alibaba + fastjson + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-databind + + + cn.hutool + hutool-all + + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + icanci + icanci@foxmail.com + https://gitee.com/icanci + +8 + + + + + + ${project.artifactId}-${project.version} + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + verify + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-deploy-plugin.version} + + ${javadoc.opts} + + + + + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.target} + ${maven.compiler.source} + ${project.build.sourceEncoding} + + + + + org.apache.maven.plugins + maven-source-plugin + + + package + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + package + + jar + + + + + + + + + + + disable-javadoc-doclint + + [1.8,) + + + -Xdoclint:none + + + + release + + + + + org.apache.maven.plugins + maven-source-plugin + + + package + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + package + + jar + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + verify + + sign + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + ${nexus-staging-maven-plugin.version} + true + + oss-release + https://s01.oss.sonatype.org/ + true + + + + + + + sonatype-snapshots + https://s01.oss.sonatype.org/content/repositories/snapshots + + + sonatype-release + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + + + sonatype-snapshots + https://s01.oss.sonatype.org/content/repositories/snapshots + + + sonatype-release + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ + + \ No newline at end of file diff --git a/spi/pom.xml b/spi/pom.xml index 8e8c83d..9910a10 100644 --- a/spi/pom.xml +++ b/spi/pom.xml @@ -16,4 +16,11 @@ 8 + + + + org.springframework.boot + spring-boot-starter-web + + \ No newline at end of file diff --git a/spi/src/main/java/cn/icanci/ddk/spi/event/AbstractEventDispatcher.java b/spi/src/main/java/cn/icanci/ddk/spi/event/AbstractEventDispatcher.java new file mode 100644 index 0000000..812dc29 --- /dev/null +++ b/spi/src/main/java/cn/icanci/ddk/spi/event/AbstractEventDispatcher.java @@ -0,0 +1,77 @@ +package cn.icanci.ddk.spi.event; + +import java.util.*; +import java.util.concurrent.*; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * 事件分发抽象处理器 + * + * @author icanci + * @since 1.0 Created in 2022/11/11 18:01 + */ +public abstract class AbstractEventDispatcher implements EventDispatcher, ApplicationContextAware { + /** + * Spring 容器 + */ + protected ApplicationContext applicationContext; + /** + * 事件监听器列表 + */ + protected Map, List> eventListMap = new ConcurrentHashMap<>(); + /** + * 监听器 + */ + protected List listeners = new LinkedList(); + /** + * 注册事件类型 + */ + protected Set> eventClasses = new HashSet<>(); + /** + * 排序器 + */ + protected static final ListenerComparator LISTENER_COMPARATOR = new ListenerComparator(); + /** + * 线程池核心大小 + */ + private static final int CORE_SIZE = Runtime.getRuntime().availableProcessors(); + /** + * 线程池 + */ + protected static final ThreadPoolExecutor EVENT_POOL = new ThreadPoolExecutor(CORE_SIZE, // + CORE_SIZE << 1, // + 60L, // + TimeUnit.SECONDS, // + new LinkedBlockingQueue<>(2000), // + runnable -> new Thread(runnable, "AbstractEventDispatcher Pool-" + runnable.hashCode()), // + (r, executor) -> { + throw new RuntimeException("AbstractEventDispatcher Pool is EXHAUSTED!"); + }); + + private final Object lock = new Object(); + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + synchronized (lock) { + register(); + } + } + + /** + * 注册事件和监听器 + */ + protected abstract void register(); + + /** + * 获取事件执行线程池 + * + * @return 事件执行线程池 + */ + protected Executor getTaskPool() { + return EVENT_POOL; + } +} diff --git a/spi/src/main/java/cn/icanci/ddk/spi/event/BaseEvent.java b/spi/src/main/java/cn/icanci/ddk/spi/event/BaseEvent.java new file mode 100644 index 0000000..a7bab11 --- /dev/null +++ b/spi/src/main/java/cn/icanci/ddk/spi/event/BaseEvent.java @@ -0,0 +1,18 @@ +package cn.icanci.ddk.spi.event; + +import java.util.EventObject; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/11 18:01 + */ +public class BaseEvent extends EventObject { + + public BaseEvent(Object source) { + super(source); + } + + public BaseEvent() { + super("BaseEvent"); + } +} diff --git a/spi/src/main/java/cn/icanci/ddk/spi/event/BaseEventListener.java b/spi/src/main/java/cn/icanci/ddk/spi/event/BaseEventListener.java new file mode 100644 index 0000000..b876953 --- /dev/null +++ b/spi/src/main/java/cn/icanci/ddk/spi/event/BaseEventListener.java @@ -0,0 +1,47 @@ +package cn.icanci.ddk.spi.event; + +import java.util.EventListener; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/11 18:01 + */ +public abstract class BaseEventListener implements EventListener { + + /** + * 接受Event方法 + * + * @param event 事件 + */ + protected abstract void event(T event); + + /** + * 处理 Event + * + * @param event 事件 + */ + public final void onEvent(T event) { + if (isSupport(event)) { + event(event); + } + } + + /** + * 是否支持 + * + * @param event event + * @return 返回是否支持 + */ + protected boolean isSupport(T event) { + return true; + } + + /** + * 监听器执行的顺序 数值越小,优先级越高 + * + * @return 返回顺序 + */ + protected int order() { + return 0; + } +} diff --git a/spi/src/main/java/cn/icanci/ddk/spi/event/DefaultEventDispatcher.java b/spi/src/main/java/cn/icanci/ddk/spi/event/DefaultEventDispatcher.java new file mode 100644 index 0000000..bbd843e --- /dev/null +++ b/spi/src/main/java/cn/icanci/ddk/spi/event/DefaultEventDispatcher.java @@ -0,0 +1,137 @@ +package cn.icanci.ddk.spi.event; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; +import java.util.function.Consumer; + +/** + * 事件分发器默认实现 + * + * @author icanci + * @since 1.0 Created in 2022/11/11 18:01 + */ +public class DefaultEventDispatcher extends AbstractEventDispatcher { + + /** + * 注册事件和监听器 + */ + @Override + @SuppressWarnings("all") + protected void register() { + Map eventMap = applicationContext.getBeansOfType(BaseEvent.class); + for (BaseEvent bean : eventMap.values()) { + eventClasses.add(bean.getClass()); + } + + Map listenerMap = applicationContext.getBeansOfType(BaseEventListener.class); + for (BaseEventListener bean : listenerMap.values()) { + listeners.add(bean); + } + postEventListenerMapper(); + } + + /** + * 映射mapper + */ + private void postEventListenerMapper() { + if (listeners.isEmpty() || eventClasses.isEmpty()) { + return; + } + + for (Class eventClass : eventClasses) { + for (BaseEventListener listener : listeners) { + if (!isSupport(eventClass, listener)) { + continue; + } + List baseEventListeners = eventListMap.get(eventClass); + if (baseEventListeners == null || baseEventListeners.isEmpty()) { + baseEventListeners = new ArrayList<>(); + } + baseEventListeners.add(listener); + eventListMap.put(eventClass, baseEventListeners); + } + } + + // 清空 help gc + listeners = null; + eventClasses = null; + + // 排序 + Collection> listCollection = eventListMap.values(); + for (List baseEventListeners : listCollection) { + baseEventListeners.sort(LISTENER_COMPARATOR); + } + } + + /** + * 是否支持加入到listener + * + * @param eventClass eventClass + * @param listener listener + * @return 是否支持加入到listener + */ + private boolean isSupport(Class eventClass, BaseEventListener listener) { + Type type = listener.getClass().getGenericSuperclass(); + ParameterizedType parameterizedType = (ParameterizedType) type; + Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); + Type actualTypeArgument = actualTypeArguments[0]; + return eventClass == actualTypeArgument; + } + + /** + * 移除监听器 + * + * @param baseEvent baseEvent 事件 + * @param baseEventListener baseEventListener 监听器 + */ + public void remove(BaseEvent baseEvent, BaseEventListener baseEventListener) { + List listeners = eventListMap.get(baseEvent.getClass()); + if (listeners == null || listeners.isEmpty()) { + return; + } + listeners.remove(baseEventListener); + } + + /** + * 分发事件 + * + * @param baseEvent baseEvent + */ + @Override + public void fire(BaseEvent baseEvent) { + fire(baseEvent, true); + } + + /** + * 分发事件 + * + * @param baseEvent baseEvent + * @param sync 是否同步发送 + */ + @Override + public void fire(final BaseEvent baseEvent, boolean sync) { + final List listeners = eventListMap.get(baseEvent.getClass()); + if (listeners == null || listeners.isEmpty()) { + return; + } + + Consumer> consumer = sync ? baseEventListeners -> { + for (final BaseEventListener listener : baseEventListeners) { + listener.onEvent(baseEvent); + } + } : baseEventListeners -> { + Executor taskExecutor = getTaskPool(); + for (final BaseEventListener listener : baseEventListeners) { + taskExecutor.execute(new EventHandler(baseEvent, listener)); + } + }; + + consumer.accept(listeners); + } + +} diff --git a/spi/src/main/java/cn/icanci/ddk/spi/event/EventDispatcher.java b/spi/src/main/java/cn/icanci/ddk/spi/event/EventDispatcher.java new file mode 100644 index 0000000..4aa628d --- /dev/null +++ b/spi/src/main/java/cn/icanci/ddk/spi/event/EventDispatcher.java @@ -0,0 +1,24 @@ +package cn.icanci.ddk.spi.event; + +/** + * 事件分发器抽象 + * + * @author icanci + * @since 1.0 Created in 2022/11/11 18:01 + */ +public interface EventDispatcher { + /** + * 分发事件 同步发送 + * + * @param event event + */ + void fire(final BaseEvent event); + + /** + * 分发事件 + * + * @param event event + * @param sync 是否同步发送 + */ + void fire(final BaseEvent event, boolean sync); +} diff --git a/spi/src/main/java/cn/icanci/ddk/spi/event/EventHandler.java b/spi/src/main/java/cn/icanci/ddk/spi/event/EventHandler.java new file mode 100644 index 0000000..fa7e08e --- /dev/null +++ b/spi/src/main/java/cn/icanci/ddk/spi/event/EventHandler.java @@ -0,0 +1,25 @@ +package cn.icanci.ddk.spi.event; + +/** + * 事件执行 + * + * @author icanci + * @since 1.0 Created in 2022/11/11 18:01 + */ +public class EventHandler implements Runnable { + /** 事件 */ + private final BaseEvent event; + + /** 事件监听器 */ + private final BaseEventListener listener; + + public EventHandler(BaseEvent event, BaseEventListener listener) { + this.event = event; + this.listener = listener; + } + + @Override + public void run() { + listener.onEvent(event); + } +} diff --git a/spi/src/main/java/cn/icanci/ddk/spi/event/ListenerComparator.java b/spi/src/main/java/cn/icanci/ddk/spi/event/ListenerComparator.java new file mode 100644 index 0000000..df82aa3 --- /dev/null +++ b/spi/src/main/java/cn/icanci/ddk/spi/event/ListenerComparator.java @@ -0,0 +1,14 @@ +package cn.icanci.ddk.spi.event; + +import java.util.Comparator; + +/** + * @author icanci + * @since 1.0 Created in 2022/11/11 18:01 + */ +public class ListenerComparator implements Comparator { + @Override + public int compare(BaseEventListener o1, BaseEventListener o2) { + return o1.order() - o2.order(); + } +} diff --git a/spi/src/main/java/cn/icanci/ddk/spi/package-info.java b/spi/src/main/java/cn/icanci/ddk/spi/package-info.java new file mode 100644 index 0000000..a489c2a --- /dev/null +++ b/spi/src/main/java/cn/icanci/ddk/spi/package-info.java @@ -0,0 +1,5 @@ +/** + * @author icanci + * @since 1.0 Created in 2022/12/11 12:48 + */ +package cn.icanci.ddk.spi; \ No newline at end of file -- Gitee