Commit 5e3df5c7 by tangyi

优化网关

parent 9ca661d9
Version v3.0.0 (2019-7-15)
--------------------------
改进:
* 优化优化网关的动态路由
* 学生增加城市id、县id
Version v3.0.0 (2019-7-6)
--------------------------
改进:
......
......@@ -4,6 +4,7 @@ import com.github.tangyi.common.core.constant.CommonConstant;
import com.github.tangyi.common.core.properties.SysProperties;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
......@@ -25,6 +26,7 @@ public class AppStartupRunner implements CommandLineRunner {
log.info("start command line...");
log.info("set system properties...");
// 设置系统属性
System.setProperty(CommonConstant.CACHE_EXPIRE, sysProperties.getCacheExpire());
if (StringUtils.isNotBlank(sysProperties.getCacheExpire()))
System.setProperty(CommonConstant.CACHE_EXPIRE, sysProperties.getCacheExpire());
}
}
......@@ -7,21 +7,6 @@ package com.github.tangyi.common.core.constant;
public class MqConstant {
/**
* 修改路由
*/
public static final String EDIT_GATEWAY_ROUTE_QUEUE = "edit_gateway_route_queue";
/**
* 删除路由
*/
public static final String DEL_GATEWAY_ROUTE_QUEUE = "del_gateway_route_queue";
/**
* 刷新路由
*/
public static final String REFRESH_GATEWAY_ROUTE_QUEUE = "refresh_gateway_route_queue";
/**
* 提交考试
*/
public static final String SUBMIT_EXAMINATION_QUEUE = "submit_examination_queue";
......
server:
port: 8000
spring:
datasource:
url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/microservice-gateway?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=CTT&characterEncoding=UTF-8
username: ${MYSQL_USERNAME:root}
password: ${MYSQL_PASSWORD:11}
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
redis:
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
......@@ -28,6 +34,21 @@ spring:
zipkin:
base-url: http://${ZIPKIN_HOST:localhost}:${ZIPKIN_PORT:9411} # 指定了Zipkin服务器的地址
# mybatis配置
mybatis:
type-aliases-package: com.github.tangyi.gateway.module
configuration:
# 驼峰转换
map-underscore-to-camel-case: true
# 延迟加载
lazy-loading-enabled: true
mapper-locations: classpath:mapper/*.xml
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
# 系统配置
sys:
adminUser: ${ADMIN_USER:admin} # 管理员账号,默认是admin
......
/*
Navicat Premium Data Transfer
Source Server : mysql_localhost
Source Server Type : MySQL
Source Server Version : 50617
Source Host : localhost:3306
Source Schema : microservice-gateway
Target Server Type : MySQL
Target Server Version : 50617
File Encoding : 65001
Date: 15/07/2019 21:39:26
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for sys_route
-- ----------------------------
DROP TABLE IF EXISTS `sys_route`;
CREATE TABLE `sys_route` (
`id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`route_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '路由ID',
`route_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '路由名称',
`predicates` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '断言',
`filters` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '过滤器',
`uri` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'URI',
`sort` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '排序',
`status` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '启用禁用',
`creator` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`create_date` timestamp(0) NULL DEFAULT NULL COMMENT '创建时间',
`modifier` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '修改人',
`modify_date` timestamp(0) NULL DEFAULT NULL COMMENT '修改时间',
`del_flag` int(11) NULL DEFAULT NULL COMMENT '删除标记',
`application_code` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '系统编号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_route
-- ----------------------------
INSERT INTO `sys_route` VALUES ('0f1aec35a545433c8cc0c8e78995f039', 'auth-service', '认证授权服务', '[\n {\n \"name\": \"Path\",\n \"args\": {\n \"_genkey_0\": \"/api/auth/**\"\n }\n }\n]', '[\n {\n \"name\": \"StripPrefix\",\n \"args\": {\n \"_genkey_0\": \"2\"\n }\n },\n {\n \"name\": \"RemoveRequestHeader\",\n \"args\": {\n \"_genkey_0\": \"Cookie\",\n \"_genkey_1\": \"Set-Cookie\"\n }\n }\n]', 'lb://auth-service', '0', '0', 'admin', '2019-04-07 11:20:55', 'admin', '2019-04-26 22:45:28', 0, 'EXAM');
INSERT INTO `sys_route` VALUES ('5d9dd5f2cb1147aaad6f8b82a58586e8', 'exam-service', '考试服务', '[\n {\n \"name\": \"Path\",\n \"args\": {\n \"_genkey_0\": \"/api/exam/**\"\n }\n }\n]', '[\n {\n \"name\": \"StripPrefix\",\n \"args\": {\n \"_genkey_0\": \"2\"\n }\n },\n {\n \"name\": \"RemoveRequestHeader\",\n \"args\": {\n \"_genkey_0\": \"Cookie\",\n \"_genkey_1\": \"Set-Cookie\"\n }\n }\n]', 'lb://exam-service', '0', '0', 'admin', '2019-04-02 21:39:30', 'admin', '2019-04-26 22:45:30', 0, 'EXAM');
INSERT INTO `sys_route` VALUES ('e9199257e8dc4f2d8fbb2a113c407eca', 'user-service', '用户服务', '[\n {\n \"name\": \"Path\",\n \"args\": {\n \"_genkey_0\": \"/api/user/**\"\n }\n }\n]', '[\n {\n \"name\": \"StripPrefix\",\n \"args\": {\n \"_genkey_0\": \"2\"\n }\n },\n {\n \"name\": \"RemoveRequestHeader\",\n \"args\": {\n \"_genkey_0\": \"Cookie\",\n \"_genkey_1\": \"Set-Cookie\"\n }\n }\n]', 'lb://user-service', '0', '0', 'admin', '2019-04-07 11:22:05', 'admin', '2019-06-07 21:48:45', 0, 'EXAM');
SET FOREIGN_KEY_CHECKS = 1;
......@@ -35,6 +35,18 @@
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!--MySQL-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
......
......@@ -3,13 +3,12 @@ package com.github.tangyi.gateway;
import com.github.tangyi.gateway.annotation.EnableGatewayTokenTransfer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
@EnableDiscoveryClient
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@SpringBootApplication
@ComponentScan(basePackages = {"com.github.tangyi"})
@EnableCircuitBreaker
@EnableGatewayTokenTransfer
......
package com.github.tangyi.gateway.config;
import com.github.tangyi.common.core.constant.MqConstant;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* RabbitMq配置
*
* @author tangyi
* @date 2019/4/2 17:56
*/
@Configuration
public class RabbitConfig {
/**
* 修改路由
*
* @return Queue
*/
@Bean
public Queue editQueue() {
return new Queue(MqConstant.EDIT_GATEWAY_ROUTE_QUEUE);
}
/**
* 删除路由
*
* @return Queue
*/
@Bean
public Queue delQueue() {
return new Queue(MqConstant.DEL_GATEWAY_ROUTE_QUEUE);
}
/**
* 刷新路由
*
* @return Queue
*/
@Bean
public Queue refreshQueue() {
return new Queue(MqConstant.REFRESH_GATEWAY_ROUTE_QUEUE);
}
}
package com.github.tangyi.gateway.config;
import com.github.tangyi.common.core.constant.CommonConstant;
import com.github.tangyi.common.core.model.Route;
import com.github.tangyi.gateway.module.Route;
import com.github.tangyi.common.core.utils.JsonMapper;
import com.github.tangyi.common.core.vo.RoutePredicateVo;
import com.github.tangyi.gateway.vo.RoutePredicateVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
......
package com.github.tangyi.gateway.config;
import com.github.tangyi.common.core.constant.CommonConstant;
import com.github.tangyi.common.core.model.Route;
import com.github.tangyi.common.core.utils.JsonMapper;
import com.github.tangyi.gateway.receiver.GatewayRouteReceiver;
import com.github.tangyi.gateway.service.RouteService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
/**
* 动态路由实现:修改数据库路由配置,用户服务发送路由更新消息,网关消费消息,更新路由配置
* 依赖Redis,如果Redis被清空,需要手动刷新加载路由列表
* 初始化的时候加载路由数据
*
* @author tangyi
* @date 2019/4/2 14:40
......@@ -26,21 +18,10 @@ import java.util.List;
@Configuration
public class RouteInitConfig {
private final RedisTemplate redisTemplate;
private final GatewayRouteReceiver gatewayRouteReceiver;
private final RouteService routeService;
@PostConstruct
public void initRoute() {
// 重Redis加载路由列表
Object object = redisTemplate.opsForValue().get(CommonConstant.ROUTE_KEY);
if (object != null) {
List<Route> routes = JsonMapper.getInstance().fromJson(object.toString(), JsonMapper.getInstance().createCollectionType(ArrayList.class, Route.class));
if (CollectionUtils.isNotEmpty(routes)) {
log.info("加载{}条路由记录", routes.size());
for (Route route : routes)
gatewayRouteReceiver.editRoute(route);
}
}
routeService.refresh();
}
}
......@@ -51,4 +51,14 @@ public class GatewayConstant {
*/
public static final String GATEWAY_REFRESH_TOKENS = "gateway_refresh:";
/**
* 默认系统编号
*/
public static final String SYS_CODE = "EXAM";
/**
* 默认租户编号
*/
public static final String DEFAULT_TENANT_CODE = "gitee";
}
package com.github.tangyi.gateway.controller;
import com.github.tangyi.common.core.constant.MqConstant;
import com.github.tangyi.common.core.model.ResponseBean;
import com.github.tangyi.common.core.vo.RouteFilterVo;
import com.github.tangyi.common.core.vo.RoutePredicateVo;
import com.github.tangyi.common.core.vo.RouteVo;
import com.github.tangyi.gateway.service.DynamicRouteService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 动态路由Controller
*
* @author tangyi
* @date 2019/3/27 10:59
*/
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/api/route")
public class GatewayRouteController {
private final RouteDefinitionLocator routeDefinitionLocator;
private final RouteLocator routeLocator;
private final DynamicRouteService dynamicRouteService;
private final AmqpTemplate amqpTemplate;
/**
* 获取路由信息列表
*
* @return Mono
*/
@GetMapping("routeList")
public Mono<List<Map<String, Object>>> routes() {
Mono<Map<String, RouteDefinition>> routeDefs = this.routeDefinitionLocator
.getRouteDefinitions().collectMap(RouteDefinition::getId);
Mono<List<Route>> routes = this.routeLocator.getRoutes().collectList();
return Mono.zip(routeDefs, routes).map(tuple -> {
Map<String, RouteDefinition> defs = tuple.getT1();
List<Route> routeList = tuple.getT2();
List<Map<String, Object>> allRoutes = new ArrayList<>();
routeList.forEach(route -> {
HashMap<String, Object> r = new HashMap<>();
r.put("route_id", route.getId());
r.put("order", route.getOrder());
if (defs.containsKey(route.getId())) {
r.put("route_definition", defs.get(route.getId()));
} else {
HashMap<String, Object> obj = new HashMap<>();
obj.put("predicate", route.getPredicate().toString());
if (!route.getFilters().isEmpty()) {
ArrayList<String> filters = new ArrayList<>();
for (GatewayFilter filter : route.getFilters()) {
filters.add(filter.toString());
}
obj.put("filters", filters);
}
if (!obj.isEmpty()) {
r.put("route_object", obj);
}
}
allRoutes.add(r);
});
return allRoutes;
});
}
/**
* 增加路由
*
* @param gatewayRouteDefinition gatewayRouteDefinition
* @return ResponseBean
*/
@PostMapping
public ResponseBean<String> add(@RequestBody RouteVo gatewayRouteDefinition) {
try {
RouteDefinition definition = assembleRouteDefinition(gatewayRouteDefinition);
log.info("新增路由:{},{}", definition.getId(), definition);
return new ResponseBean<>(this.dynamicRouteService.add(definition));
} catch (Exception e) {
e.printStackTrace();
}
return new ResponseBean<>("success");
}
/**
* 删除路由
*
* @param id id
* @return ResponseEntity
*/
@DeleteMapping("/{id}")
public Mono<ResponseEntity<Object>> delete(@PathVariable String id) {
log.info("删除路由:{}", id);
return this.dynamicRouteService.delete(id);
}
/**
* 更新路由
*
* @param routeVo routeVo
* @return ResponseBean
*/
@PutMapping
public ResponseBean<String> update(@RequestBody RouteVo routeVo) {
RouteDefinition definition = assembleRouteDefinition(routeVo);
return new ResponseBean<>(this.dynamicRouteService.update(definition));
}
/**
* 刷新路由
*
* @return ResponseBean
* @author tangyi
* @date 2019/04/07 12:32
*/
@GetMapping("refresh")
public ResponseBean<Boolean> refresh() {
amqpTemplate.convertAndSend(MqConstant.REFRESH_GATEWAY_ROUTE_QUEUE, "refresh");
return new ResponseBean<>(Boolean.TRUE);
}
/**
* @param routeVo routeVo
* @return RouteDefinition
*/
private RouteDefinition assembleRouteDefinition(RouteVo routeVo) {
RouteDefinition definition = new RouteDefinition();
// id
definition.setId(routeVo.getRouteId());
List<PredicateDefinition> predicateDefinitions = new ArrayList<>();
// predicates
for (RoutePredicateVo routePredicateVo : routeVo.getPredicates()) {
PredicateDefinition predicate = new PredicateDefinition();
predicate.setArgs(routePredicateVo.getArgs());
predicate.setName(routePredicateVo.getName());
predicateDefinitions.add(predicate);
}
definition.setPredicates(predicateDefinitions);
// filters
List<FilterDefinition> filterDefinitions = new ArrayList<>();
for (RouteFilterVo routeFilterVo : routeVo.getFilters()) {
FilterDefinition filterDefinition = new FilterDefinition();
filterDefinition.setName(routeFilterVo.getName());
filterDefinition.setArgs(routeFilterVo.getArgs());
filterDefinitions.add(filterDefinition);
}
definition.setFilters(filterDefinitions);
// uri
definition.setUri(URI.create(routeVo.getUri()));
return definition;
}
}
package com.github.tangyi.user.controller;
package com.github.tangyi.gateway.controller;
import com.github.pagehelper.PageInfo;
import com.github.tangyi.common.core.constant.CommonConstant;
import com.github.tangyi.common.core.constant.MqConstant;
import com.github.tangyi.common.core.exceptions.CommonException;
import com.github.tangyi.common.core.model.ResponseBean;
import com.github.tangyi.common.core.model.Route;
import com.github.tangyi.common.core.utils.PageUtil;
import com.github.tangyi.common.core.utils.SysUtil;
import com.github.tangyi.common.core.web.BaseController;
import com.github.tangyi.common.log.annotation.Log;
import com.github.tangyi.common.security.constant.SecurityConstant;
import com.github.tangyi.user.service.RouteService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import com.github.tangyi.gateway.module.Route;
import com.github.tangyi.gateway.service.RouteService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Collections;
import java.util.List;
/**
* 路由controller
......@@ -35,15 +23,12 @@ import java.util.List;
*/
@Slf4j
@AllArgsConstructor
@Api("网关路由信息管理")
@RestController
@RequestMapping("/v1/route")
@RequestMapping("/api/route/v1/route")
public class RouteController extends BaseController {
private final RouteService routeService;
private final AmqpTemplate amqpTemplate;
/**
* 根据id获取路由
......@@ -54,15 +39,15 @@ public class RouteController extends BaseController {
* @date 2019/4/2 15:09
*/
@GetMapping("/{id}")
@ApiOperation(value = "获取路由信息", notes = "根据路由id获取路由详细信息")
@ApiImplicitParam(name = "id", value = "路由ID", required = true, dataType = "String", paramType = "path")
public Route get(@PathVariable String id) {
try {
return routeService.get(id);
Route route = new Route();
route.setId(id);
return routeService.get(route);
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new CommonException(e.getMessage());
}
return new Route();
}
/**
......@@ -78,14 +63,6 @@ public class RouteController extends BaseController {
* @date 2019/4/2 15:09
*/
@GetMapping("routeList")
@ApiOperation(value = "获取路由列表")
@ApiImplicitParams({
@ApiImplicitParam(name = CommonConstant.PAGE_NUM, value = "分页页码", defaultValue = CommonConstant.PAGE_NUM_DEFAULT, dataType = "String"),
@ApiImplicitParam(name = CommonConstant.PAGE_SIZE, value = "分页大小", defaultValue = CommonConstant.PAGE_SIZE_DEFAULT, dataType = "String"),
@ApiImplicitParam(name = CommonConstant.SORT, value = "排序字段", defaultValue = CommonConstant.PAGE_SORT_DEFAULT, dataType = "String"),
@ApiImplicitParam(name = CommonConstant.ORDER, value = "排序方向", defaultValue = CommonConstant.PAGE_ORDER_DEFAULT, dataType = "String"),
@ApiImplicitParam(name = "route", value = "路由信息", dataType = "Route")
})
public PageInfo<Route> userList(@RequestParam(value = CommonConstant.PAGE_NUM, required = false, defaultValue = CommonConstant.PAGE_NUM_DEFAULT) String pageNum,
@RequestParam(value = CommonConstant.PAGE_SIZE, required = false, defaultValue = CommonConstant.PAGE_SIZE_DEFAULT) String pageSize,
@RequestParam(value = CommonConstant.SORT, required = false, defaultValue = CommonConstant.PAGE_SORT_DEFAULT) String sort,
......@@ -103,22 +80,14 @@ public class RouteController extends BaseController {
* @date 2019/4/2 15:09
*/
@PutMapping
@PreAuthorize("hasAuthority('sys:route:edit') or hasAnyRole('" + SecurityConstant.ROLE_ADMIN + "')")
@ApiOperation(value = "更新路由信息", notes = "根据路由id更新路由的基本信息")
@ApiImplicitParam(name = "route", value = "路由实体route", required = true, dataType = "Route")
@Log("修改路由")
public ResponseBean<Boolean> updateRoute(@RequestBody @Valid Route route) {
route.setCommonValue(SysUtil.getUser(), SysUtil.getSysCode());
// 更新路由
if (routeService.update(route) > 0) {
// 发送消息
if (Integer.parseInt(route.getStatus()) == CommonConstant.DEL_FLAG_DEL) {
amqpTemplate.convertAndSend(MqConstant.DEL_GATEWAY_ROUTE_QUEUE, route);
} else {
amqpTemplate.convertAndSend(MqConstant.EDIT_GATEWAY_ROUTE_QUEUE, route);
}
try {
// 更新路由
return new ResponseBean<>(routeService.update(route) > 0);
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new CommonException(e.getMessage());
}
return new ResponseBean<>(Boolean.TRUE);
}
/**
......@@ -130,17 +99,14 @@ public class RouteController extends BaseController {
* @date 2019/4/2 15:09
*/
@PostMapping
@PreAuthorize("hasAuthority('sys:route:add') or hasAnyRole('" + SecurityConstant.ROLE_ADMIN + "')")
@ApiOperation(value = "创建路由", notes = "创建路由")
@ApiImplicitParam(name = "route", value = "路由实体route", required = true, dataType = "Route")
@Log("新增路由")
public ResponseBean<Boolean> add(@RequestBody @Valid Route route) {
route.setCommonValue(SysUtil.getUser(), SysUtil.getSysCode());
if (routeService.insert(route) > 0 && Integer.parseInt(route.getStatus()) == CommonConstant.DEL_FLAG_NORMAL) {
// 发送消息
amqpTemplate.convertAndSend(MqConstant.EDIT_GATEWAY_ROUTE_QUEUE, route);
try {
// 新增路由
return new ResponseBean<>(routeService.insert(route) > 0);
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new CommonException(e.getMessage());
}
return new ResponseBean<>(Boolean.TRUE);
}
/**
......@@ -152,21 +118,13 @@ public class RouteController extends BaseController {
* @date 2019/4/2 15:09
*/
@DeleteMapping("/{id}")
@PreAuthorize("hasAuthority('sys:route:del') or hasAnyRole('" + SecurityConstant.ROLE_ADMIN + "')")
@ApiOperation(value = "删除路由", notes = "根据ID删除路由")
@ApiImplicitParam(name = "id", value = "路由ID", required = true, paramType = "path")
@Log("删除路由")
public ResponseBean<Boolean> delete(@PathVariable String id) {
Route route = new Route();
route.setId(id);
route = routeService.get(route);
route.setNewRecord(false);
route.setCommonValue(SysUtil.getUser(), SysUtil.getSysCode());
if (routeService.delete(route) > 0) {
// 发送消息
amqpTemplate.convertAndSend(MqConstant.DEL_GATEWAY_ROUTE_QUEUE, Collections.singletonList(route));
try {
return new ResponseBean<>(routeService.delete(id) > 0);
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new CommonException(e.getMessage());
}
return new ResponseBean<>(Boolean.TRUE);
}
/**
......@@ -178,26 +136,33 @@ public class RouteController extends BaseController {
* @date 2019/4/2 15:09
*/
@PostMapping("deleteAll")
@PreAuthorize("hasAuthority('sys:route:del') or hasAnyRole('" + SecurityConstant.ROLE_ADMIN + "')")
@ApiOperation(value = "批量删除路由", notes = "根据路由id批量删除路由")
@ApiImplicitParam(name = "route", value = "路由信息", dataType = "Route")
@Log("批量删除路由")
public ResponseBean<Boolean> deleteAll(@RequestBody Route route) {
boolean success = false;
try {
if (StringUtils.isNotEmpty(route.getIdString())) {
// 先获取路由列表
List<Route> routeList = routeService.findListById(route);
// 删除
if (StringUtils.isNotEmpty(route.getIdString()))
success = routeService.deleteAll(route.getIdString().split(",")) > 0;
if (success && CollectionUtils.isNotEmpty(routeList)) {
// 发送消息
amqpTemplate.convertAndSend(MqConstant.DEL_GATEWAY_ROUTE_QUEUE, route);
}
}
return new ResponseBean<>(success);
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new CommonException(e.getMessage());
}
}
/**
* 刷新路由
*
* @return ResponseBean
* @author tangyi
* @date 2019/04/07 12:32
*/
@GetMapping("refresh")
public ResponseBean<Boolean> refresh() {
try {
return new ResponseBean<>(routeService.refresh());
} catch (Exception e) {
log.error("删除路由失败!", e);
log.error(e.getMessage());
throw new CommonException(e.getMessage());
}
return new ResponseBean<>(success);
}
}
package com.github.tangyi.user.mapper;
package com.github.tangyi.gateway.mapper;
import com.github.tangyi.common.core.model.Route;
import com.github.tangyi.gateway.module.Route;
import com.github.tangyi.common.core.persistence.CrudMapper;
import org.apache.ibatis.annotations.Mapper;
......
package com.github.tangyi.common.core.model;
package com.github.tangyi.gateway.module;
import com.github.tangyi.common.core.persistence.BaseEntity;
import lombok.Data;
......
package com.github.tangyi.gateway.receiver;
package com.github.tangyi.gateway.service;
import com.fasterxml.jackson.databind.JavaType;
import com.github.tangyi.common.core.constant.MqConstant;
import com.github.tangyi.common.core.model.Route;
import com.github.tangyi.common.core.constant.CommonConstant;
import com.github.tangyi.common.core.service.CrudService;
import com.github.tangyi.common.core.utils.JsonMapper;
import com.github.tangyi.common.core.vo.RouteFilterVo;
import com.github.tangyi.common.core.vo.RoutePredicateVo;
import com.github.tangyi.gateway.service.DynamicRouteService;
import com.github.tangyi.gateway.constants.GatewayConstant;
import com.github.tangyi.gateway.mapper.RouteMapper;
import com.github.tangyi.gateway.module.Route;
import com.github.tangyi.gateway.vo.RouteFilterVo;
import com.github.tangyi.gateway.vo.RoutePredicateVo;
import com.github.tangyi.gateway.vo.RouteVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
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;
/**
* 动态路由
* 路由service
*
* @author tangyi
* @date 2019/4/2 18:07
* @date 2019/4/2 15:01
*/
@Slf4j
@AllArgsConstructor
@Service
public class GatewayRouteReceiver {
public class RouteService extends CrudService<RouteMapper, Route> {
private final DynamicRouteService dynamicRouteService;
private final RedisTemplate redisTemplate;
/**
* 修改路由
* 新增路由
*
* @param route route
* @author tangyi
* @date 2019/04/02 20:51
* @return int
*/
@Override
public int insert(Route route) {
int update;
route.setCommonValue("", GatewayConstant.SYS_CODE, GatewayConstant.DEFAULT_TENANT_CODE);
if ((update = this.dao.insert(route)) > 0) {
dynamicRouteService.add(routeDefinition(route));
}
return update;
}
/**
* 更新路由
*
* @param route route
* @return int
*/
@RabbitListener(queues = {MqConstant.EDIT_GATEWAY_ROUTE_QUEUE})
public void editRoute(Route route) {
if (route.getRouteId() == null)
throw new IllegalArgumentException("routeId不能为空!");
log.info("更新{}路由", route.getRouteId());
dynamicRouteService.update(routeDefinition(route));
@Override
public int update(Route route) {
int update;
route.setNewRecord(false);
route.setCommonValue("", GatewayConstant.SYS_CODE, GatewayConstant.DEFAULT_TENANT_CODE);
if ((update = this.dao.update(route)) > 0) {
dynamicRouteService.update(routeDefinition(route));
}
return update;
}
/**
* 删除路由
*
* @param routes routes
* @author tangyi
* @date 2019/04/02 20:51
* @param id id
* @return Mono
*/
@Transactional
public int delete(String id) {
Route route = new Route();
route.setId(id);
route.setNewRecord(false);
route.setCommonValue("", GatewayConstant.SYS_CODE, GatewayConstant.DEFAULT_TENANT_CODE);
int update = this.dao.delete(route);
dynamicRouteService.delete(id);
return update;
}
/**
* 刷新路由
*
* @return boolean
*/
@RabbitListener(queues = {MqConstant.DEL_GATEWAY_ROUTE_QUEUE})
public void delRoute(List<Route> routes) {
if (routes == null || routes.isEmpty())
return;
for (Route route : routes) {
if (route.getRouteId() == null)
throw new IllegalArgumentException("routeId不能为空!");
log.info("删除{}路由", route.getRouteId());
dynamicRouteService.delete(route.getRouteId());
public boolean refresh() {
Route init = new Route();
init.setStatus(CommonConstant.DEL_FLAG_NORMAL.toString());
List<Route> routes = this.findList(init);
if (CollectionUtils.isNotEmpty(routes)) {
log.info("加载{}条路由记录", routes.size());
for (Route route : routes)
dynamicRouteService.update(routeDefinition(route));
// 存入Redis
redisTemplate.opsForValue().set(CommonConstant.ROUTE_KEY, JsonMapper.getInstance().toJson(routes));
}
return true;
}
/**
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.github.tangyi.user.mapper.RouteMapper">
<resultMap id="routeResultMap" type="com.github.tangyi.common.core.model.Route">
<mapper namespace="com.github.tangyi.gateway.mapper.RouteMapper">
<resultMap id="routeResultMap" type="com.github.tangyi.gateway.module.Route">
<id column="id" property="id"/>
<result column="route_id" property="routeId"/>
<result column="route_name" property="routeName"/>
......
package com.github.tangyi.user.config;
import com.github.tangyi.common.core.constant.MqConstant;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* RabbitMq配置
*
* @author tangyi
* @date 2019/4/2 17:56
*/
@Configuration
public class RabbitConfig {
/**
* 修改路由
*
* @return Queue
*/
@Bean
public Queue editQueue() {
return new Queue(MqConstant.EDIT_GATEWAY_ROUTE_QUEUE);
}
/**
* 删除路由
*
* @return Queue
*/
@Bean
public Queue delQueue() {
return new Queue(MqConstant.DEL_GATEWAY_ROUTE_QUEUE);
}
/**
* 刷新路由
*
* @return Queue
*/
@Bean
public Queue refreshQueue() {
return new Queue(MqConstant.REFRESH_GATEWAY_ROUTE_QUEUE);
}
}
package com.github.tangyi.user.config;
import com.github.tangyi.common.core.constant.CommonConstant;
import com.github.tangyi.common.core.constant.MqConstant;
import com.github.tangyi.common.core.model.Route;
import com.github.tangyi.common.core.utils.JsonMapper;
import com.github.tangyi.user.service.RouteService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.PostConstruct;
import java.util.List;
/**
* 初始化路由信息
*
* @author tangyi
* @date 2019/4/2 18:42
*/
@Slf4j
@AllArgsConstructor
@Configuration
public class RouteInitConfig {
private final RouteService routeService;
private final AmqpTemplate amqpTemplate;
private final RedisTemplate redisTemplate;
@PostConstruct
public void initRoute() {
init();
}
/**
* 加载所有路由,发送到mq,存放到redis
*
* @author tangyi
* @date 2019/04/07 12:05
*/
public void init() {
try {
Route init = new Route();
init.setStatus(CommonConstant.DEL_FLAG_NORMAL.toString());
List<Route> routes = routeService.findList(init);
if (CollectionUtils.isNotEmpty(routes)) {
log.info("加载{}条路由记录", routes.size());
for (Route route : routes) {
// 发送消息
amqpTemplate.convertAndSend(MqConstant.EDIT_GATEWAY_ROUTE_QUEUE, route);
}
// 存入Redis
redisTemplate.opsForValue().set(CommonConstant.ROUTE_KEY, JsonMapper.getInstance().toJson(routes));
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
package com.github.tangyi.user.receiver;
import com.github.tangyi.common.core.constant.MqConstant;
import com.github.tangyi.user.config.RouteInitConfig;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
/**
* @author tangyi
* @date 2019/4/7 12:38
*/
@Slf4j
@AllArgsConstructor
@Service
public class RouteReceiver {
private final RouteInitConfig routeInitConfig;
/**
* 刷新路由
*
* @param msg msg
* @author tangyi
* @date 2019/04/07 12:39
*/
@RabbitListener(queues = {MqConstant.REFRESH_GATEWAY_ROUTE_QUEUE})
public void refreshRoute(String msg) {
log.info("刷新路由{}", msg);
routeInitConfig.init();
}
}
package com.github.tangyi.user.service;
import com.github.tangyi.common.core.model.Route;
import com.github.tangyi.common.core.service.CrudService;
import com.github.tangyi.user.mapper.RouteMapper;
import org.springframework.stereotype.Service;
/**
* 路由service
*
* @author tangyi
* @date 2019/4/2 15:01
*/
@Service
public class RouteService extends CrudService<RouteMapper, Route> {
}
......@@ -11,6 +11,8 @@
<result column="grade" property="grade"/>
<result column="school" property="school"/>
<result column="wechat" property="wechat"/>
<result column="cityId" property="city_id"/>
<result column="countyId" property="county_id"/>
<result column="creator" property="creator"/>
<result column="create_date" property="createDate" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
<result column="modifier" property="modifier"/>
......@@ -28,6 +30,8 @@
a.grade,
a.school,
a.wechat,
a.cityId,
a.countyId,
a.creator,
a.create_date,
a.modifier,
......@@ -70,6 +74,8 @@
grade,
school,
wechat,
city_id,
county_id,
creator,
create_date,
modifier,
......@@ -85,6 +91,8 @@
#{grade},
#{school},
#{wechat},
#{cityId},
#{countyId},
#{creator},
#{createDate, jdbcType=TIMESTAMP, javaType=java.util.Date},
#{modifier},
......@@ -119,6 +127,12 @@
<if test="wechat != null">
wechat = #{wechat},
</if>
<if test="cityId != null">
city_id = #{cityId},
</if>
<if test="countyId != null">
county_id = #{countyId},
</if>
<if test="delFlag != null">
del_flag = #{delFlag},
</if>
......
......@@ -82,4 +82,16 @@ public class StudentDto implements Serializable {
*/
@ApiModelProperty(value = "就读学校")
private String school;
/**
* 城市id
*/
@ApiModelProperty(value = "就读学校")
private String cityId;
/**
* 县id
*/
@ApiModelProperty(value = "县id")
private String countyId;
}
......@@ -49,7 +49,7 @@ public interface UserServiceClient {
* @date 2019/07/06 14:14:11
*/
@GetMapping("/v1/user/findUserByIdentifier/{identifier}")
UserVo findUserByIdentifier(@PathVariable("identifier") String identifier, @RequestParam(required = false) Integer identityType, @RequestParam("tenantCode") String tenantCode);
UserVo findUserByIdentifier(@PathVariable("identifier") String identifier, @RequestParam(value = "identityType", required = false) Integer identityType, @RequestParam("tenantCode") String tenantCode);
/**
......
......@@ -53,4 +53,14 @@ public class Student extends BaseEntity<Student> {
* 就读学校
*/
private String school;
/**
* 城市id
*/
private String cityId;
/**
* 县id
*/
private String countyId;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment