♻️ Refactoring code. 优化动态路由避免更新数据影响范围过大
This commit is contained in:
1 parent
cb4f51facc
commit
90f31d178f
4 files changed
+75
-95
No files matched your search
@@ -511,6 +511,7 @@ INSERT INTO `sys_menu` VALUES (2905, '导入导出', 'sys_i18n_export', NULL, 29
|
||||
INSERT INTO `sys_menu` VALUES (2906, '文件管理', NULL, '/admin/file/index', 2000, 'ele-Files', '1', 6, '0', NULL, '0', '', '2019-06-25 12:44:46', 'admin', '2023-02-16 15:24:42', '0', 1);
|
||||
INSERT INTO `sys_menu` VALUES (2907, '删除文件', 'sys_file_del', NULL, 2906, NULL, '1', 1, '0', NULL, '1', ' ', '2019-06-25 13:41:41', ' ', '2020-03-24 08:58:42', '0', 1);
|
||||
INSERT INTO `sys_menu` VALUES (2908, '路由管理', NULL, '/ext/route', 2000, 'iconfont icon-diqiu1', '1', 12, '0', NULL, '0', '', '2019-06-25 12:44:46', 'admin', '2023-02-16 15:24:42', '0', 1);
|
||||
INSERT INTO `sys_menu` VALUES (2909, '路由配置', 'sys_route_manage', NULL, 2908, NULL, '1', 1, '0', NULL, '1', ' ', '2019-06-25 13:41:41', ' ', '2020-03-24 08:58:42', '0', 1);
|
||||
INSERT INTO `sys_menu` VALUES (3000, '公众号平台', NULL, '/mp', -1, 'iconfont icon-zhongyingzhuanhuan', '1', 10, '0', '0', '0', 'admin', '2023-02-24 10:40:44', 'admin', '2023-03-06 10:05:21', '0', 1);
|
||||
INSERT INTO `sys_menu` VALUES (3001, '账号管理', NULL, '/mp/wx-account/index', 3000, 'iconfont icon-putong', '1', 0, '0', '0', '0', 'admin', '2023-02-24 10:43:03', ' ', NULL, '0', 1);
|
||||
INSERT INTO `sys_menu` VALUES (3002, '菜单设置', NULL, '/mp/wx-menu/index', 3000, 'iconfont icon--chaifenlie', '1', 1, '0', '0', '0', 'admin', '2023-02-24 11:16:32', 'admin', '2023-03-11 16:28:56', '0', 1);
|
||||
|
||||
+20
-10
@@ -17,7 +17,10 @@
|
||||
|
||||
package com.pig4cloud.pigx.admin.controller;
|
||||
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysRouteConf;
|
||||
import com.pig4cloud.pigx.admin.service.SysRouteConfService;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.log.annotation.SysLog;
|
||||
@@ -47,19 +50,26 @@ public class SysRouteConfController {
|
||||
* @return
|
||||
*/
|
||||
@GetMapping
|
||||
public R listRoutes() {
|
||||
return R.ok(sysRouteConfService.list());
|
||||
public R listRoutes(@RequestParam(required = false) String routeId) {
|
||||
return R.ok(sysRouteConfService.list(Wrappers.<SysRouteConf>lambdaQuery()
|
||||
.eq(StrUtil.isNotBlank(routeId), SysRouteConf::getRouteId, routeId)));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{routeId}")
|
||||
public R deleteRoute(@PathVariable String routeId) {
|
||||
return R
|
||||
.ok(sysRouteConfService.remove(Wrappers.<SysRouteConf>lambdaQuery().eq(SysRouteConf::getRouteId, routeId)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改路由
|
||||
* @param routes 路由定义
|
||||
* @return
|
||||
* 新增修改路由
|
||||
* @param route 路由定义
|
||||
* @return success
|
||||
*/
|
||||
@SysLog("修改路由")
|
||||
@PutMapping
|
||||
public R updateRoutes(@RequestBody JSONArray routes) {
|
||||
return R.ok(sysRouteConfService.updateRoutes(routes));
|
||||
@SysLog("新增修改路由")
|
||||
@PostMapping
|
||||
public R addOrUpdateRoute(@RequestBody JSONObject route) {
|
||||
return R.ok(sysRouteConfService.addOrUpdateRoute(route));
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -17,7 +17,7 @@
|
||||
|
||||
package com.pig4cloud.pigx.admin.service;
|
||||
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysRouteConf;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -32,9 +32,9 @@ public interface SysRouteConfService extends IService<SysRouteConf> {
|
||||
|
||||
/**
|
||||
* 更新路由信息
|
||||
* @param routes 路由信息
|
||||
* @param route 路由信息
|
||||
* @return
|
||||
*/
|
||||
Mono<Void> updateRoutes(JSONArray routes);
|
||||
Mono<Void> addOrUpdateRoute(JSONObject route);
|
||||
|
||||
}
|
||||
+51
-82
@@ -17,15 +17,15 @@
|
||||
|
||||
package com.pig4cloud.pigx.admin.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysRouteConf;
|
||||
import com.pig4cloud.pigx.admin.mapper.SysRouteConfMapper;
|
||||
import com.pig4cloud.pigx.admin.service.SysRouteConfService;
|
||||
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.gateway.support.DynamicRouteInitEvent;
|
||||
import com.pig4cloud.pigx.common.gateway.vo.RouteDefinitionVo;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -33,17 +33,13 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.gateway.filter.FilterDefinition;
|
||||
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
@@ -57,107 +53,80 @@ import java.util.stream.Collectors;
|
||||
public class SysRouteConfServiceImpl extends ServiceImpl<SysRouteConfMapper, SysRouteConf>
|
||||
implements SysRouteConfService {
|
||||
|
||||
private final RedisTemplate redisTemplate;
|
||||
|
||||
private final ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
/**
|
||||
* 更新路由信息
|
||||
* @param routes 路由信息
|
||||
* @param route 路由信息
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Mono<Void> updateRoutes(JSONArray routes) {
|
||||
// 清空Redis 缓存
|
||||
Boolean result = redisTemplate.delete(CacheConstants.ROUTE_KEY);
|
||||
log.info("清空网关路由 {} ", result);
|
||||
|
||||
// 遍历修改的routes,保存到Redis
|
||||
List<RouteDefinitionVo> routeDefinitionVoList = new ArrayList<>();
|
||||
|
||||
public Mono<Void> addOrUpdateRoute(JSONObject route) {
|
||||
try {
|
||||
routes.forEach(value -> {
|
||||
log.info("更新路由 ->{}", value);
|
||||
RouteDefinitionVo vo = new RouteDefinitionVo();
|
||||
Map<String, Object> map = (Map) value;
|
||||
log.info("更新路由 ->{}", route);
|
||||
RouteDefinitionVo vo = new RouteDefinitionVo();
|
||||
|
||||
Object id = map.get("routeId");
|
||||
if (id != null) {
|
||||
vo.setId(String.valueOf(id));
|
||||
}
|
||||
String id = route.getStr("routeId");
|
||||
if (StrUtil.isNotBlank(id)) {
|
||||
vo.setId(id);
|
||||
}
|
||||
|
||||
Object routeName = map.get("routeName");
|
||||
if (routeName != null) {
|
||||
vo.setRouteName(String.valueOf(routeName));
|
||||
}
|
||||
String routeName = route.getStr("routeName");
|
||||
if (StrUtil.isNotBlank(routeName)) {
|
||||
vo.setRouteName(routeName);
|
||||
}
|
||||
|
||||
Object predicates = map.get("predicates");
|
||||
if (predicates != null) {
|
||||
JSONArray predicatesArray = (JSONArray) predicates;
|
||||
List<PredicateDefinition> predicateDefinitionList = predicatesArray
|
||||
.toList(PredicateDefinition.class);
|
||||
vo.setPredicates(predicateDefinitionList);
|
||||
}
|
||||
JSONArray predicates = route.getJSONArray("predicates");
|
||||
if (predicates != null) {
|
||||
List<PredicateDefinition> predicateDefinitionList = predicates.toList(PredicateDefinition.class);
|
||||
vo.setPredicates(predicateDefinitionList);
|
||||
}
|
||||
|
||||
Object filters = map.get("filters");
|
||||
if (filters != null) {
|
||||
JSONArray filtersArray = (JSONArray) filters;
|
||||
List<FilterDefinition> filterDefinitionList = filtersArray.toList(FilterDefinition.class);
|
||||
vo.setFilters(filterDefinitionList);
|
||||
}
|
||||
JSONArray filters = route.getJSONArray("filters");
|
||||
if (filters != null) {
|
||||
List<FilterDefinition> filterDefinitionList = filters.toList(FilterDefinition.class);
|
||||
vo.setFilters(filterDefinitionList);
|
||||
}
|
||||
|
||||
Object uri = map.get("uri");
|
||||
if (uri != null) {
|
||||
vo.setUri(URI.create(String.valueOf(uri)));
|
||||
}
|
||||
Object uri = route.getStr("uri");
|
||||
if (uri != null) {
|
||||
vo.setUri(URI.create(String.valueOf(uri)));
|
||||
}
|
||||
|
||||
Object order = map.get("order");
|
||||
if (order != null) {
|
||||
vo.setOrder(Integer.parseInt(String.valueOf(order)));
|
||||
}
|
||||
Integer order = route.getInt("order");
|
||||
if (order != null) {
|
||||
vo.setOrder(order);
|
||||
}
|
||||
|
||||
Object metadata = map.get("metadata");
|
||||
if (metadata != null) {
|
||||
Map<String, Object> metadataMap = JSONUtil.toBean(String.valueOf(metadata), Map.class);
|
||||
vo.setMetadata(metadataMap);
|
||||
}
|
||||
Map<String, Object> metadataMap = route.getBean("metadata", Map.class);
|
||||
if (metadataMap != null) {
|
||||
vo.setMetadata(metadataMap);
|
||||
}
|
||||
|
||||
redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(RouteDefinitionVo.class));
|
||||
redisTemplate.opsForHash().put(CacheConstants.ROUTE_KEY, vo.getId(), vo);
|
||||
routeDefinitionVoList.add(vo);
|
||||
});
|
||||
|
||||
// 逻辑删除全部
|
||||
SysRouteConf condition = new SysRouteConf();
|
||||
condition.setDelFlag(CommonConstants.STATUS_NORMAL);
|
||||
this.remove(new UpdateWrapper<>(condition));
|
||||
// 逻辑删除 ,不直接更新避免危险!
|
||||
this.remove(Wrappers.<SysRouteConf>lambdaQuery().eq(SysRouteConf::getRouteId, id));
|
||||
|
||||
// 插入生效路由
|
||||
List<SysRouteConf> routeConfList = routeDefinitionVoList.stream().map(vo -> {
|
||||
SysRouteConf routeConf = new SysRouteConf();
|
||||
routeConf.setRouteId(vo.getId());
|
||||
routeConf.setRouteName(vo.getRouteName());
|
||||
routeConf.setFilters(JSONUtil.toJsonStr(vo.getFilters()));
|
||||
routeConf.setPredicates(JSONUtil.toJsonStr(vo.getPredicates()));
|
||||
routeConf.setSortOrder(vo.getOrder());
|
||||
routeConf.setUri(vo.getUri().toString());
|
||||
routeConf.setMetadata(JSONUtil.toJsonStr(vo.getMetadata()));
|
||||
return routeConf;
|
||||
}).collect(Collectors.toList());
|
||||
this.saveBatch(routeConfList);
|
||||
SysRouteConf routeConf = new SysRouteConf();
|
||||
routeConf.setRouteId(vo.getId());
|
||||
routeConf.setRouteName(vo.getRouteName());
|
||||
routeConf.setFilters(JSONUtil.toJsonStr(vo.getFilters()));
|
||||
routeConf.setPredicates(JSONUtil.toJsonStr(vo.getPredicates()));
|
||||
routeConf.setSortOrder(vo.getOrder());
|
||||
routeConf.setUri(vo.getUri().toString());
|
||||
routeConf.setMetadata(JSONUtil.toJsonStr(vo.getMetadata()));
|
||||
this.save(routeConf);
|
||||
log.debug("更新网关路由结束 ");
|
||||
|
||||
// 通知网关重置路由
|
||||
redisTemplate.convertAndSend(CacheConstants.ROUTE_JVM_RELOAD_TOPIC, "路由信息,网关缓存更新");
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("路由配置解析失败", e);
|
||||
// 回滚路由,重新加载即可
|
||||
this.applicationEventPublisher.publishEvent(new DynamicRouteInitEvent(this));
|
||||
// 抛出异常
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
finally {
|
||||
this.applicationEventPublisher.publishEvent(new DynamicRouteInitEvent(this));
|
||||
}
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user