feat():完善故障报警

master
Jiang Peng 2024-06-22 20:04:50 +08:00
parent fabd5e0d5e
commit 65494efb9c
21 changed files with 546 additions and 119 deletions

View File

@ -37,9 +37,9 @@ public class ManyDataSource {
DruidDataSourceFactory druidDataSourceFactory= SpringUtils.getBean(DruidDataSourceFactory.class); DruidDataSourceFactory druidDataSourceFactory= SpringUtils.getBean(DruidDataSourceFactory.class);
DynamicDataSource dynamicDataSource= SpringUtils.getBean(DynamicDataSource.class); DynamicDataSource dynamicDataSource= SpringUtils.getBean(DynamicDataSource.class);
EnterPriseInfo enterPriseInfo = EnterPriseInfo.builder() EnterPriseInfo enterPriseInfo = EnterPriseInfo.builder()
.entCode("jiang_0530") .entCode("jiang_15")
.ip("101.34.248.9") .ip("101.34.248.9")
.port(3308) .port(3321)
.build(); .build();
DataSourceInfo dataSourceInfo = DataSourceInfo.hostAndPortBuild(enterPriseInfo.getEntCode(), enterPriseInfo.getIp(), enterPriseInfo.getPort()); DataSourceInfo dataSourceInfo = DataSourceInfo.hostAndPortBuild(enterPriseInfo.getEntCode(), enterPriseInfo.getIp(), enterPriseInfo.getPort());
@ -53,9 +53,9 @@ public class ManyDataSource {
List<EnterPriseInfo> list = new ArrayList<>(); List<EnterPriseInfo> list = new ArrayList<>();
list.add( list.add(
EnterPriseInfo.builder() EnterPriseInfo.builder()
.entCode("jiang_0612") .entCode("jiang_14")
.ip("101.34.248.9") .ip("101.34.248.9")
.port(3309) .port(3320)
.build() .build()
); );
return list; return list;

View File

@ -7,7 +7,7 @@ package com.muyu.cloud.many.datasource.config.contents;
*/ */
public class DatasourceContent { public class DatasourceContent {
public final static String DATASOURCE_URL = "jdbc:mysql://{}:{}/etltest?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8"; public final static String DATASOURCE_URL = "jdbc:mysql://{}:{}/vehicle?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
public final static String USER_NAME = "root"; public final static String USER_NAME = "root";

View File

@ -1,53 +1,53 @@
package com.muyu.cloud.many.datasource.config.interceptor; //package com.muyu.cloud.many.datasource.config.interceptor;
//
import com.muyu.cloud.many.datasource.config.contents.SaaSConstant; //import com.muyu.cloud.many.datasource.config.contents.SaaSConstant;
import com.muyu.cloud.many.datasource.config.exception.SaaSException; //import com.muyu.cloud.many.datasource.config.exception.SaaSException;
import com.muyu.cloud.many.datasource.config.holder.DynamicDataSourceHolder; //import com.muyu.cloud.many.datasource.config.holder.DynamicDataSourceHolder;
import com.muyu.cloud.many.datasource.config.role.DynamicDataSource; //import com.muyu.cloud.many.datasource.config.role.DynamicDataSource;
import com.muyu.common.core.utils.ServletUtils; //import com.muyu.common.core.utils.ServletUtils;
import com.muyu.common.core.utils.SpringUtils; //import com.muyu.common.core.utils.SpringUtils;
import org.springframework.web.method.HandlerMethod; //import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor; //import org.springframework.web.servlet.AsyncHandlerInterceptor;
//
import javax.servlet.http.HttpServletRequest; //import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; //import javax.servlet.http.HttpServletResponse;
//
/** ///**
* SaaS SaaSInterceptor // * SaaS拦截器 SaaSInterceptor
* // *
* Date 2024/6/4 14:39 // * Date 2024/6/4 14:39
*/ // */
public class SaaSInterceptor implements AsyncHandlerInterceptor { //public class SaaSInterceptor implements AsyncHandlerInterceptor {
//
/** // /**
* // * 之前
*/ // */
@Override // @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)){ // if (!(handler instanceof HandlerMethod)){
return true; // return true;
} // }
//
String SaasKey = ServletUtils.getHeader(request, SaaSConstant.SAAS_KEY); // String SaasKey = ServletUtils.getHeader(request, SaaSConstant.SAAS_KEY);
//
if (SaasKey==null){ // if (SaasKey==null){
throw new SaaSException("SaaS非法访问"); // throw new SaaSException("SaaS非法访问");
} else { // } else {
DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class); // DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);
if (!dynamicDataSource.hashKye(SaasKey)){ // if (!dynamicDataSource.hashKye(SaasKey)){
throw new SaaSException("SaaS非法访问"); // throw new SaaSException("SaaS非法访问");
} // }
} // }
DynamicDataSourceHolder.setDynamicDataSourceKey(SaasKey); // DynamicDataSourceHolder.setDynamicDataSourceKey(SaasKey);
return true; // return true;
} // }
//
/** // /**
* // * 之后
*/ // */
@Override // @Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
DynamicDataSourceHolder.removeDynamicDataSourceKey(); // DynamicDataSourceHolder.removeDynamicDataSourceKey();
} // }
//
} //}

View File

@ -1,31 +1,31 @@
package com.muyu.cloud.many.datasource.config.interceptor; //package com.muyu.cloud.many.datasource.config.interceptor;
//
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; //import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; //import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//
/** ///**
* // * 拦截器配置
* // *
* @author muyu //// * @author muyua
*/ // */
public class WebMvcSaaSConfig implements WebMvcConfigurer { //public class WebMvcSaaSConfig implements WebMvcConfigurer {
/** // /**
* // * 不需要拦截地址
*/ // */
public static final String[] excludeUrls = {"/login", "/logout", "/refresh"}; // public static final String[] excludeUrls = {"/login", "/logout", "/refresh"};
//
@Override // @Override
public void addInterceptors (InterceptorRegistry registry) { // public void addInterceptors (InterceptorRegistry registry) {
registry.addInterceptor(getHeaderInterceptor()) // registry.addInterceptor(getHeaderInterceptor())
.addPathPatterns("/**") // .addPathPatterns("/**")
.excludePathPatterns(excludeUrls) // .excludePathPatterns(excludeUrls)
.order(-10); // .order(-10);
} // }
//
/** // /**
* // * 自定义请求头拦截器
*/ // */
public SaaSInterceptor getHeaderInterceptor () { // public SaaSInterceptor getHeaderInterceptor () {
return new SaaSInterceptor(); // return new SaaSInterceptor();
} // }
} //}

View File

@ -1 +1,3 @@
com.muyu.cloud.many.datasource.config.interceptor.WebMvcSaaSConfig com.muyu.cloud.many.datasource.config.domain.model.EnterPriseInfo
com.muyu.cloud.many.datasource.config.factory.DruidDataSourceFactory
com.muyu.cloud.many.datasource.config.ManyDataSource

View File

@ -94,11 +94,6 @@
<groupId>com.muyu</groupId> <groupId>com.muyu</groupId>
<artifactId>muyu-common-swagger</artifactId> <artifactId>muyu-common-swagger</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-amqp</artifactId>
<version>2.4.1</version>
</dependency>
</dependencies> </dependencies>

View File

@ -43,7 +43,7 @@ public class FaultCodeController extends BaseController {
* *
*/ */
@ApiOperation("获取车辆故障码列表") @ApiOperation("获取车辆故障码列表")
@RequiresPermissions("customerBusiness:faultCode:list")
@GetMapping("/list") @GetMapping("/list")
public Result<TableDataInfo<FaultCode>> list(FaultCodeQueryReq faultCodeQueryReq) { public Result<TableDataInfo<FaultCode>> list(FaultCodeQueryReq faultCodeQueryReq) {
startPage(); startPage();
@ -55,7 +55,6 @@ public class FaultCodeController extends BaseController {
* *
*/ */
@ApiOperation("导出车辆故障码列表") @ApiOperation("导出车辆故障码列表")
@RequiresPermissions("customerBusiness:faultCode:export")
@Log(title = "车辆故障码", businessType = BusinessType.EXPORT) @Log(title = "车辆故障码", businessType = BusinessType.EXPORT)
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, FaultCode faultCode) { public void export(HttpServletResponse response, FaultCode faultCode) {
@ -68,7 +67,6 @@ public class FaultCodeController extends BaseController {
* *
*/ */
@ApiOperation("获取车辆故障码详细信息") @ApiOperation("获取车辆故障码详细信息")
@RequiresPermissions("customerBusiness:faultCode:query")
@GetMapping(value = "/{id}") @GetMapping(value = "/{id}")
@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class) @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class)
public Result<FaultCode> getInfo(@PathVariable("id") Long id) { public Result<FaultCode> getInfo(@PathVariable("id") Long id) {
@ -78,7 +76,7 @@ public class FaultCodeController extends BaseController {
/** /**
* *
*/ */
@RequiresPermissions("customerBusiness:faultCode:add")
@Log(title = "车辆故障码", businessType = BusinessType.INSERT) @Log(title = "车辆故障码", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
@ApiOperation("新增车辆故障码") @ApiOperation("新增车辆故障码")
@ -89,7 +87,7 @@ public class FaultCodeController extends BaseController {
/** /**
* *
*/ */
@RequiresPermissions("customerBusiness:faultCode:edit")
@Log(title = "车辆故障码", businessType = BusinessType.UPDATE) @Log(title = "车辆故障码", businessType = BusinessType.UPDATE)
@PutMapping("/{id}") @PutMapping("/{id}")
@ApiOperation("修改车辆故障码") @ApiOperation("修改车辆故障码")
@ -100,7 +98,7 @@ public class FaultCodeController extends BaseController {
/** /**
* *
*/ */
@RequiresPermissions("customerBusiness:faultCode:remove")
@Log(title = "车辆故障码", businessType = BusinessType.DELETE) @Log(title = "车辆故障码", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
@ApiOperation("删除车辆故障码") @ApiOperation("删除车辆故障码")

View File

@ -40,7 +40,7 @@ public class FaultRecordController extends BaseController {
* *
*/ */
@ApiOperation("获取故障记录列表") @ApiOperation("获取故障记录列表")
@RequiresPermissions("customerBusiness:faultRecord:list") // @RequiresPermissions("customerBusiness:faultRecord:list")
@GetMapping("/list") @GetMapping("/list")
public Result<TableDataInfo<FaultRecord>> list(FaultRecordQueryReq faultRecordQueryReq) { public Result<TableDataInfo<FaultRecord>> list(FaultRecordQueryReq faultRecordQueryReq) {
startPage(); startPage();
@ -52,7 +52,7 @@ public class FaultRecordController extends BaseController {
* *
*/ */
@ApiOperation("导出故障记录列表") @ApiOperation("导出故障记录列表")
@RequiresPermissions("customerBusiness:faultRecord:export")
@Log(title = "故障记录", businessType = BusinessType.EXPORT) @Log(title = "故障记录", businessType = BusinessType.EXPORT)
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, FaultRecord faultRecord) { public void export(HttpServletResponse response, FaultRecord faultRecord) {
@ -65,7 +65,7 @@ public class FaultRecordController extends BaseController {
* *
*/ */
@ApiOperation("获取故障记录详细信息") @ApiOperation("获取故障记录详细信息")
@RequiresPermissions("customerBusiness:faultRecord:query")
@GetMapping(value = "/{id}") @GetMapping(value = "/{id}")
@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class) @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class)
public Result<FaultRecord> getInfo(@PathVariable("id") Long id) { public Result<FaultRecord> getInfo(@PathVariable("id") Long id) {
@ -75,7 +75,7 @@ public class FaultRecordController extends BaseController {
/** /**
* *
*/ */
@RequiresPermissions("customerBusiness:faultRecord:add")
@Log(title = "故障记录", businessType = BusinessType.INSERT) @Log(title = "故障记录", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
@ApiOperation("新增故障记录") @ApiOperation("新增故障记录")
@ -86,7 +86,7 @@ public class FaultRecordController extends BaseController {
/** /**
* *
*/ */
@RequiresPermissions("customerBusiness:faultRecord:edit")
@Log(title = "故障记录", businessType = BusinessType.UPDATE) @Log(title = "故障记录", businessType = BusinessType.UPDATE)
@PutMapping("/{id}") @PutMapping("/{id}")
@ApiOperation("修改故障记录") @ApiOperation("修改故障记录")
@ -97,7 +97,7 @@ public class FaultRecordController extends BaseController {
/** /**
* *
*/ */
@RequiresPermissions("customerBusiness:faultRecord:remove")
@Log(title = "故障记录", businessType = BusinessType.DELETE) @Log(title = "故障记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
@ApiOperation("删除故障记录") @ApiOperation("删除故障记录")

View File

@ -43,7 +43,7 @@ public class FenceController extends BaseController {
* *
*/ */
@ApiOperation("获取电子围栏列表") @ApiOperation("获取电子围栏列表")
@RequiresPermissions("customerBusiness:fence:list")
@GetMapping("/list") @GetMapping("/list")
public Result<TableDataInfo<Fence>> list(FenceQueryReq fenceQueryReq) { public Result<TableDataInfo<Fence>> list(FenceQueryReq fenceQueryReq) {
startPage(); startPage();
@ -55,7 +55,7 @@ public class FenceController extends BaseController {
* *
*/ */
@ApiOperation("导出电子围栏列表") @ApiOperation("导出电子围栏列表")
@RequiresPermissions("customerBusiness:fence:export")
@Log(title = "电子围栏", businessType = BusinessType.EXPORT) @Log(title = "电子围栏", businessType = BusinessType.EXPORT)
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, Fence fence) { public void export(HttpServletResponse response, Fence fence) {
@ -68,7 +68,6 @@ public class FenceController extends BaseController {
* *
*/ */
@ApiOperation("获取电子围栏详细信息") @ApiOperation("获取电子围栏详细信息")
@RequiresPermissions("customerBusiness:fence:query")
@GetMapping(value = "/{id}") @GetMapping(value = "/{id}")
@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class) @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class)
public Result<Fence> getInfo(@PathVariable("id") Long id) { public Result<Fence> getInfo(@PathVariable("id") Long id) {
@ -78,7 +77,7 @@ public class FenceController extends BaseController {
/** /**
* *
*/ */
@RequiresPermissions("customerBusiness:fence:add")
@Log(title = "电子围栏", businessType = BusinessType.INSERT) @Log(title = "电子围栏", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
@ApiOperation("新增电子围栏") @ApiOperation("新增电子围栏")
@ -89,7 +88,7 @@ public class FenceController extends BaseController {
/** /**
* *
*/ */
@RequiresPermissions("customerBusiness:fence:edit")
@Log(title = "电子围栏", businessType = BusinessType.UPDATE) @Log(title = "电子围栏", businessType = BusinessType.UPDATE)
@PutMapping("/{id}") @PutMapping("/{id}")
@ApiOperation("修改电子围栏") @ApiOperation("修改电子围栏")
@ -100,7 +99,7 @@ public class FenceController extends BaseController {
/** /**
* *
*/ */
@RequiresPermissions("customerBusiness:fence:remove")
@Log(title = "电子围栏", businessType = BusinessType.DELETE) @Log(title = "电子围栏", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
@ApiOperation("删除电子围栏") @ApiOperation("删除电子围栏")

View File

@ -48,7 +48,6 @@ public class VehicleController extends BaseController {
* *
*/ */
@ApiOperation("获取车辆录入列表") @ApiOperation("获取车辆录入列表")
@RequiresPermissions("customerBusiness:vehicle:list")
@GetMapping("/list") @GetMapping("/list")
public Result<TableDataInfo<Vehicle>> list(VehicleQueryReq vehicleQueryReq) { public Result<TableDataInfo<Vehicle>> list(VehicleQueryReq vehicleQueryReq) {
startPage(); startPage();
@ -60,7 +59,7 @@ public class VehicleController extends BaseController {
* *
*/ */
@ApiOperation("导出车辆录入列表") @ApiOperation("导出车辆录入列表")
@RequiresPermissions("customerBusiness:vehicle:export")
@Log(title = "车辆录入", businessType = BusinessType.EXPORT) @Log(title = "车辆录入", businessType = BusinessType.EXPORT)
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, Vehicle vehicle) { public void export(HttpServletResponse response, Vehicle vehicle) {
@ -73,7 +72,7 @@ public class VehicleController extends BaseController {
* *
*/ */
@ApiOperation("获取车辆录入详细信息") @ApiOperation("获取车辆录入详细信息")
@RequiresPermissions("customerBusiness:vehicle:query")
@GetMapping(value = "/{id}") @GetMapping(value = "/{id}")
@ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class) @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path", dataTypeClass = Long.class)
public Result<Vehicle> getInfo(@PathVariable("id") Long id) { public Result<Vehicle> getInfo(@PathVariable("id") Long id) {
@ -83,7 +82,7 @@ public class VehicleController extends BaseController {
/** /**
* *
*/ */
@RequiresPermissions("customerBusiness:vehicle:add")
@Log(title = "车辆录入", businessType = BusinessType.INSERT) @Log(title = "车辆录入", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
@ApiOperation("新增车辆录入") @ApiOperation("新增车辆录入")
@ -94,7 +93,7 @@ public class VehicleController extends BaseController {
/** /**
* *
*/ */
@RequiresPermissions("customerBusiness:vehicle:edit")
@Log(title = "车辆录入", businessType = BusinessType.UPDATE) @Log(title = "车辆录入", businessType = BusinessType.UPDATE)
@PutMapping("/{id}") @PutMapping("/{id}")
@ApiOperation("修改车辆录入") @ApiOperation("修改车辆录入")
@ -105,7 +104,7 @@ public class VehicleController extends BaseController {
/** /**
* *
*/ */
@RequiresPermissions("customerBusiness:vehicle:remove")
@Log(title = "车辆录入", businessType = BusinessType.DELETE) @Log(title = "车辆录入", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
@ApiOperation("删除车辆录入") @ApiOperation("删除车辆录入")

View File

@ -0,0 +1,15 @@
package com.muyu.customer.business.saas.contents;
/**
* @author DongZl
* @description:
* @Date 2023-8-1 11:02
*/
public class DatasourceContent {
public final static String DATASOURCE_URL = "jdbc:mysql://{}:{}/vehicle_networking?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
public final static String USER_NAME = "root";
public final static String PASSWORD = "L041120D";
}

View File

@ -0,0 +1,12 @@
package com.muyu.customer.business.saas.contents;
/**
* SaaS SaaSConstant
*
* @author DeKangLiu
* Date 2024/6/4 18:34
*/
public class SaaSConstant {
public final static String SAAS_KEY="enterprise-code";
}

View File

@ -0,0 +1,121 @@
package com.muyu.customer.business.saas.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSON;
import com.muyu.common.core.utils.SpringUtils;
import com.muyu.common.redis.service.RedisService;
import com.muyu.customer.business.saas.domain.model.EnterPriseInfo;
import com.muyu.customer.business.saas.factory.DruidDataSourceFactory;
import com.muyu.customer.business.saas.domain.model.DataSourceInfo;
import com.muyu.customer.business.saas.role.DynamicDataSource;
import com.rabbitmq.client.Channel;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.*;
/**
* ManyDataSource
*
* @author DeKangLiu
* Date 2024/6/3 20:01
*/
@Component
@Log4j2
@AutoConfigureBefore(RedisService.class)
public class ManyDataSource {
@Autowired
private RedisTemplate<String,String> redisTemplate;
// @Autowired
// private RemoteBusinessService remoteBusinessService;
@Autowired
private RabbitTemplate rabbitTemplate;
@RabbitListener(queuesToDeclare = {@Queue(name = "smsConfig")})
public void smsConfig(String msg, Message message, Channel channel){
//获取消息的ID
String messageId = message.getMessageProperties().getMessageId();
try {
//添加消息id到redis set集合中 添加成功返回1 表示未消费 添加失败返回0 表示已消费
Long count = redisTemplate.opsForSet().add("messageId", messageId);
//添加成功 正常消费信息
if (count == 1) {
log.info("开始消费");
druidData(msg);
//确认消费
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
log.info("消费成功");
}
} catch (Exception e) {
log.info("消费失败,尝试重连");
try {
//回退消息,尝试重连
druidData(msg);
channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
log.info("消费失败");
} catch (IOException ex) {
//回退失败
log.info("消费异常");
}
}
}
private void druidData(String msg) {
EnterPriseInfo entInfo= JSON.parseObject(msg, EnterPriseInfo.class);
log.info("消息为:{}",entInfo);
DruidDataSourceFactory druidDataSourceFactory = SpringUtils.getBean(DruidDataSourceFactory.class);
DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);
DataSourceInfo dataSourceInfo = DataSourceInfo.hostAndPortBuild(entInfo.getEntCode(), entInfo.getIp(), entInfo.getPort());
DruidDataSource druidDataSource = druidDataSourceFactory.create(dataSourceInfo);
dynamicDataSource.put(dataSourceInfo.getKey(), druidDataSource);
}
@Lazy
private List<EnterPriseInfo> dataSourceInfoList(){
List<EnterPriseInfo> list = new ArrayList<>();
list.add(
EnterPriseInfo.builder()
.entCode("jiang_14")
.ip("101.34.248.9")
.port(3320)
.build()
);
return list;
}
@Bean
@Primary
public DynamicDataSource dynamicDataSource(DruidDataSourceFactory druidDataSourceFactory) {
//企业列表 企业CODE 端口 ip
Map<Object, Object> dataSourceMap = new HashMap<>();
dataSourceInfoList()
.stream()
.map(enterPriseInfo -> DataSourceInfo.hostAndPortBuild(enterPriseInfo.getEntCode(), enterPriseInfo.getIp(),enterPriseInfo.getPort()))
.forEach(dataSourceInfo -> {
dataSourceMap.put(dataSourceInfo.getKey(), druidDataSourceFactory.create(dataSourceInfo));
});
//设置动态数据源
DynamicDataSource dynamicDataSource = new DynamicDataSource();
// dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
dynamicDataSource.setTargetDataSources(dataSourceMap);
//将数据源信息备份在defineTargetDataSources中
dynamicDataSource.setDefineTargetDataSources(dataSourceMap);
return dynamicDataSource;
}
}

View File

@ -0,0 +1,52 @@
package com.muyu.customer.business.saas.domain.model;
import com.muyu.common.core.utils.StringUtils;
import com.muyu.customer.business.saas.contents.DatasourceContent;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author DongZl
* @description:
* @Date 2023-8-1 11:15
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DataSourceInfo {
/**
*
*/
private String key;
/**
*
*/
private String url;
/**
*
*/
private String userName;
/**
*
*/
private String password;
public static DataSourceInfo hostAndPortBuild(String key,String host, Integer port){
return DataSourceInfo.builder()
.key(key)
.url(StringUtils.format(DatasourceContent.DATASOURCE_URL, host, port,port))
.password(DatasourceContent.PASSWORD)
.userName(DatasourceContent.USER_NAME)
.build();
}
}

View File

@ -0,0 +1,25 @@
package com.muyu.customer.business.saas.domain.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* EnterPriseInfo
*
* @author DeKangLiu
* Date 2024/6/4 08:53
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EnterPriseInfo {
private String entCode;
private String ip;
private Integer port;
}

View File

@ -0,0 +1,26 @@
package com.muyu.customer.business.saas.exception;
import com.muyu.common.core.exception.ServiceException;
/**
* SaaS SaaSException
*
* @author DeKangLiu
* Date 2024/6/4 18:45
*/
public class SaaSException extends ServiceException {
public SaaSException(String message, Integer code) {
super(message, code);
}
public SaaSException(String message) {
super(message);
}
public SaaSException() {
super();
}
}

View File

@ -0,0 +1,39 @@
package com.muyu.customer.business.saas.factory;
import com.alibaba.druid.pool.DruidDataSource;
import com.muyu.customer.business.saas.domain.model.DataSourceInfo;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;
import java.sql.SQLException;
/**
* Druid DruidDataSourceFactory
*
* @author DeKangLiu
* Date 2024/6/3 20:12
*/
@Log4j2
@Component
public class DruidDataSourceFactory {
/**
* @Description:
* @Author Dongzl
*/
public DruidDataSource create(DataSourceInfo dataSourceInfo) {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl(dataSourceInfo.getUrl());
druidDataSource.setUsername(dataSourceInfo.getUserName());
druidDataSource.setPassword(dataSourceInfo.getPassword());
druidDataSource.setBreakAfterAcquireFailure(true);
druidDataSource.setConnectionErrorRetryAttempts(0);
try {
druidDataSource.getConnection(2000);
log.info("{} -> 数据源连接成功", dataSourceInfo.getKey());
return druidDataSource;
} catch (SQLException throwables) {
log.error("数据源 {} 连接失败,用户名:{},密码 {}",dataSourceInfo.getUrl(),dataSourceInfo.getUserName(),dataSourceInfo.getPassword());
return null;
}
}
}

View File

@ -0,0 +1,42 @@
package com.muyu.customer.business.saas.holder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
/**
*
*
* @author Dongzl
*/
@Slf4j
public class DynamicDataSourceHolder {
/**
*
*/
private static final ThreadLocal<String> DYNAMIC_DATASOURCE_KEY = new ThreadLocal<>();
/**
* /线使
*/
public static void setDynamicDataSourceKey(String key){
log.info("数据源切换为:{}",key);
DYNAMIC_DATASOURCE_KEY.set(key);
}
/**
* 使mater
*/
public static String getDynamicDataSourceKey(){
String key = DYNAMIC_DATASOURCE_KEY.get();
Assert.notNull(key, "请携带数据标识");
return key;
}
/**
*
*/
public static void removeDynamicDataSourceKey(){
log.info("移除数据源:{}",DYNAMIC_DATASOURCE_KEY.get());
DYNAMIC_DATASOURCE_KEY.remove();
}
}

View File

@ -0,0 +1,49 @@
package com.muyu.customer.business.saas.role;
import com.muyu.common.security.utils.SecurityUtils;
import com.muyu.common.system.domain.SysUser;
import com.muyu.common.system.remote.RemoteUserService;
import com.muyu.customer.business.saas.holder.DynamicDataSourceHolder;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
* BingRui.Hou
*
*
*/
@Aspect
@Component
public class DataSourceAsp {
@Lazy
@Autowired
private RemoteUserService remoteUserService;
@Pointcut(value = "execution(public * com.muyu.customer.business.controller.*Controller.*(..))")
public void pointcut () {
}
/**
*
*/
@Before("pointcut()")
public void beforeMethod() {
DynamicDataSourceHolder.setDynamicDataSourceKey("jiang"+14);
}
/**
*
*
*
*/
@After("pointcut()")
public void afterMethod() {
DynamicDataSourceHolder.removeDynamicDataSourceKey();
}
}

View File

@ -0,0 +1,52 @@
package com.muyu.customer.business.saas.role;
import com.alibaba.druid.pool.DruidDataSource;
import com.muyu.customer.business.saas.holder.DynamicDataSourceHolder;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import java.util.Map;
/**
*
* AddDefineDataSourceaddDefineDynamicDataSourcetargetdatasourcesmapmaptargetdatasourcesmap
* 使@DataSource(value = "数据源名称")DynamicDataSourceContextHolder.setContextKey("数据源名称")
* @author Dongzl
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DynamicDataSource extends AbstractRoutingDataSource {
//备份所有数据源信息,备份的是个 指针!!!
private Map<Object, Object> defineTargetDataSources;
/**
*
* @param key
* @return true false
*/
public boolean hashKye(String key){
return defineTargetDataSources.containsKey(key);
}
/**
*
* @param key
* @param value
*/
public void put(String key, DruidDataSource value){
defineTargetDataSources.put(key,value);
this.afterPropertiesSet();
}
/**
* 线使
*/
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceHolder.getDynamicDataSourceKey();
}
}

View File

@ -17,6 +17,7 @@ spring:
publisher-returns: true publisher-returns: true
main: main:
allow-circular-references: true allow-circular-references: true
allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册
application: application:
# 应用名称 # 应用名称
name: muyu-customer-business name: muyu-customer-business