From 54a10c144695dfcdaaed28a76fdcae727c75da72 Mon Sep 17 00:00:00 2001 From: lishangbu Date: Wed, 7 Nov 2018 19:49:19 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20=E4=BF=AE=E5=A4=8D=20BUG:=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E5=8A=A8=E6=80=81=E8=B7=AF=E7=94=B1=E5=AF=BC=E8=87=B4?= =?UTF-8?q?swagger=E5=A4=B1=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pigx/gateway/config/SwaggerProvider.java | 13 +- .../gateway/handler/DynamicRouteHandler.java | 125 ++++++++++++++++++ 2 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/handler/DynamicRouteHandler.java diff --git a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/config/SwaggerProvider.java b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/config/SwaggerProvider.java index 261ff8cc6..60c510df4 100644 --- a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/config/SwaggerProvider.java +++ b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/config/SwaggerProvider.java @@ -17,9 +17,8 @@ package com.pig4cloud.pigx.gateway.config; +import com.pig4cloud.pigx.gateway.handler.DynamicRouteHandler; import lombok.AllArgsConstructor; -import org.springframework.cloud.gateway.config.GatewayProperties; -import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.support.NameUtils; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @@ -38,22 +37,22 @@ import java.util.List; @AllArgsConstructor public class SwaggerProvider implements SwaggerResourcesProvider { private static final String API_URI = "/v2/api-docs"; - private final RouteLocator routeLocator; - private final GatewayProperties gatewayProperties; + private final DynamicRouteHandler dynamicRouteHandler; + @Override public List get() { List resources = new ArrayList<>(); List routes = new ArrayList<>(); - routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); - gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())) + dynamicRouteHandler.routes().subscribe(routeMap->routeMap.keySet().forEach(route->routes.add(route))); + dynamicRouteHandler.routes().subscribe(routeMap->routeMap.values().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())) .forEach(routeDefinition -> routeDefinition.getPredicates().stream() .filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName())) .filter(predicateDefinition -> !"pigx-auth".equalsIgnoreCase(routeDefinition.getId())) .forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(), predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0") - .replace("/**", API_URI))))); + .replace("/**", API_URI)))))); return resources; } diff --git a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/handler/DynamicRouteHandler.java b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/handler/DynamicRouteHandler.java new file mode 100644 index 000000000..bd81eaa00 --- /dev/null +++ b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/handler/DynamicRouteHandler.java @@ -0,0 +1,125 @@ +package com.pig4cloud.pigx.gateway.handler; + +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import com.pig4cloud.pigx.common.core.constant.CommonConstant; +import com.pig4cloud.pigx.common.gateway.support.DynamicRouteInitEvent; +import com.pig4cloud.pigx.common.gateway.vo.RouteDefinitionVo; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cloud.gateway.event.RefreshRoutesEvent; +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.cloud.gateway.route.RouteDefinitionLocator; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Mono; + +import java.net.URI; +import java.util.List; +import java.util.Map; + +/** + * DynamicRouteHandler + * 动态路由处理器 + * @author: lengleng + * @date: 2018/11/7 + */ +@Slf4j +@Service +public class DynamicRouteHandler implements ApplicationEventPublisherAware { + private final RouteDefinitionLocator routeDefinitionLocator; + private final RedisTemplate redisTemplate; + private ApplicationEventPublisher applicationEventPublisher; + + public DynamicRouteHandler(RedisTemplate redisTemplate + , RouteDefinitionLocator routeDefinitionLocator) { + this.redisTemplate = redisTemplate; + this.routeDefinitionLocator = routeDefinitionLocator; + } + + /** + * 获取全部路由 + *

+ * RedisRouteDefinitionWriter.java + * PropertiesRouteDefinitionLocator.java + * + * @return + */ + public Mono> routes() { + return routeDefinitionLocator.getRouteDefinitions() + .collectMap(RouteDefinition::getId); + } + + /** + * 更新路由信息 + * + * @param routes 路由信息 + * @return + */ + public Mono editRoutes(JSONObject routes) { + Boolean result = redisTemplate.delete(CommonConstant.ROUTE_KEY); + log.info("清空网关路由 {} ", result); + + routes.forEach((key, value) -> { + log.info("更新路由 -> {} ->{}", key, value); + RouteDefinitionVo vo = new RouteDefinitionVo(); + Map map = (Map) value; + + Object id = map.get("id"); + if (id != null) { + vo.setId(String.valueOf(id)); + } + + Object predicates = map.get("predicates"); + if (predicates != null) { + JSONArray predicatesArray = (JSONArray) predicates; + List predicateDefinitionList = + predicatesArray.toList(PredicateDefinition.class); + vo.setPredicates(predicateDefinitionList); + } + + Object filters = map.get("filters"); + if (filters != null) { + JSONArray filtersArray = (JSONArray) filters; + List filterDefinitionList + = filtersArray.toList(FilterDefinition.class); + vo.setFilters(filterDefinitionList); + } + + Object uri = map.get("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))); + } + + redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(RouteDefinitionVo.class)); + redisTemplate.opsForHash().put(CommonConstant.ROUTE_KEY, key, vo); + }); + log.debug("更新网关路由结束 "); + this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this)); + return Mono.empty(); + } + + /** + * 回滚路由 + * + * @return + */ + public Mono fallback() { + this.applicationEventPublisher.publishEvent(new DynamicRouteInitEvent(this)); + return Mono.empty(); + } + + @Override + public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + this.applicationEventPublisher = applicationEventPublisher; + } +}