Commit 5e3df5c7 by tangyi

优化网关

parent 9ca661d9
Version v3.0.0 (2019-7-15)
--------------------------
改进:
* 优化优化网关的动态路由
* 学生增加城市id、县id
Version v3.0.0 (2019-7-6) Version v3.0.0 (2019-7-6)
-------------------------- --------------------------
改进: 改进:
......
...@@ -4,6 +4,7 @@ import com.github.tangyi.common.core.constant.CommonConstant; ...@@ -4,6 +4,7 @@ import com.github.tangyi.common.core.constant.CommonConstant;
import com.github.tangyi.common.core.properties.SysProperties; import com.github.tangyi.common.core.properties.SysProperties;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
...@@ -25,6 +26,7 @@ public class AppStartupRunner implements CommandLineRunner { ...@@ -25,6 +26,7 @@ public class AppStartupRunner implements CommandLineRunner {
log.info("start command line..."); log.info("start command line...");
log.info("set system properties..."); 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; ...@@ -7,21 +7,6 @@ package com.github.tangyi.common.core.constant;
public class MqConstant { 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"; public static final String SUBMIT_EXAMINATION_QUEUE = "submit_examination_queue";
......
server: server:
port: 8000 port: 8000
spring: 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: redis:
host: ${REDIS_HOST:localhost} host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379} port: ${REDIS_PORT:6379}
...@@ -28,6 +34,21 @@ spring: ...@@ -28,6 +34,21 @@ spring:
zipkin: zipkin:
base-url: http://${ZIPKIN_HOST:localhost}:${ZIPKIN_PORT:9411} # 指定了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: sys:
adminUser: ${ADMIN_USER:admin} # 管理员账号,默认是admin 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 @@ ...@@ -35,6 +35,18 @@
<groupId>de.codecentric</groupId> <groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId> <artifactId>spring-boot-admin-starter-client</artifactId>
</dependency> </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> </dependencies>
<build> <build>
......
...@@ -3,13 +3,12 @@ package com.github.tangyi.gateway; ...@@ -3,13 +3,12 @@ package com.github.tangyi.gateway;
import com.github.tangyi.gateway.annotation.EnableGatewayTokenTransfer; import com.github.tangyi.gateway.annotation.EnableGatewayTokenTransfer;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; 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.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
@EnableDiscoveryClient @EnableDiscoveryClient
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) @SpringBootApplication
@ComponentScan(basePackages = {"com.github.tangyi"}) @ComponentScan(basePackages = {"com.github.tangyi"})
@EnableCircuitBreaker @EnableCircuitBreaker
@EnableGatewayTokenTransfer @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; package com.github.tangyi.gateway.config;
import com.github.tangyi.common.core.constant.CommonConstant; 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.utils.JsonMapper;
import com.github.tangyi.common.core.vo.RoutePredicateVo; import com.github.tangyi.gateway.vo.RoutePredicateVo;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
......
package com.github.tangyi.gateway.config; package com.github.tangyi.gateway.config;
import com.github.tangyi.common.core.constant.CommonConstant; import com.github.tangyi.gateway.service.RouteService;
import com.github.tangyi.common.core.model.Route;
import com.github.tangyi.common.core.utils.JsonMapper;
import com.github.tangyi.gateway.receiver.GatewayRouteReceiver;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
/** /**
* 动态路由实现:修改数据库路由配置,用户服务发送路由更新消息,网关消费消息,更新路由配置 * 初始化的时候加载路由数据
* 依赖Redis,如果Redis被清空,需要手动刷新加载路由列表
* *
* @author tangyi * @author tangyi
* @date 2019/4/2 14:40 * @date 2019/4/2 14:40
...@@ -26,21 +18,10 @@ import java.util.List; ...@@ -26,21 +18,10 @@ import java.util.List;
@Configuration @Configuration
public class RouteInitConfig { public class RouteInitConfig {
private final RedisTemplate redisTemplate; private final RouteService routeService;
private final GatewayRouteReceiver gatewayRouteReceiver;
@PostConstruct @PostConstruct
public void initRoute() { public void initRoute() {
// 重Redis加载路由列表 routeService.refresh();
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);
}
}
} }
} }
...@@ -51,4 +51,14 @@ public class GatewayConstant { ...@@ -51,4 +51,14 @@ public class GatewayConstant {
*/ */
public static final String GATEWAY_REFRESH_TOKENS = "gateway_refresh:"; 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.pagehelper.PageInfo;
import com.github.tangyi.common.core.constant.CommonConstant; 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.ResponseBean;
import com.github.tangyi.common.core.model.Route;
import com.github.tangyi.common.core.utils.PageUtil; 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.core.web.BaseController;
import com.github.tangyi.common.log.annotation.Log; import com.github.tangyi.gateway.module.Route;
import com.github.tangyi.common.security.constant.SecurityConstant; import com.github.tangyi.gateway.service.RouteService;
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 lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils; 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 org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.Collections;
import java.util.List;
/** /**
* 路由controller * 路由controller
...@@ -35,15 +23,12 @@ import java.util.List; ...@@ -35,15 +23,12 @@ import java.util.List;
*/ */
@Slf4j @Slf4j
@AllArgsConstructor @AllArgsConstructor
@Api("网关路由信息管理")
@RestController @RestController
@RequestMapping("/v1/route") @RequestMapping("/api/route/v1/route")
public class RouteController extends BaseController { public class RouteController extends BaseController {
private final RouteService routeService; private final RouteService routeService;
private final AmqpTemplate amqpTemplate;
/** /**
* 根据id获取路由 * 根据id获取路由
...@@ -54,15 +39,15 @@ public class RouteController extends BaseController { ...@@ -54,15 +39,15 @@ public class RouteController extends BaseController {
* @date 2019/4/2 15:09 * @date 2019/4/2 15:09
*/ */
@GetMapping("/{id}") @GetMapping("/{id}")
@ApiOperation(value = "获取路由信息", notes = "根据路由id获取路由详细信息")
@ApiImplicitParam(name = "id", value = "路由ID", required = true, dataType = "String", paramType = "path")
public Route get(@PathVariable String id) { public Route get(@PathVariable String id) {
try { try {
return routeService.get(id); Route route = new Route();
route.setId(id);
return routeService.get(route);
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
throw new CommonException(e.getMessage());
} }
return new Route();
} }
/** /**
...@@ -78,14 +63,6 @@ public class RouteController extends BaseController { ...@@ -78,14 +63,6 @@ public class RouteController extends BaseController {
* @date 2019/4/2 15:09 * @date 2019/4/2 15:09
*/ */
@GetMapping("routeList") @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, 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.PAGE_SIZE, required = false, defaultValue = CommonConstant.PAGE_SIZE_DEFAULT) String pageSize,
@RequestParam(value = CommonConstant.SORT, required = false, defaultValue = CommonConstant.PAGE_SORT_DEFAULT) String sort, @RequestParam(value = CommonConstant.SORT, required = false, defaultValue = CommonConstant.PAGE_SORT_DEFAULT) String sort,
...@@ -103,22 +80,14 @@ public class RouteController extends BaseController { ...@@ -103,22 +80,14 @@ public class RouteController extends BaseController {
* @date 2019/4/2 15:09 * @date 2019/4/2 15:09
*/ */
@PutMapping @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) { public ResponseBean<Boolean> updateRoute(@RequestBody @Valid Route route) {
route.setCommonValue(SysUtil.getUser(), SysUtil.getSysCode()); try {
// 更新路由 // 更新路由
if (routeService.update(route) > 0) { return new ResponseBean<>(routeService.update(route) > 0);
// 发送消息 } catch (Exception e) {
if (Integer.parseInt(route.getStatus()) == CommonConstant.DEL_FLAG_DEL) { log.error(e.getMessage(), e);
amqpTemplate.convertAndSend(MqConstant.DEL_GATEWAY_ROUTE_QUEUE, route); throw new CommonException(e.getMessage());
} else {
amqpTemplate.convertAndSend(MqConstant.EDIT_GATEWAY_ROUTE_QUEUE, route);
}
} }
return new ResponseBean<>(Boolean.TRUE);
} }
/** /**
...@@ -130,17 +99,14 @@ public class RouteController extends BaseController { ...@@ -130,17 +99,14 @@ public class RouteController extends BaseController {
* @date 2019/4/2 15:09 * @date 2019/4/2 15:09
*/ */
@PostMapping @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) { public ResponseBean<Boolean> add(@RequestBody @Valid Route route) {
route.setCommonValue(SysUtil.getUser(), SysUtil.getSysCode()); try {
if (routeService.insert(route) > 0 && Integer.parseInt(route.getStatus()) == CommonConstant.DEL_FLAG_NORMAL) { // 新增路由
// 发送消息 return new ResponseBean<>(routeService.insert(route) > 0);
amqpTemplate.convertAndSend(MqConstant.EDIT_GATEWAY_ROUTE_QUEUE, route); } 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 { ...@@ -152,21 +118,13 @@ public class RouteController extends BaseController {
* @date 2019/4/2 15:09 * @date 2019/4/2 15:09
*/ */
@DeleteMapping("/{id}") @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) { public ResponseBean<Boolean> delete(@PathVariable String id) {
Route route = new Route(); try {
route.setId(id); return new ResponseBean<>(routeService.delete(id) > 0);
route = routeService.get(route); } catch (Exception e) {
route.setNewRecord(false); log.error(e.getMessage(), e);
route.setCommonValue(SysUtil.getUser(), SysUtil.getSysCode()); throw new CommonException(e.getMessage());
if (routeService.delete(route) > 0) {
// 发送消息
amqpTemplate.convertAndSend(MqConstant.DEL_GATEWAY_ROUTE_QUEUE, Collections.singletonList(route));
} }
return new ResponseBean<>(Boolean.TRUE);
} }
/** /**
...@@ -178,26 +136,33 @@ public class RouteController extends BaseController { ...@@ -178,26 +136,33 @@ public class RouteController extends BaseController {
* @date 2019/4/2 15:09 * @date 2019/4/2 15:09
*/ */
@PostMapping("deleteAll") @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) { public ResponseBean<Boolean> deleteAll(@RequestBody Route route) {
boolean success = false; boolean success = false;
try { try {
if (StringUtils.isNotEmpty(route.getIdString())) { if (StringUtils.isNotEmpty(route.getIdString()))
// 先获取路由列表
List<Route> routeList = routeService.findListById(route);
// 删除
success = routeService.deleteAll(route.getIdString().split(",")) > 0; success = routeService.deleteAll(route.getIdString().split(",")) > 0;
if (success && CollectionUtils.isNotEmpty(routeList)) { return new ResponseBean<>(success);
// 发送消息 } catch (Exception e) {
amqpTemplate.convertAndSend(MqConstant.DEL_GATEWAY_ROUTE_QUEUE, route); 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) { } 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 com.github.tangyi.common.core.persistence.CrudMapper;
import org.apache.ibatis.annotations.Mapper; 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 com.github.tangyi.common.core.persistence.BaseEntity;
import lombok.Data; import lombok.Data;
......
package com.github.tangyi.gateway.receiver; package com.github.tangyi.gateway.service;
import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JavaType;
import com.github.tangyi.common.core.constant.MqConstant; import com.github.tangyi.common.core.constant.CommonConstant;
import com.github.tangyi.common.core.model.Route; import com.github.tangyi.common.core.service.CrudService;
import com.github.tangyi.common.core.utils.JsonMapper; import com.github.tangyi.common.core.utils.JsonMapper;
import com.github.tangyi.common.core.vo.RouteFilterVo; import com.github.tangyi.gateway.constants.GatewayConstant;
import com.github.tangyi.common.core.vo.RoutePredicateVo; import com.github.tangyi.gateway.mapper.RouteMapper;
import com.github.tangyi.gateway.service.DynamicRouteService; 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.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils; 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.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition; import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition; 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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Mono;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* 动态路由 * 路由service
* *
* @author tangyi * @author tangyi
* @date 2019/4/2 18:07 * @date 2019/4/2 15:01
*/ */
@Slf4j @Slf4j
@AllArgsConstructor @AllArgsConstructor
@Service @Service
public class GatewayRouteReceiver { public class RouteService extends CrudService<RouteMapper, Route> {
private final DynamicRouteService dynamicRouteService; private final DynamicRouteService dynamicRouteService;
private final RedisTemplate redisTemplate;
/** /**
* 修改路由 * 新增路由
* *
* @param route route * @param route route
* @author tangyi * @return int
* @date 2019/04/02 20:51 */
@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}) @Override
public void editRoute(Route route) { public int update(Route route) {
if (route.getRouteId() == null) int update;
throw new IllegalArgumentException("routeId不能为空!"); route.setNewRecord(false);
log.info("更新{}路由", route.getRouteId()); route.setCommonValue("", GatewayConstant.SYS_CODE, GatewayConstant.DEFAULT_TENANT_CODE);
dynamicRouteService.update(routeDefinition(route)); if ((update = this.dao.update(route)) > 0) {
dynamicRouteService.update(routeDefinition(route));
}
return update;
} }
/** /**
* 删除路由 * 删除路由
* *
* @param routes routes * @param id id
* @author tangyi * @return Mono
* @date 2019/04/02 20:51 */
@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 boolean refresh() {
public void delRoute(List<Route> routes) { Route init = new Route();
if (routes == null || routes.isEmpty()) init.setStatus(CommonConstant.DEL_FLAG_NORMAL.toString());
return; List<Route> routes = this.findList(init);
for (Route route : routes) { if (CollectionUtils.isNotEmpty(routes)) {
if (route.getRouteId() == null) log.info("加载{}条路由记录", routes.size());
throw new IllegalArgumentException("routeId不能为空!"); for (Route route : routes)
log.info("删除{}路由", route.getRouteId()); dynamicRouteService.update(routeDefinition(route));
dynamicRouteService.delete(route.getRouteId()); // 存入Redis
redisTemplate.opsForValue().set(CommonConstant.ROUTE_KEY, JsonMapper.getInstance().toJson(routes));
} }
return true;
} }
/** /**
......
package com.github.tangyi.common.core.vo; package com.github.tangyi.gateway.vo;
import lombok.Data; import lombok.Data;
......
package com.github.tangyi.common.core.vo; package com.github.tangyi.gateway.vo;
import lombok.Data; import lombok.Data;
......
<?xml version="1.0" encoding="UTF-8"?> <?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"> <!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"> <mapper namespace="com.github.tangyi.gateway.mapper.RouteMapper">
<resultMap id="routeResultMap" type="com.github.tangyi.common.core.model.Route"> <resultMap id="routeResultMap" type="com.github.tangyi.gateway.module.Route">
<id column="id" property="id"/> <id column="id" property="id"/>
<result column="route_id" property="routeId"/> <result column="route_id" property="routeId"/>
<result column="route_name" property="routeName"/> <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 @@ ...@@ -11,6 +11,8 @@
<result column="grade" property="grade"/> <result column="grade" property="grade"/>
<result column="school" property="school"/> <result column="school" property="school"/>
<result column="wechat" property="wechat"/> <result column="wechat" property="wechat"/>
<result column="cityId" property="city_id"/>
<result column="countyId" property="county_id"/>
<result column="creator" property="creator"/> <result column="creator" property="creator"/>
<result column="create_date" property="createDate" javaType="java.util.Date" jdbcType="TIMESTAMP"/> <result column="create_date" property="createDate" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
<result column="modifier" property="modifier"/> <result column="modifier" property="modifier"/>
...@@ -28,6 +30,8 @@ ...@@ -28,6 +30,8 @@
a.grade, a.grade,
a.school, a.school,
a.wechat, a.wechat,
a.cityId,
a.countyId,
a.creator, a.creator,
a.create_date, a.create_date,
a.modifier, a.modifier,
...@@ -70,6 +74,8 @@ ...@@ -70,6 +74,8 @@
grade, grade,
school, school,
wechat, wechat,
city_id,
county_id,
creator, creator,
create_date, create_date,
modifier, modifier,
...@@ -85,6 +91,8 @@ ...@@ -85,6 +91,8 @@
#{grade}, #{grade},
#{school}, #{school},
#{wechat}, #{wechat},
#{cityId},
#{countyId},
#{creator}, #{creator},
#{createDate, jdbcType=TIMESTAMP, javaType=java.util.Date}, #{createDate, jdbcType=TIMESTAMP, javaType=java.util.Date},
#{modifier}, #{modifier},
...@@ -119,6 +127,12 @@ ...@@ -119,6 +127,12 @@
<if test="wechat != null"> <if test="wechat != null">
wechat = #{wechat}, wechat = #{wechat},
</if> </if>
<if test="cityId != null">
city_id = #{cityId},
</if>
<if test="countyId != null">
county_id = #{countyId},
</if>
<if test="delFlag != null"> <if test="delFlag != null">
del_flag = #{delFlag}, del_flag = #{delFlag},
</if> </if>
......
...@@ -82,4 +82,16 @@ public class StudentDto implements Serializable { ...@@ -82,4 +82,16 @@ public class StudentDto implements Serializable {
*/ */
@ApiModelProperty(value = "就读学校") @ApiModelProperty(value = "就读学校")
private String school; private String school;
/**
* 城市id
*/
@ApiModelProperty(value = "就读学校")
private String cityId;
/**
* 县id
*/
@ApiModelProperty(value = "县id")
private String countyId;
} }
...@@ -49,7 +49,7 @@ public interface UserServiceClient { ...@@ -49,7 +49,7 @@ public interface UserServiceClient {
* @date 2019/07/06 14:14:11 * @date 2019/07/06 14:14:11
*/ */
@GetMapping("/v1/user/findUserByIdentifier/{identifier}") @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> { ...@@ -53,4 +53,14 @@ public class Student extends BaseEntity<Student> {
* 就读学校 * 就读学校
*/ */
private String school; 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