mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 21:57:56 +08:00
2.0
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
package com.gitee.sop.gatewaycommon.gateway.route;
|
||||
|
||||
import com.gitee.sop.gatewaycommon.bean.GatewayFilterDefinition;
|
||||
import com.gitee.sop.gatewaycommon.bean.GatewayPredicateDefinition;
|
||||
import com.gitee.sop.gatewaycommon.bean.RouteDefinition;
|
||||
import com.gitee.sop.gatewaycommon.bean.ServiceRouteInfo;
|
||||
import com.gitee.sop.gatewaycommon.manager.BaseRouteCache;
|
||||
@@ -11,9 +9,9 @@ import org.springframework.cloud.gateway.filter.FilterDefinition;
|
||||
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
@@ -25,45 +23,37 @@ public class GatewayRouteCache extends BaseRouteCache<GatewayTargetRoute> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GatewayTargetRoute buildRouteDefinition(ServiceRouteInfo serviceRouteInfo, RouteDefinition gatewayRouteDefinition) {
|
||||
org.springframework.cloud.gateway.route.RouteDefinition routeDefinition = new org.springframework.cloud.gateway.route.RouteDefinition();
|
||||
routeDefinition.setId(gatewayRouteDefinition.getId());
|
||||
routeDefinition.setUri(URI.create(gatewayRouteDefinition.getUri() + "#" + gatewayRouteDefinition.getPath()));
|
||||
routeDefinition.setOrder(gatewayRouteDefinition.getOrder());
|
||||
List<FilterDefinition> filterDefinitionList = new ArrayList<>(gatewayRouteDefinition.getFilters().size());
|
||||
LinkedList<PredicateDefinition> predicateDefinitionList = new LinkedList<>();
|
||||
for (GatewayFilterDefinition filter : gatewayRouteDefinition.getFilters()) {
|
||||
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());
|
||||
targetRoute.setUri(URI.create(routeDefinition.getUri() + "#" + routeDefinition.getPath()));
|
||||
targetRoute.setOrder(routeDefinition.getOrder());
|
||||
// 添加过滤器
|
||||
List<FilterDefinition> filterDefinitionList = routeDefinition.getFilters()
|
||||
.stream()
|
||||
.map(filter -> {
|
||||
FilterDefinition filterDefinition = new FilterDefinition();
|
||||
BeanUtils.copyProperties(filter, filterDefinition);
|
||||
filterDefinitionList.add(filterDefinition);
|
||||
}
|
||||
return filterDefinition;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (GatewayPredicateDefinition predicate : gatewayRouteDefinition.getPredicates()) {
|
||||
|
||||
LinkedList<PredicateDefinition> predicateDefinitionList = routeDefinition.getPredicates()
|
||||
.stream()
|
||||
.map(predicate -> {
|
||||
PredicateDefinition predicateDefinition = new PredicateDefinition();
|
||||
BeanUtils.copyProperties(predicate, predicateDefinition);
|
||||
predicateDefinitionList.add(predicateDefinition);
|
||||
}
|
||||
this.addPredicate(predicateDefinitionList, "NameVersion", gatewayRouteDefinition.getId());
|
||||
this.addPredicate(predicateDefinitionList, "ReadBody", "");
|
||||
routeDefinition.setFilters(filterDefinitionList);
|
||||
routeDefinition.setPredicates(predicateDefinitionList);
|
||||
return new GatewayTargetRoute(serviceRouteInfo, gatewayRouteDefinition, routeDefinition);
|
||||
return predicateDefinition;
|
||||
})
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
// 添加下面两个自定义的断言到顶部
|
||||
predicateDefinitionList.addFirst(new PredicateDefinition("NameVersion=" + routeDefinition.getId()));
|
||||
predicateDefinitionList.addFirst(new PredicateDefinition("ReadBody="));
|
||||
|
||||
targetRoute.setFilters(filterDefinitionList);
|
||||
targetRoute.setPredicates(predicateDefinitionList);
|
||||
return new GatewayTargetRoute(serviceRouteInfo, routeDefinition, targetRoute);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加断言
|
||||
*
|
||||
* @param predicateDefinitionList
|
||||
* @param name 断言名称
|
||||
* @param args 断言参数
|
||||
*/
|
||||
protected void addPredicate(LinkedList<PredicateDefinition> predicateDefinitionList, String name, String args) {
|
||||
for (PredicateDefinition predicateDefinition : predicateDefinitionList) {
|
||||
// 如果已经存在,直接返回
|
||||
if (predicateDefinition.getName().equals(name)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
predicateDefinitionList.addFirst(new PredicateDefinition(name + "=" + args));
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,6 @@ import com.gitee.sop.gatewaycommon.manager.RouteRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.cloud.gateway.event.PredicateArgsEvent;
|
||||
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
@@ -40,7 +39,6 @@ public class GatewayRouteRepository implements ApplicationEventPublisherAware,
|
||||
public Flux<org.springframework.cloud.gateway.route.RouteDefinition> getRouteDefinitions() {
|
||||
List<org.springframework.cloud.gateway.route.RouteDefinition> list = routes.values().parallelStream()
|
||||
.map(TargetRoute::getTargetRouteDefinition)
|
||||
.filter(routeDefinition -> !routeDefinition.getId().contains("_first.route_"))
|
||||
.collect(Collectors.toList());
|
||||
return Flux.fromIterable(list);
|
||||
}
|
||||
@@ -76,9 +74,8 @@ public class GatewayRouteRepository implements ApplicationEventPublisherAware,
|
||||
*/
|
||||
@Override
|
||||
public String add(GatewayTargetRoute targetRoute) {
|
||||
RouteDefinition baseRouteDefinition = targetRoute.getRouteDefinition();
|
||||
routes.put(baseRouteDefinition.getId(), targetRoute);
|
||||
this.publisher.publishEvent(new RefreshRoutesEvent(this));
|
||||
RouteDefinition routeDefinition = targetRoute.getRouteDefinition();
|
||||
routes.put(routeDefinition.getId(), targetRoute);
|
||||
return "success";
|
||||
}
|
||||
|
||||
|
@@ -17,6 +17,9 @@ import java.util.function.Predicate;
|
||||
/**
|
||||
* 此断言决定执行哪个路由
|
||||
*
|
||||
* 使用地方:
|
||||
* @see com.gitee.sop.gatewaycommon.gateway.route.GatewayRouteCache
|
||||
*
|
||||
* @author tanghc
|
||||
*/
|
||||
@Slf4j
|
||||
|
@@ -36,6 +36,10 @@ import static org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilt
|
||||
*
|
||||
* @see org.springframework.cloud.gateway.handler.predicate.ReadBodyPredicateFactory
|
||||
* 详见:https://blog.51cto.com/thinklili/2329184
|
||||
*
|
||||
* 使用地方:
|
||||
* @see com.gitee.sop.gatewaycommon.gateway.route.GatewayRouteCache
|
||||
*
|
||||
* @author tanghc
|
||||
*/
|
||||
public class ReadBodyRoutePredicateFactory extends AbstractRoutePredicateFactory<ReadBodyRoutePredicateFactory.Config> {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
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;
|
||||
@@ -31,7 +32,7 @@ public abstract class BaseRouteCache<T extends TargetRoute> implements RouteLoad
|
||||
* @param gatewayRouteDefinition 路由对象
|
||||
* @return 返回目标路由对象
|
||||
*/
|
||||
protected abstract T buildRouteDefinition(ServiceRouteInfo serviceRouteInfo, RouteDefinition gatewayRouteDefinition);
|
||||
protected abstract T buildTargetRoute(ServiceRouteInfo serviceRouteInfo, RouteDefinition gatewayRouteDefinition);
|
||||
|
||||
public BaseRouteCache(RouteRepository<T> routeRepository) {
|
||||
this.routeRepository = routeRepository;
|
||||
@@ -48,9 +49,12 @@ public abstract class BaseRouteCache<T extends TargetRoute> implements RouteLoad
|
||||
}
|
||||
serviceIdMd5Map.put(serviceId, newMd5);
|
||||
List<RouteDefinition> routeDefinitionList = serviceRouteInfo.getRouteDefinitionList();
|
||||
for (RouteDefinition gatewayRouteDefinition : routeDefinitionList) {
|
||||
T routeDefinition = this.buildRouteDefinition(serviceRouteInfo, gatewayRouteDefinition);
|
||||
routeRepository.add(routeDefinition);
|
||||
for (RouteDefinition routeDefinition : routeDefinitionList) {
|
||||
T targetRoute = this.buildTargetRoute(serviceRouteInfo, routeDefinition);
|
||||
routeRepository.add(targetRoute);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("新增路由:{}", JSON.toJSONString(routeDefinition));
|
||||
}
|
||||
}
|
||||
callback.accept(null);
|
||||
} catch (Exception e) {
|
||||
|
@@ -41,12 +41,6 @@ public class ServiceRoutesLoader<T extends TargetRoute> {
|
||||
@Autowired
|
||||
private NacosDiscoveryProperties nacosDiscoveryProperties;
|
||||
|
||||
// @NacosInjected
|
||||
// private NamingService namingService;
|
||||
|
||||
// @Autowired
|
||||
// private NacosConfigProperties nacosConfigProperties;
|
||||
|
||||
@NacosInjected
|
||||
private ConfigService configService;
|
||||
|
||||
|
@@ -20,7 +20,7 @@ public class ZuulRouteCache extends BaseRouteCache<ZuulTargetRoute> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ZuulTargetRoute buildRouteDefinition(ServiceRouteInfo serviceRouteInfo, RouteDefinition gatewayRouteDefinition) {
|
||||
protected ZuulTargetRoute buildTargetRoute(ServiceRouteInfo serviceRouteInfo, RouteDefinition gatewayRouteDefinition) {
|
||||
Route route = new Route(
|
||||
gatewayRouteDefinition.getId()
|
||||
, gatewayRouteDefinition.getPath()
|
||||
|
@@ -2,7 +2,6 @@ package com.gitee.sop.servercommon.manager;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.gitee.sop.servercommon.bean.ServiceApiInfo;
|
||||
import com.gitee.sop.servercommon.route.GatewayPredicateDefinition;
|
||||
import com.gitee.sop.servercommon.route.RouteDefinition;
|
||||
import com.gitee.sop.servercommon.route.ServiceRouteInfo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -13,7 +12,6 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -33,13 +31,7 @@ public class ServiceRouteInfoBuilder {
|
||||
|
||||
private static final String DEFAULT_CONTEXT_PATH = "/";
|
||||
|
||||
/**
|
||||
* NameVersion=alipay.story.get1.0
|
||||
* see com.gitee.sop.gatewaycommon.routeDefinition.NameVersionRoutePredicateFactory
|
||||
*/
|
||||
private static String QUERY_PREDICATE_DEFINITION_TPL = "NameVersion=%s";
|
||||
|
||||
private static ServiceApiInfo.ApiMeta FIRST_API_META = new ServiceApiInfo.ApiMeta("_first.route_", "/", "v_000");
|
||||
private static ServiceApiInfo.ApiMeta FIRST_API_META = new ServiceApiInfo.ApiMeta("_first_route_", "/", "1.0.0");
|
||||
|
||||
private Environment environment;
|
||||
|
||||
@@ -59,8 +51,9 @@ public class ServiceRouteInfoBuilder {
|
||||
*/
|
||||
protected ServiceRouteInfo buildServiceGatewayInfo(ServiceApiInfo serviceApiInfo) {
|
||||
List<ServiceApiInfo.ApiMeta> apis = serviceApiInfo.getApis();
|
||||
List<RouteDefinition> routeDefinitionList = new ArrayList<>(apis.size());
|
||||
routeDefinitionList.add(this.buildReadBodyRouteDefinition(serviceApiInfo));
|
||||
List<RouteDefinition> routeDefinitionList = new ArrayList<>(apis.size() + 1);
|
||||
// 在第一个位置放一个没用的路由,SpringCloudGateway会从第二个路由开始找,原因不详
|
||||
routeDefinitionList.add(this.getFirstRoute(serviceApiInfo));
|
||||
for (ServiceApiInfo.ApiMeta apiMeta : apis) {
|
||||
RouteDefinition gatewayRouteDefinition = this.buildGatewayRouteDefinition(serviceApiInfo, apiMeta);
|
||||
routeDefinitionList.add(gatewayRouteDefinition);
|
||||
@@ -73,6 +66,17 @@ public class ServiceRouteInfoBuilder {
|
||||
return serviceRouteInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加com.gitee.sop.gatewaycommon.routeDefinition.ReadBodyRoutePredicateFactory,解决form表单获取不到问题
|
||||
*
|
||||
* @return 返回路由定义
|
||||
*/
|
||||
protected RouteDefinition getFirstRoute(ServiceApiInfo serviceApiInfo) {
|
||||
RouteDefinition firstRoute = this.buildGatewayRouteDefinition(serviceApiInfo, FIRST_API_META);
|
||||
firstRoute.setOrder(Integer.MIN_VALUE);
|
||||
return firstRoute;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建路由id MD5
|
||||
*
|
||||
@@ -89,43 +93,19 @@ public class ServiceRouteInfoBuilder {
|
||||
}
|
||||
|
||||
protected RouteDefinition buildGatewayRouteDefinition(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) {
|
||||
RouteDefinition gatewayRouteDefinition = new RouteDefinition();
|
||||
RouteDefinition routeDefinition = new RouteDefinition();
|
||||
// 唯一id规则:接口名 + 版本号
|
||||
String routeId = apiMeta.fetchNameVersion();
|
||||
this.checkPath(routeId, "接口定义(" + routeId + ")不能有斜杠字符'/'");
|
||||
BeanUtils.copyProperties(apiMeta, gatewayRouteDefinition);
|
||||
gatewayRouteDefinition.setId(routeId);
|
||||
gatewayRouteDefinition.setFilters(Collections.emptyList());
|
||||
gatewayRouteDefinition.setPredicates(this.buildPredicates(apiMeta));
|
||||
BeanUtils.copyProperties(apiMeta, routeDefinition);
|
||||
routeDefinition.setId(routeId);
|
||||
routeDefinition.setFilters(Collections.emptyList());
|
||||
routeDefinition.setPredicates(Collections.emptyList());
|
||||
String uri = this.buildUri(serviceApiInfo, apiMeta);
|
||||
String path = this.buildServletPath(serviceApiInfo, apiMeta);
|
||||
gatewayRouteDefinition.setUri(uri);
|
||||
gatewayRouteDefinition.setPath(path);
|
||||
return gatewayRouteDefinition;
|
||||
}
|
||||
|
||||
protected List<GatewayPredicateDefinition> buildPredicates(ServiceApiInfo.ApiMeta apiMeta) {
|
||||
GatewayPredicateDefinition gatewayPredicateDefinition = new GatewayPredicateDefinition();
|
||||
gatewayPredicateDefinition.setName("ReadBody");
|
||||
return Arrays.asList(gatewayPredicateDefinition, this.buildNameVersionPredicateDefinition(apiMeta));
|
||||
}
|
||||
|
||||
protected GatewayPredicateDefinition buildNameVersionPredicateDefinition(ServiceApiInfo.ApiMeta apiMeta) {
|
||||
return new GatewayPredicateDefinition(String.format(QUERY_PREDICATE_DEFINITION_TPL, apiMeta.fetchNameVersion()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加com.gitee.sop.gatewaycommon.routeDefinition.ReadBodyRoutePredicateFactory,解决form表单获取不到问题
|
||||
*
|
||||
* @return 返回路由定义
|
||||
*/
|
||||
protected RouteDefinition buildReadBodyRouteDefinition(ServiceApiInfo serviceApiInfo) {
|
||||
RouteDefinition readBodyRouteDefinition = this.buildGatewayRouteDefinition(serviceApiInfo, FIRST_API_META);
|
||||
readBodyRouteDefinition.setOrder(Integer.MIN_VALUE);
|
||||
|
||||
readBodyRouteDefinition.setPredicates(this.buildPredicates(FIRST_API_META));
|
||||
|
||||
return readBodyRouteDefinition;
|
||||
routeDefinition.setUri(uri);
|
||||
routeDefinition.setPath(path);
|
||||
return routeDefinition;
|
||||
}
|
||||
|
||||
protected String buildUri(ServiceApiInfo serviceApiInfo, ServiceApiInfo.ApiMeta apiMeta) {
|
||||
|
@@ -2,7 +2,6 @@ package com.gitee.sop.servercommon.route;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -28,12 +27,12 @@ public class RouteDefinition {
|
||||
/**
|
||||
* 路由断言集合配置
|
||||
*/
|
||||
private List<GatewayPredicateDefinition> predicates = new ArrayList<>();
|
||||
private List<GatewayPredicateDefinition> predicates;
|
||||
|
||||
/**
|
||||
* 路由过滤器集合配置
|
||||
*/
|
||||
private List<GatewayFilterDefinition> filters = new ArrayList<>();
|
||||
private List<GatewayFilterDefinition> filters;
|
||||
|
||||
/**
|
||||
* 路由规则转发的目标uri
|
||||
|
@@ -57,3 +57,5 @@ spring.servlet.multipart.max-request-size=20MB
|
||||
spring.zipkin.base-url=${zipkin.url}
|
||||
# 设置sleuth收集信息的比率,默认0.1,最大是1,数字越大越耗性能
|
||||
spring.sleuth.sampler.probability=1
|
||||
|
||||
logging.level.com.gitee=debug
|
@@ -126,6 +126,45 @@ biz_content String 是 请求参数的集合,最大长度不限,除公共
|
||||
bizContent.put("name", "葫芦娃");
|
||||
// bizContent.put("name", "葫芦娃1234567890葫芦娃1234567890"); // 超出长度
|
||||
|
||||
params.put("biz_content", JSON.toJSONString(bizContent));
|
||||
|
||||
System.out.println("----------- 请求信息 -----------");
|
||||
System.out.println("请求参数:" + buildParamQuery(params));
|
||||
System.out.println("商户秘钥:" + privateKey);
|
||||
String content = AlipaySignature.getSignContent(params);
|
||||
System.out.println("待签名内容:" + content);
|
||||
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
|
||||
System.out.println("签名(sign):" + sign);
|
||||
|
||||
params.put("sign", sign);
|
||||
|
||||
System.out.println("----------- 返回结果 -----------");
|
||||
String responseData = post(url, params);// 发送请求
|
||||
System.out.println(responseData);
|
||||
}
|
||||
|
||||
public void testPost2() throws Exception {
|
||||
|
||||
// 公共请求参数
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("app_id", appId);
|
||||
params.put("method", "alipay.category.get");
|
||||
params.put("format", "json");
|
||||
params.put("charset", "utf-8");
|
||||
params.put("sign_type", "RSA2");
|
||||
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
params.put("version", "1.0");
|
||||
|
||||
// 业务参数
|
||||
Map<String, Object> bizContent = new HashMap<>();
|
||||
bizContent.put("categoryName", "啊啊啊");
|
||||
Map<String, String> storyParam = new HashMap<>();
|
||||
storyParam.put("id", "1");
|
||||
storyParam.put("name", "葫芦娃啊啊啊");
|
||||
bizContent.put("storyParam", storyParam);
|
||||
|
||||
|
||||
|
||||
params.put("biz_content", JSON.toJSONString(bizContent));
|
||||
|
||||
System.out.println("----------- 请求信息 -----------");
|
||||
|
Reference in New Issue
Block a user