parent
							
								
									45ceebc34b
								
							
						
					
					
						commit
						7468ce3524
					
				| @ -1,32 +0,0 @@ | ||||
| package com.gitee.sop.gatewaycommon.bean; | ||||
| 
 | ||||
| /** | ||||
|  * @author tanghc | ||||
|  */ | ||||
| public abstract class AbstractTargetRoute<T> implements TargetRoute<T> { | ||||
| 
 | ||||
|     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; | ||||
|     } | ||||
| } | ||||
| @ -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(); | ||||
|     } | ||||
| } | ||||
| @ -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<GatewayTargetRoute> { | ||||
| @Slf4j | ||||
| public class GatewayRouteCache implements RouteLoader { | ||||
| 
 | ||||
|     /** | ||||
|      * KEY:serviceId, value: md5 | ||||
|      */ | ||||
|     private Map<String, String> serviceIdMd5Map = new HashMap<>(); | ||||
| 
 | ||||
|     private RouteRepository<GatewayTargetRoute> routeRepository; | ||||
| 
 | ||||
|     public GatewayRouteCache(RouteRepository<GatewayTargetRoute> 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<Object> 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<RouteDefinition> 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<FilterDefinition> 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<RouteDefinition> routeDefinitionList) { | ||||
|         List<String> 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); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -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<org.springframework.cloud.gateway.route.RouteDefinition> { | ||||
| 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; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -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<T extends TargetRoute> implements RouteLoader { | ||||
| 
 | ||||
|     /** | ||||
|      * KEY:serviceId, value: md5 | ||||
|      */ | ||||
|     private Map<String, String> serviceIdMd5Map = new HashMap<>(); | ||||
| 
 | ||||
|     private RouteRepository<T> routeRepository; | ||||
| 
 | ||||
|     /** | ||||
|      * 构建目标路由对象,zuul和gateway定义的路由对象 | ||||
|      * | ||||
|      * @param serviceRouteInfo       路由服务对象 | ||||
|      * @param gatewayRouteDefinition 路由对象 | ||||
|      * @return 返回目标路由对象 | ||||
|      */ | ||||
|     protected abstract T buildTargetRoute(ServiceRouteInfo serviceRouteInfo, RouteDefinition gatewayRouteDefinition); | ||||
| 
 | ||||
|     public BaseRouteCache(RouteRepository<T> routeRepository) { | ||||
|         this.routeRepository = routeRepository; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void load(ServiceRouteInfo serviceRouteInfo, Consumer<Object> 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<RouteDefinition> 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<RouteDefinition> routeDefinitionList) { | ||||
|         List<String> 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); | ||||
|     } | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue