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; |
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.RouteDefinition; |
||||||
|
import com.gitee.sop.gatewaycommon.bean.ServiceDefinition; |
||||||
import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo; |
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 com.gitee.sop.gatewaycommon.manager.RouteRepository; |
||||||
import org.springframework.beans.BeanUtils; |
import lombok.extern.slf4j.Slf4j; |
||||||
import org.springframework.cloud.gateway.filter.FilterDefinition; |
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.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Objects; |
||||||
|
import java.util.function.Consumer; |
||||||
import java.util.stream.Collectors; |
import java.util.stream.Collectors; |
||||||
|
|
||||||
/** |
/** |
||||||
* @author tanghc |
* @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) { |
public GatewayRouteCache(RouteRepository<GatewayTargetRoute> routeRepository) { |
||||||
super(routeRepository); |
this.routeRepository = routeRepository; |
||||||
} |
} |
||||||
|
|
||||||
@Override |
@Override |
||||||
protected GatewayTargetRoute buildTargetRoute(ServiceRouteInfo serviceRouteInfo, RouteDefinition routeDefinition) { |
public void load(ServiceRouteInfo serviceRouteInfo, Consumer<Object> callback) { |
||||||
org.springframework.cloud.gateway.route.RouteDefinition targetRoute = new org.springframework.cloud.gateway.route.RouteDefinition(); |
try { |
||||||
targetRoute.setId(routeDefinition.getId()); |
String serviceId = serviceRouteInfo.getServiceId(); |
||||||
String path = routeDefinition.getPath(); |
String newMd5 = buildMd5(serviceRouteInfo.getRouteDefinitionList()); |
||||||
if (path != null && path.contains("{") && path.contains("}")) { |
String oldMd5 = serviceIdMd5Map.get(serviceId); |
||||||
path = path.replace('{', '?'); |
if (Objects.equals(newMd5, oldMd5)) { |
||||||
path = path.replace('}', '?'); |
return; |
||||||
} |
} |
||||||
targetRoute.setUri(URI.create(routeDefinition.getUri() + "/" + path)); |
serviceIdMd5Map.put(serviceId, newMd5); |
||||||
targetRoute.setOrder(routeDefinition.getOrder()); |
|
||||||
// 添加过滤器
|
List<RouteDefinition> routeDefinitionList = serviceRouteInfo.getRouteDefinitionList(); |
||||||
List<FilterDefinition> filterDefinitionList = routeDefinition.getFilters() |
for (RouteDefinition routeDefinition : routeDefinitionList) { |
||||||
.stream() |
this.add(serviceId, routeDefinition); |
||||||
.map(filter -> { |
if (log.isDebugEnabled()) { |
||||||
FilterDefinition filterDefinition = new FilterDefinition(); |
log.debug("新增路由:{}", JSON.toJSONString(routeDefinition)); |
||||||
BeanUtils.copyProperties(filter, filterDefinition); |
} |
||||||
return filterDefinition; |
} |
||||||
}) |
this.routeRepository.refresh(); |
||||||
|
callback.accept(null); |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("加载路由信息失败,serviceRouteInfo:{}", serviceRouteInfo, e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
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()); |
.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; |
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.RouteDefinition; |
||||||
import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo; |
import com.gitee.sop.gatewaycommon.bean.ServiceDefinition; |
||||||
|
import com.gitee.sop.gatewaycommon.bean.TargetRoute; |
||||||
|
|
||||||
/** |
/** |
||||||
* @author tanghc |
* @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) { |
private ServiceDefinition serviceDefinition; |
||||||
super(serviceRouteInfo, routeDefinition, targetRoute); |
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