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