初始代码
This commit is contained in:
34
yunzhupaas-cloud-common/pom.xml
Normal file
34
yunzhupaas-cloud-common/pom.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yunzhupaas-common</artifactId>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<version>5.2.0-RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>yunzhupaas-cloud-common</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>yunzhupaas-common-dubbo</module>
|
||||
<module>yunzhupaas-common-feign</module>
|
||||
<module>yunzhupaas-common-seata</module>
|
||||
<module>yunzhupaas-common-cloudshardingsphere</module>
|
||||
<module>yunzhupaas-common-mq</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!--<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-boot-common</artifactId>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>-->
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-cloud-common</artifactId>
|
||||
<version>5.2.0-RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>yunzhupaas-common-cloudshardingsphere</artifactId>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-common-shardingsphere</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.yunzhupaas.config;
|
||||
|
||||
import com.alibaba.cloud.nacos.NacosConfigManager;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
|
||||
import com.yunzhupaas.constant.GlobalConst;
|
||||
import org.apache.shardingsphere.driver.api.yaml.YamlShardingSphereDataSourceFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @author 云筑产品开发平台组
|
||||
* @user N
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
* @date 2024/11/23 16:52
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(name = "org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient")
|
||||
@ConditionalOnProperty(prefix = "config", name = "sharding-sphere-enabled", havingValue = "true")
|
||||
public class CloudShardingSphereAutoConfig {
|
||||
|
||||
public CloudShardingSphereAutoConfig() {
|
||||
System.out.println("启用 ShardingSphere");
|
||||
}
|
||||
|
||||
public static final String PREFIX = "shardingsphere";
|
||||
|
||||
@Bean
|
||||
public Object initShardingSphereDataSource(@Qualifier("dataSourceSystem") DynamicRoutingDataSource dataSource,
|
||||
NacosConfigManager nacosConfigManager) throws SQLException, IOException, NacosException {
|
||||
String shardingContent = nacosConfigManager.getConfigService().getConfig("sharding-sphere.yaml",
|
||||
"DEFAULT_GROUP", 3000L);
|
||||
if (shardingContent != null) {
|
||||
DataSource SSDataSource = YamlShardingSphereDataSourceFactory
|
||||
.createDataSource(shardingContent.getBytes(GlobalConst.DEFAULT_CHARSET));
|
||||
dataSource.addDataSource(PREFIX, SSDataSource);
|
||||
} else {
|
||||
System.out.println("ShardingSphere 加载失败,缺少 sharding-sphere.yaml 配置文件");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
39
yunzhupaas-cloud-common/yunzhupaas-common-dubbo/pom.xml
Normal file
39
yunzhupaas-cloud-common/yunzhupaas-common-dubbo/pom.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yunzhupaas-cloud-common</artifactId>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<version>5.2.0-RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>yunzhupaas-common-dubbo</artifactId>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-common-auth</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.yunzhupaas.filter;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.rpc.*;
|
||||
|
||||
/**
|
||||
* Dubbo请求过滤器
|
||||
*/
|
||||
@Slf4j
|
||||
@Activate(group = { CommonConstants.PROVIDER, CommonConstants.CONSUMER }, order = 100)
|
||||
public class MyDubboRequestFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
|
||||
Result result;
|
||||
// Provider端记录日志
|
||||
if (RpcContext.getContext().isProviderSide()) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
result = invoker.invoke(invocation);
|
||||
long elapsed = System.currentTimeMillis() - startTime;
|
||||
|
||||
String baselog = "Client[" + CommonConstants.PROVIDER + "],InterfaceName=["
|
||||
+ invocation.getInvoker().getInterface().getSimpleName() + "],MethodName=["
|
||||
+ invocation.getMethodName() + "]";
|
||||
if (result.hasException()) {
|
||||
log.error("DUBBO - 处理异常: {}, Exception = {}", baselog, result.getException());
|
||||
} else {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("DUBBO - 服务响应: {}, Elapsed=[{}ms]", baselog, elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
result = invoker.invoke(invocation);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.yunzhupaas.filter;
|
||||
|
||||
import cn.dev33.satoken.same.SaSameUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.consts.AuthConsts;
|
||||
import com.yunzhupaas.properties.SecurityProperties;
|
||||
import com.yunzhupaas.util.Constants;
|
||||
import com.yunzhupaas.util.UserProvider;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.rpc.*;
|
||||
|
||||
/**
|
||||
* Dubbo过滤器 自动传递装载UserInfo
|
||||
*/
|
||||
@Activate(group = { CommonConstants.PROVIDER, CommonConstants.CONSUMER }, order = 101)
|
||||
public class MyDubboTokenFilter implements Filter {
|
||||
|
||||
private static SecurityProperties securityProperties;
|
||||
|
||||
public MyDubboTokenFilter() {
|
||||
MyDubboTokenFilter.securityProperties = SpringUtil.getBean(SecurityProperties.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
|
||||
UserInfo userInfo;
|
||||
Result result;
|
||||
boolean isProvider;
|
||||
String url = RpcContext.getContext().getUrl().toString();
|
||||
if (url.startsWith("injvm")) {
|
||||
isProvider = url.contains("side=provider");
|
||||
} else {
|
||||
isProvider = RpcContext.getContext().isProviderSide();
|
||||
}
|
||||
// Provider端
|
||||
if (isProvider) {
|
||||
try {
|
||||
// 设置本地认证信息
|
||||
userInfo = (UserInfo) RpcContext.getContext().getObjectAttachment(Constants.AUTHORIZATION);
|
||||
UserProvider.setLocalLoginUser(userInfo);
|
||||
if (securityProperties.isEnableInnerAuth()) {
|
||||
String innerToken = invocation.getAttachment(AuthConsts.INNER_TOKEN_KEY);
|
||||
SaSameUtil.checkToken(innerToken);
|
||||
}
|
||||
result = invoker.invoke(invocation);
|
||||
} finally {
|
||||
// 清除用户缓存
|
||||
UserProvider.clearLocalUser();
|
||||
}
|
||||
} else {
|
||||
// Consumer端
|
||||
// 传递UserInfo
|
||||
userInfo = UserProvider.getUser();
|
||||
if (userInfo.getUserId() != null) {
|
||||
invocation.setAttachment(Constants.AUTHORIZATION, userInfo);
|
||||
}
|
||||
if (securityProperties.isEnableInnerAuth()) {
|
||||
invocation.setAttachment(AuthConsts.INNER_TOKEN_KEY, UserProvider.getInnerAuthToken());
|
||||
}
|
||||
result = invoker.invoke(invocation);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
yunzhupaasDubboToken=com.yunzhupaas.filter.MyDubboTokenFilter
|
||||
yunzhupaasDubboRequest=com.yunzhupaas.filter.MyDubboRequestFilter
|
||||
@@ -0,0 +1,2 @@
|
||||
# security/serialize.allowlist
|
||||
com.yunzhupaas.base.UserInfo
|
||||
26
yunzhupaas-cloud-common/yunzhupaas-common-feign/pom.xml
Normal file
26
yunzhupaas-cloud-common/yunzhupaas-common-feign/pom.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yunzhupaas-cloud-common</artifactId>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<version>5.2.0-RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>yunzhupaas-common-feign</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-common-auth</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.yunzhupaas;
|
||||
|
||||
import feign.Logger;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.constant.GlobalConst;
|
||||
import com.yunzhupaas.consts.AuthConsts;
|
||||
import com.yunzhupaas.properties.SecurityProperties;
|
||||
import com.yunzhupaas.util.Constants;
|
||||
import com.yunzhupaas.util.ServletUtil;
|
||||
import com.yunzhupaas.util.UserProvider;
|
||||
import com.yunzhupaas.utils.FeignHolder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author 云筑产品开发平台组
|
||||
* @version V3.1.0
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
* @date 2024/3/16 10:51
|
||||
*/
|
||||
@Configuration
|
||||
public class FeignConfig implements RequestInterceptor {
|
||||
|
||||
@Autowired
|
||||
private SecurityProperties securityProperties;
|
||||
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
// 添加token
|
||||
Map<String, String> headers = FeignHolder.get();
|
||||
String token = null;
|
||||
if (headers != null) {
|
||||
// 通过FeignHolder调用
|
||||
template.header("User-Agent", headers.get("user-agent"));
|
||||
template.header(Constants.AUTHORIZATION, headers.get(Constants.AUTHORIZATION));
|
||||
template.header("X-Real-IP", headers.get("x-real-ip"));
|
||||
template.header("X-Forwarded-For", headers.get("x-forwarded-for"));
|
||||
/*
|
||||
* headers.entrySet().forEach((k)->{
|
||||
* template.header(k.getKey(), k.getValue());
|
||||
* });
|
||||
*/
|
||||
} else {
|
||||
// 先获取当前本地缓存中UserInfo的TOKEN
|
||||
// 适配临时切换用户
|
||||
UserInfo userInfo = UserProvider.getLocalLoginUser();
|
||||
if (userInfo != null && userInfo.getToken() != null) {
|
||||
token = userInfo.getToken();
|
||||
template.header(Constants.AUTHORIZATION, token);
|
||||
}
|
||||
// Web环境直接调用
|
||||
HttpServletRequest request = ServletUtil.getRequest();
|
||||
if (request != null) {
|
||||
if (token == null) {
|
||||
template.header(Constants.AUTHORIZATION, request.getHeader(Constants.AUTHORIZATION));
|
||||
}
|
||||
template.header("User-Agent", request.getHeader("User-Agent"));
|
||||
template.header("X-Real-IP", request.getHeader("X-Real-IP"));
|
||||
template.header("X-Forwarded-For", request.getHeader("X-Forwarded-For"));
|
||||
}
|
||||
}
|
||||
if (securityProperties.isEnableInnerAuth() || securityProperties.isEnablePreAuth()) {
|
||||
template.header(AuthConsts.INNER_TOKEN_KEY, UserProvider.getInnerAuthToken());
|
||||
}
|
||||
template.header(GlobalConst.HEADER_HOST, ServletUtil.getRequestHost());
|
||||
}
|
||||
|
||||
/**
|
||||
* Openfeign调用日志
|
||||
* NONE,BASIC,HEADERS,FULL共有四种等级
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
Logger.Level feignLoggerLeave() {
|
||||
return Logger.Level.FULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.yunzhupaas.utils;
|
||||
|
||||
import com.yunzhupaas.util.ThreadPoolExecutorUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* 异步FEIGN请求, 把当前REQUEST的HEADER存入新线程中, 在新线程中调用feign请求, FeignConfig
|
||||
* 中取当前headers发送到新服务
|
||||
* 使用方式:
|
||||
* 1、直接调用set设置Header, Feign请求全部调用完之后调用clear清除线程变量
|
||||
* 2、调用asyncFeign、sendFeign 调用完后自动清除线程变量
|
||||
*/
|
||||
// @ConditionalOnBean(ThreadPoolTaskExecutor.class)
|
||||
@Component
|
||||
@Slf4j
|
||||
public class FeignHolder {
|
||||
private static ThreadLocal<Map<String, String>> feignHeader = new ThreadLocal<>();
|
||||
|
||||
public static void set(Map<String, String> headers) {
|
||||
TreeMap map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
map.putAll(headers);
|
||||
feignHeader.set(map);
|
||||
}
|
||||
|
||||
public static Map<String, String> get() {
|
||||
return feignHeader.get();
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
feignHeader.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Async异步发送请求, 完成后清空线程变量
|
||||
*
|
||||
* @param headers
|
||||
* @param supplier
|
||||
* @return
|
||||
*/
|
||||
public static Future<?> asyncFeign(Map<String, String> headers, Supplier supplier) {
|
||||
return ThreadPoolExecutorUtil.getExecutor().submit(() -> sendFeign(headers, supplier));
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步发送请求, 完成后清空线程变量
|
||||
*
|
||||
* @param headers
|
||||
* @param supplier
|
||||
*/
|
||||
public static <R> R sendFeign(Map<String, String> headers, Supplier<R> supplier) {
|
||||
try {
|
||||
set(headers);
|
||||
return supplier.get();
|
||||
} catch (Exception e) {
|
||||
log.error("同步发送Feign请求失败", e);
|
||||
return null;
|
||||
} finally {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.yunzhupaas.utils;
|
||||
|
||||
import com.yunzhupaas.constant.ModuleName;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author 云筑产品开发平台组
|
||||
* @version V3.1.0
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
* @date 2024/3/16 10:51
|
||||
*/
|
||||
@Data
|
||||
public class FeignName {
|
||||
public static final String SYSTEM_SERVER_NAME = ModuleName.SYSTEM_SERVER_NAME;
|
||||
|
||||
public static final String MESSAGE_SERVER_NAME = ModuleName.MESSAGE_SERVER_NAME;
|
||||
|
||||
public static final String VUSUALDEV_SERVER_NAME = ModuleName.VUSUALDEV_SERVER_NAME;
|
||||
|
||||
public static final String EXAMPLE_SERVER_NAME = ModuleName.EXAMPLE_SERVER_NAME;
|
||||
|
||||
public static final String EXTEND_SERVER_NAME = ModuleName.EXTEND_SERVER_NAME;
|
||||
|
||||
public static final String APP_SERVER_NAME = ModuleName.APP_SERVER_NAME;
|
||||
|
||||
public static final String WORKFLOW_SERVER_NAME = ModuleName.WORKFLOW_SERVER_NAME;
|
||||
|
||||
public static final String FILE_SERVER_NAME = ModuleName.FILE_SERVER_NAME;
|
||||
|
||||
public static final String PERMISSION_SERVER_NAME = ModuleName.PERMISSION_SERVER_NAME;
|
||||
|
||||
public static final String FORM_SERVER_NAME = ModuleName.FORM_SERVER_NAME;
|
||||
|
||||
public static final String OAUTH_SERVER_NAME = ModuleName.OAUTH_SERVER_NAME;
|
||||
|
||||
public static final String SCHEDULE_SERVER_NAME = ModuleName.SCHEDULE_SERVER_NAME;
|
||||
|
||||
}
|
||||
40
yunzhupaas-cloud-common/yunzhupaas-common-mq/pom.xml
Normal file
40
yunzhupaas-cloud-common/yunzhupaas-common-mq/pom.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-cloud-common</artifactId>
|
||||
<version>5.2.0-RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>yunzhupaas-common-mq</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-common-event</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--RocketMQ-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--RabbitMQ-->
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
|
||||
</dependency>-->
|
||||
|
||||
<!--Kafka-->
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
|
||||
</dependency>-->
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.yunzhupaas.config;
|
||||
|
||||
import com.baomidou.lock.LockTemplate;
|
||||
import com.yunzhupaas.consts.ProjectEventConst;
|
||||
import com.yunzhupaas.handler.ProjectEventMQMessageHandler;
|
||||
import com.yunzhupaas.handler.ProjectEventMQSender;
|
||||
import com.yunzhupaas.properties.EventProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.stream.function.StreamBridge;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class MqAutoConfiguration {
|
||||
|
||||
@Bean(ProjectEventConst.DEFAULT_TOPIC_NAME)
|
||||
@ConditionalOnProperty(prefix = "event", name = "event-publish-type", havingValue = ProjectEventConst.EVENT_PUBLISH_TYPE_QUEUE)
|
||||
public Consumer<Message<?>> getDefaultMqConsumer(LockTemplate lockTemplate) {
|
||||
return new ProjectEventMQMessageHandler(lockTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义事件发布渠道为QUEUE
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "event", name = "event-publish-type", havingValue = ProjectEventConst.EVENT_PUBLISH_TYPE_QUEUE)
|
||||
public ProjectEventMQSender getProjectEventMQSender(StreamBridge streamBridge, EventProperty eventProperties) {
|
||||
return new ProjectEventMQSender(streamBridge, eventProperties);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.yunzhupaas.handler;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.lock.LockTemplate;
|
||||
import com.yunzhupaas.consts.ProjectEventConst;
|
||||
import com.yunzhupaas.module.ProjectEventInstance;
|
||||
import com.yunzhupaas.util.JsonUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 自定义事件监听, MQ渠道, 收到通知后发送Spring事件(RedisEventInstance)
|
||||
*/
|
||||
@Slf4j
|
||||
public class ProjectEventMQMessageHandler implements Consumer<Message<?>>, ApplicationEventPublisherAware {
|
||||
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
private final LockTemplate lockTemplate;
|
||||
|
||||
public ProjectEventMQMessageHandler(LockTemplate lockTemplate) {
|
||||
this.lockTemplate = lockTemplate;
|
||||
log.info("初始化自定义事件MQ监听器");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Message<?> o) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("事件监听收到MQ消息:{}", JSON.toJSONString(o));
|
||||
}
|
||||
// 是否存在自定义事件的标识
|
||||
if (o.getHeaders().get(ProjectEventConst.DEFAULT_CHANNEL_PREFIX) == null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("事件监听忽略MQ消息:{}", JSON.toJSONString(o));
|
||||
}
|
||||
return;
|
||||
}
|
||||
Object payload = o.getPayload();
|
||||
ProjectEventInstance instance;
|
||||
if (payload instanceof byte[]) {
|
||||
instance = JSON.parseObject((byte[]) payload, ProjectEventInstance.class);
|
||||
} else if (payload instanceof String) {
|
||||
instance = JSON.parseObject((String) payload, ProjectEventInstance.class);
|
||||
} else {
|
||||
instance = JsonUtil.getJsonToBean(payload, ProjectEventInstance.class);
|
||||
}
|
||||
applicationEventPublisher.publishEvent(instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
this.applicationEventPublisher = applicationEventPublisher;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.yunzhupaas.handler;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.yunzhupaas.consts.ProjectEventConst;
|
||||
import com.yunzhupaas.module.ProjectEvent;
|
||||
import com.yunzhupaas.event.ProjectEventSender;
|
||||
import com.yunzhupaas.properties.EventProperty;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.stream.function.StreamBridge;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
/**
|
||||
* 自定义事件发布 MQ渠道
|
||||
*/
|
||||
@Slf4j
|
||||
public class ProjectEventMQSender implements ProjectEventSender {
|
||||
|
||||
private StreamBridge streamBridge;
|
||||
private EventProperty eventProperty;
|
||||
|
||||
public ProjectEventMQSender(StreamBridge streamBridge, EventProperty eventProperty) {
|
||||
this.streamBridge = streamBridge;
|
||||
this.eventProperty = eventProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(ProjectEvent event) {
|
||||
streamBridge.send(ProjectEventConst.DEFAULT_TOPIC_NAME + "-out-0", MessageBuilder.withPayload(event)
|
||||
// 添加自定义事件标识
|
||||
.setHeader(ProjectEventConst.DEFAULT_CHANNEL_PREFIX, event.getChannel())
|
||||
.build());
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("发送MQ自定义事件: {}", JSON.toJSONString(event));
|
||||
}
|
||||
}
|
||||
}
|
||||
35
yunzhupaas-cloud-common/yunzhupaas-common-seata/pom.xml
Normal file
35
yunzhupaas-cloud-common/yunzhupaas-common-seata/pom.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yunzhupaas-cloud-common</artifactId>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<version>5.2.0-RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>yunzhupaas-common-seata</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- seata -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.esotericsoftware</groupId>
|
||||
<artifactId>kryo</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.javakaffee</groupId>
|
||||
<artifactId>kryo-serializers</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,159 @@
|
||||
package io.seata.rm.datasource;
|
||||
|
||||
import io.seata.rm.datasource.sql.struct.Field;
|
||||
import io.seata.sqlparser.util.ColumnUtils;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* generate sql and set value to sql
|
||||
*
|
||||
* @author JerryYin
|
||||
*/
|
||||
public class SqlGenerateUtils {
|
||||
|
||||
private static final int MAX_IN_SIZE = 1000;
|
||||
|
||||
private SqlGenerateUtils() {
|
||||
|
||||
}
|
||||
|
||||
public static String buildWhereConditionByPKs(List<String> pkNameList, int rowSize, String dbType)
|
||||
throws SQLException {
|
||||
return "sqlserver".equals(dbType) ? buildWhereConditionByPKsBySqlServer(pkNameList, rowSize, dbType, MAX_IN_SIZE) : buildWhereConditionByPKs(pkNameList, rowSize, dbType, MAX_IN_SIZE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* each pk is a condition.the result will like :" (id,userCode) in ((?,?),(?,?)) or (id,userCode) in ((?,?),(?,?)
|
||||
* ) or (id,userCode) in ((?,?))"
|
||||
* Build where condition by pks string.
|
||||
*
|
||||
* @param pkNameList pk column name list
|
||||
* @param rowSize the row size of records
|
||||
* @param dbType the type of database
|
||||
* @param maxInSize the max in size
|
||||
* @return return where condition sql string.the sql can search all related records not just one.
|
||||
* @throws SQLException the sql exception
|
||||
*/
|
||||
public static String buildWhereConditionByPKs(List<String> pkNameList, int rowSize, String dbType, int maxInSize)
|
||||
throws SQLException {
|
||||
StringBuilder whereStr = new StringBuilder();
|
||||
//we must consider the situation of composite primary key
|
||||
int batchSize = rowSize % maxInSize == 0 ? rowSize / maxInSize : (rowSize / maxInSize) + 1;
|
||||
for (int batch = 0; batch < batchSize; batch++) {
|
||||
if (batch > 0) {
|
||||
whereStr.append(" or ");
|
||||
}
|
||||
whereStr.append("(");
|
||||
for (int i = 0; i < pkNameList.size(); i++) {
|
||||
if (i > 0) {
|
||||
whereStr.append(",");
|
||||
}
|
||||
whereStr.append(ColumnUtils.addEscape(pkNameList.get(i), dbType));
|
||||
}
|
||||
whereStr.append(") in ( ");
|
||||
|
||||
int eachSize = (batch == batchSize - 1) ? (rowSize % maxInSize == 0 ? maxInSize : rowSize % maxInSize)
|
||||
: maxInSize;
|
||||
for (int i = 0; i < eachSize; i++) {
|
||||
//each row is a bracket
|
||||
if (i > 0) {
|
||||
whereStr.append(",");
|
||||
}
|
||||
whereStr.append("(");
|
||||
for (int x = 0; x < pkNameList.size(); x++) {
|
||||
if (x > 0) {
|
||||
whereStr.append(",");
|
||||
}
|
||||
whereStr.append("?");
|
||||
}
|
||||
whereStr.append(")");
|
||||
}
|
||||
whereStr.append(" )");
|
||||
}
|
||||
|
||||
return whereStr.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* each pk is a condition.the result will like :" (id = ? and userCode = ?) or (id = ? and userCode = ?)"
|
||||
* Build where condition by pks string.
|
||||
*
|
||||
* @param pkNameList pk column name list
|
||||
* @param rowSize the row size of records
|
||||
* @param dbType the type of database
|
||||
* @param maxInSize the max in size
|
||||
* @return return where condition sql string.the sql can search all related records not just one.
|
||||
* @throws SQLException the sql exception
|
||||
*/
|
||||
public static String buildWhereConditionByPKsBySqlServer(List<String> pkNameList, int rowSize, String dbType, int maxInSize)
|
||||
throws SQLException {
|
||||
StringBuilder whereStr = new StringBuilder();
|
||||
//we must consider the situation of composite primary key
|
||||
for (int batch = 0; batch < rowSize; batch++) {
|
||||
if (batch > 0) {
|
||||
whereStr.append(" or ");
|
||||
}
|
||||
whereStr.append("(");
|
||||
for (int i = 0; i < pkNameList.size(); i++) {
|
||||
if (i > 0) {
|
||||
whereStr.append(" and ");
|
||||
}
|
||||
whereStr.append(ColumnUtils.addEscape(pkNameList.get(i), dbType));
|
||||
whereStr.append(" = ? ");
|
||||
}
|
||||
whereStr.append(")");
|
||||
}
|
||||
|
||||
return whereStr.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* set parameter for PreparedStatement, this is only used in pk sql.
|
||||
*
|
||||
* @param pkRowsList pkRowsList
|
||||
* @param pkColumnNameList pkColumnNameList
|
||||
* @param pst preparedStatement
|
||||
* @throws SQLException SQLException
|
||||
*/
|
||||
public static void setParamForPk(List<Map<String, Field>> pkRowsList, List<String> pkColumnNameList,
|
||||
PreparedStatement pst) throws SQLException {
|
||||
int paramIndex = 1;
|
||||
for (int i = 0; i < pkRowsList.size(); i++) {
|
||||
Map<String, Field> rowData = pkRowsList.get(i);
|
||||
for (String columnName : pkColumnNameList) {
|
||||
Field pkField = rowData.get(columnName);
|
||||
pst.setObject(paramIndex, pkField.getValue(), pkField.getType());
|
||||
paramIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* each pk is a condition.the result will like :" id =? and userCode =?"
|
||||
*
|
||||
* @param pkNameList pkNameList
|
||||
* @param dbType dbType
|
||||
* @return return where condition sql string.the sql can just search one related record.
|
||||
*/
|
||||
public static String buildWhereConditionByPKs(List<String> pkNameList, String dbType) {
|
||||
StringBuilder whereStr = new StringBuilder();
|
||||
//we must consider the situation of composite primary key
|
||||
for (int i = 0; i < pkNameList.size(); i++) {
|
||||
if (i > 0) {
|
||||
whereStr.append(" and ");
|
||||
}
|
||||
String pkName = pkNameList.get(i);
|
||||
whereStr.append(ColumnUtils.addEscape(pkName, dbType));
|
||||
whereStr.append(" = ? ");
|
||||
}
|
||||
return whereStr.toString();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user