diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/AbstractTargetRoute.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/AbstractTargetRoute.java deleted file mode 100644 index 65b40cc2..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/AbstractTargetRoute.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.gitee.sop.gatewaycommon.bean; - -/** - * @author tanghc - */ -public abstract class AbstractTargetRoute implements TargetRoute { - - private ServiceRouteInfo serviceRouteInfo; - private RouteDefinition routeDefinition; - private T targetRoute; - - public AbstractTargetRoute(ServiceRouteInfo serviceRouteInfo, RouteDefinition routeDefinition, T targetRoute) { - this.serviceRouteInfo = serviceRouteInfo; - this.routeDefinition = routeDefinition; - this.targetRoute = targetRoute; - } - - @Override - public ServiceRouteInfo getServiceRouteInfo() { - return serviceRouteInfo; - } - - @Override - public RouteDefinition getRouteDefinition() { - return routeDefinition; - } - - @Override - public T getTargetRouteDefinition() { - return targetRoute; - } -} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ServiceDefinition.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ServiceDefinition.java new file mode 100644 index 00000000..ab6764bd --- /dev/null +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/ServiceDefinition.java @@ -0,0 +1,26 @@ +package com.gitee.sop.gatewaycommon.bean; + +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * @author tanghc + */ +@Data +public class ServiceDefinition { + + /** + * 服务名称,对应spring.application.name + */ + private String serviceId; + + public ServiceDefinition(String serviceId) { + this.serviceId = serviceId; + } + + public String fetchServiceIdLowerCase() { + return serviceId.toLowerCase(); + } +} \ No newline at end of file diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/TargetRoute.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/TargetRoute.java index f522d49a..32ea5569 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/TargetRoute.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/TargetRoute.java @@ -3,14 +3,14 @@ package com.gitee.sop.gatewaycommon.bean; /** * @author tanghc */ -public interface TargetRoute { +public interface TargetRoute { /** * 返回服务信息 * * @return 返回服务信息 */ - ServiceRouteInfo getServiceRouteInfo(); + ServiceDefinition getServiceDefinition(); /** * 返回微服务路由对象 @@ -19,10 +19,4 @@ public interface TargetRoute { */ RouteDefinition getRouteDefinition(); - /** - * 返回网关路由对象 - * - * @return 返回网关路由对象 - */ - T getTargetRouteDefinition(); } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/EnvGrayFilter.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/EnvGrayFilter.java index 84dbbed6..0bece971 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/EnvGrayFilter.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/EnvGrayFilter.java @@ -32,7 +32,7 @@ public class EnvGrayFilter implements GlobalFilter, Ordered { if (targetRoute == null) { return chain.filter(exchange); } - String serviceId = targetRoute.getServiceRouteInfo().fetchServiceIdLowerCase(); + String serviceId = targetRoute.getServiceDefinition().fetchServiceIdLowerCase(); // 如果服务在灰度阶段,返回一个灰度版本号 String version = envGrayManager.getVersion(serviceId, nameVersion); if (version != null && envGrayManager.containsKey(serviceId, apiParam.fetchAppKey())) { diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteCache.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteCache.java index 3e47b41c..abd7ecaa 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteCache.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteCache.java @@ -1,46 +1,88 @@ package com.gitee.sop.gatewaycommon.gateway.route; +import com.alibaba.fastjson.JSON; import com.gitee.sop.gatewaycommon.bean.RouteDefinition; +import com.gitee.sop.gatewaycommon.bean.ServiceDefinition; import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo; -import com.gitee.sop.gatewaycommon.manager.BaseRouteCache; +import com.gitee.sop.gatewaycommon.manager.RouteLoader; import com.gitee.sop.gatewaycommon.manager.RouteRepository; -import org.springframework.beans.BeanUtils; -import org.springframework.cloud.gateway.filter.FilterDefinition; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.DigestUtils; -import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Consumer; import java.util.stream.Collectors; /** * @author tanghc */ -public class GatewayRouteCache extends BaseRouteCache { +@Slf4j +public class GatewayRouteCache implements RouteLoader { + + /** + * KEY:serviceId, value: md5 + */ + private Map serviceIdMd5Map = new HashMap<>(); + + private RouteRepository routeRepository; public GatewayRouteCache(RouteRepository routeRepository) { - super(routeRepository); + this.routeRepository = routeRepository; } @Override - protected GatewayTargetRoute buildTargetRoute(ServiceRouteInfo serviceRouteInfo, RouteDefinition routeDefinition) { - org.springframework.cloud.gateway.route.RouteDefinition targetRoute = new org.springframework.cloud.gateway.route.RouteDefinition(); - targetRoute.setId(routeDefinition.getId()); - String path = routeDefinition.getPath(); - if (path != null && path.contains("{") && path.contains("}")) { - path = path.replace('{', '?'); - path = path.replace('}', '?'); + public void load(ServiceRouteInfo serviceRouteInfo, Consumer callback) { + try { + String serviceId = serviceRouteInfo.getServiceId(); + String newMd5 = buildMd5(serviceRouteInfo.getRouteDefinitionList()); + String oldMd5 = serviceIdMd5Map.get(serviceId); + if (Objects.equals(newMd5, oldMd5)) { + return; + } + serviceIdMd5Map.put(serviceId, newMd5); + + List routeDefinitionList = serviceRouteInfo.getRouteDefinitionList(); + for (RouteDefinition routeDefinition : routeDefinitionList) { + this.add(serviceId, routeDefinition); + if (log.isDebugEnabled()) { + log.debug("新增路由:{}", JSON.toJSONString(routeDefinition)); + } + } + this.routeRepository.refresh(); + callback.accept(null); + } catch (Exception e) { + log.error("加载路由信息失败,serviceRouteInfo:{}", serviceRouteInfo, e); } - targetRoute.setUri(URI.create(routeDefinition.getUri() + "/" + path)); - targetRoute.setOrder(routeDefinition.getOrder()); - // 添加过滤器 - List filterDefinitionList = routeDefinition.getFilters() - .stream() - .map(filter -> { - FilterDefinition filterDefinition = new FilterDefinition(); - BeanUtils.copyProperties(filter, filterDefinition); - return filterDefinition; - }) + } + + public void add(String serviceId, RouteDefinition routeDefinition) { + GatewayTargetRoute targetRoute = new GatewayTargetRoute(new ServiceDefinition(serviceId), routeDefinition); + routeRepository.add(targetRoute); + } + + /** + * 构建路由id MD5 + * + * @param routeDefinitionList 路由列表 + * @return 返回MD5 + */ + private String buildMd5(List routeDefinitionList) { + List routeIdList = routeDefinitionList.stream() + .map(JSON::toJSONString) + .sorted() .collect(Collectors.toList()); - return new GatewayTargetRoute(serviceRouteInfo, routeDefinition, targetRoute); + String md5Source = org.apache.commons.lang3.StringUtils.join(routeIdList, ""); + return DigestUtils.md5DigestAsHex(md5Source.getBytes(StandardCharsets.UTF_8)); + } + + @Override + public void remove(String serviceId) { + serviceIdMd5Map.remove(serviceId); + routeRepository.deleteAll(serviceId); } } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteRepository.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteRepository.java index b1aceee3..7ff6c428 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteRepository.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteRepository.java @@ -1,19 +1,15 @@ package com.gitee.sop.gatewaycommon.gateway.route; -import com.gitee.sop.gatewaycommon.bean.AbstractTargetRoute; import com.gitee.sop.gatewaycommon.bean.RouteDefinition; import com.gitee.sop.gatewaycommon.manager.RouteRepository; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.gateway.event.RefreshRoutesEvent; import org.springframework.cloud.gateway.route.Route; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.context.ApplicationContext; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.PathMatcher; import reactor.core.publisher.Flux; import java.util.Collection; @@ -32,8 +28,6 @@ import static java.util.Collections.synchronizedMap; @Slf4j public class GatewayRouteRepository implements RouteRepository, RouteLocator { - private final PathMatcher pathMatcher = new AntPathMatcher(); - private static final Map routes = synchronizedMap(new LinkedHashMap<>()); @Autowired @@ -56,7 +50,7 @@ public class GatewayRouteRepository implements RouteRepository routeDefinitionList = routes.values() .stream() - .map(AbstractTargetRoute::getRouteDefinition) + .map(GatewayTargetRoute::getRouteDefinition) .collect(Collectors.toList()); routeDefinitionList.forEach(routeDefinition -> builder.route(routeDefinition.getId(), r -> r.path(routeDefinition.getPath()) @@ -75,32 +69,7 @@ public class GatewayRouteRepository implements RouteRepository entry : routes.entrySet()) { - // /food/get/?id? - String pattern = entry.getKey(); - if (this.pathMatcher.match(pattern, id)) { - return clone(id, entry.getValue()); - } - } - return null; - } - - private GatewayTargetRoute clone(String path, GatewayTargetRoute gatewayTargetRoute) { - String prefix = "/" + gatewayTargetRoute.getServiceRouteInfo().getServiceId(); - if (path.startsWith(prefix)) { - path = path.substring(prefix.length()); - } - RouteDefinition routeDefinition = gatewayTargetRoute.getRouteDefinition(); - RouteDefinition newRouteDefinition = new RouteDefinition(); - BeanUtils.copyProperties(routeDefinition, newRouteDefinition); - newRouteDefinition.setPath(path); - return new GatewayTargetRoute(gatewayTargetRoute.getServiceRouteInfo() - , newRouteDefinition - , gatewayTargetRoute.getTargetRouteDefinition()); + return routes.get(id); } @@ -136,7 +105,7 @@ public class GatewayRouteRepository implements RouteRepository idList = routes.values().stream() - .filter(zuulTargetRoute -> StringUtils.equalsIgnoreCase(serviceId, zuulTargetRoute.getServiceRouteInfo().getServiceId())) + .filter(zuulTargetRoute -> StringUtils.equalsIgnoreCase(serviceId, zuulTargetRoute.getServiceDefinition().getServiceId())) .map(zuulTargetRoute -> zuulTargetRoute.getRouteDefinition().getId()) .collect(Collectors.toList()); diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayTargetRoute.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayTargetRoute.java index f2239305..8249da2a 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayTargetRoute.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayTargetRoute.java @@ -1,15 +1,30 @@ package com.gitee.sop.gatewaycommon.gateway.route; -import com.gitee.sop.gatewaycommon.bean.AbstractTargetRoute; import com.gitee.sop.gatewaycommon.bean.RouteDefinition; -import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo; +import com.gitee.sop.gatewaycommon.bean.ServiceDefinition; +import com.gitee.sop.gatewaycommon.bean.TargetRoute; /** * @author tanghc */ -public class GatewayTargetRoute extends AbstractTargetRoute { +public class GatewayTargetRoute implements TargetRoute { - public GatewayTargetRoute(ServiceRouteInfo serviceRouteInfo, RouteDefinition routeDefinition, org.springframework.cloud.gateway.route.RouteDefinition targetRoute) { - super(serviceRouteInfo, routeDefinition, targetRoute); + private ServiceDefinition serviceDefinition; + private RouteDefinition routeDefinition; + + + public GatewayTargetRoute(ServiceDefinition serviceDefinition, RouteDefinition routeDefinition) { + this.serviceDefinition = serviceDefinition; + this.routeDefinition = routeDefinition; + } + + @Override + public ServiceDefinition getServiceDefinition() { + return serviceDefinition; + } + + @Override + public RouteDefinition getRouteDefinition() { + return routeDefinition; } } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/BaseRouteCache.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/BaseRouteCache.java deleted file mode 100644 index 0c0ace23..00000000 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/manager/BaseRouteCache.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.gitee.sop.gatewaycommon.manager; - -import com.alibaba.fastjson.JSON; -import com.gitee.sop.gatewaycommon.bean.RouteDefinition; -import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo; -import com.gitee.sop.gatewaycommon.bean.TargetRoute; -import lombok.extern.slf4j.Slf4j; -import org.springframework.util.DigestUtils; - -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -/** - * @author tanghc - */ -@Slf4j -public abstract class BaseRouteCache implements RouteLoader { - - /** - * KEY:serviceId, value: md5 - */ - private Map serviceIdMd5Map = new HashMap<>(); - - private RouteRepository routeRepository; - - /** - * 构建目标路由对象,zuul和gateway定义的路由对象 - * - * @param serviceRouteInfo 路由服务对象 - * @param gatewayRouteDefinition 路由对象 - * @return 返回目标路由对象 - */ - protected abstract T buildTargetRoute(ServiceRouteInfo serviceRouteInfo, RouteDefinition gatewayRouteDefinition); - - public BaseRouteCache(RouteRepository routeRepository) { - this.routeRepository = routeRepository; - } - - @Override - public void load(ServiceRouteInfo serviceRouteInfo, Consumer callback) { - try { - String serviceId = serviceRouteInfo.getServiceId(); - String newMd5 = buildMd5(serviceRouteInfo.getRouteDefinitionList()); - String oldMd5 = serviceIdMd5Map.get(serviceId); - if (Objects.equals(newMd5, oldMd5)) { - return; - } - serviceIdMd5Map.put(serviceId, newMd5); - - List routeDefinitionList = serviceRouteInfo.getRouteDefinitionList(); - for (RouteDefinition routeDefinition : routeDefinitionList) { - T targetRoute = this.buildTargetRoute(serviceRouteInfo, routeDefinition); - routeRepository.add(targetRoute); - if (log.isDebugEnabled()) { - log.debug("新增路由:{}", JSON.toJSONString(routeDefinition)); - } - } - this.routeRepository.refresh(); - callback.accept(null); - } catch (Exception e) { - log.error("加载路由信息失败,serviceRouteInfo:{}", serviceRouteInfo, e); - } - } - - /** - * 构建路由id MD5 - * - * @param routeDefinitionList 路由列表 - * @return 返回MD5 - */ - private String buildMd5(List routeDefinitionList) { - List routeIdList = routeDefinitionList.stream() - .map(JSON::toJSONString) - .sorted() - .collect(Collectors.toList()); - String md5Source = org.apache.commons.lang3.StringUtils.join(routeIdList, ""); - return DigestUtils.md5DigestAsHex(md5Source.getBytes(StandardCharsets.UTF_8)); - } - - @Override - public void remove(String serviceId) { - serviceIdMd5Map.remove(serviceId); - routeRepository.deleteAll(serviceId); - } -} diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/BaseForwardChooser.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/BaseForwardChooser.java index 261742d2..258c759b 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/BaseForwardChooser.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/BaseForwardChooser.java @@ -24,7 +24,7 @@ public abstract class BaseForwardChooser implements ForwardChooser, ApiPar ApiParam apiParam = getApiParam(t); String nameVersion = apiParam.fetchNameVersion(); TargetRoute targetRoute = RouteRepositoryContext.getRouteRepository().get(nameVersion); - String serviceId = targetRoute.getServiceRouteInfo().fetchServiceIdLowerCase(); + String serviceId = targetRoute.getServiceDefinition().fetchServiceIdLowerCase(); // 如果服务在灰度阶段,返回一个灰度版本号 String grayVersion = envGrayManager.getVersion(serviceId, nameVersion); // 如果是灰度环境 diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/ServiceRouteListener.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/ServiceRouteListener.java index b466312e..68a1f07f 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/ServiceRouteListener.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/route/ServiceRouteListener.java @@ -3,7 +3,7 @@ package com.gitee.sop.gatewaycommon.route; import com.alibaba.fastjson.JSON; import com.gitee.sop.gatewaycommon.bean.InstanceDefinition; import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo; -import com.gitee.sop.gatewaycommon.manager.BaseRouteCache; +import com.gitee.sop.gatewaycommon.gateway.route.GatewayRouteCache; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -24,10 +24,8 @@ public class ServiceRouteListener extends BaseServiceListener { private static final String METADATA_SOP_ROUTES_PATH = "sop.routes.path"; - private static final String HEADER_RESTFUL = "restful"; - @Autowired - private BaseRouteCache baseRouteCache; + private GatewayRouteCache gatewayRouteCache; @Autowired private RoutesProcessor routesProcessor; @@ -35,7 +33,7 @@ public class ServiceRouteListener extends BaseServiceListener { @Override public void onRemoveService(String serviceId) { log.info("服务下线,删除路由配置,serviceId: {}", serviceId); - baseRouteCache.remove(serviceId); + gatewayRouteCache.remove(serviceId); routesProcessor.removeAllRoutes(serviceId); } @@ -48,7 +46,7 @@ public class ServiceRouteListener extends BaseServiceListener { if (responseEntity.getStatusCode() == HttpStatus.OK) { String body = responseEntity.getBody(); ServiceRouteInfo serviceRouteInfo = JSON.parseObject(body, ServiceRouteInfo.class); - baseRouteCache.load(serviceRouteInfo, callback -> routesProcessor.saveRoutes(serviceRouteInfo, instance)); + gatewayRouteCache.load(serviceRouteInfo, callback -> routesProcessor.saveRoutes(serviceRouteInfo, instance)); } else { log.error("拉取路由配置异常,url: {}, status: {}, body: {}", url, responseEntity.getStatusCodeValue(), responseEntity.getBody()); } diff --git a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java index 19093743..50ea7c08 100644 --- a/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java +++ b/sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/validate/ApiValidator.java @@ -129,7 +129,7 @@ public class ApiValidator implements Validator { } private void initFields(TargetRoute targetRoute, ApiParam apiParam) { - apiParam.setServiceId(targetRoute.getServiceRouteInfo().getServiceId()); + apiParam.setServiceId(targetRoute.getServiceDefinition().getServiceId()); boolean mergeResult; Boolean defaultSetting = ApiContext.getApiConfig().getMergeResult(); if (defaultSetting != null) { diff --git a/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigServiceRouteMapper.java b/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigServiceRouteMapper.java index 94a6137c..3fb317fa 100644 --- a/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigServiceRouteMapper.java +++ b/sop-gateway/src/main/java/com/gitee/sop/gateway/mapper/ConfigServiceRouteMapper.java @@ -7,5 +7,5 @@ import com.gitee.sop.gateway.entity.ConfigServiceRoute; /** * @author tanghc */ -public interface ConfigServiceRouteMapper extends CrudMapper { +public interface ConfigServiceRouteMapper extends CrudMapper { }