use of com.huawei.route.common.gray.label.entity.Rule in project Sermant by huaweicloud.
the class RouterUtil method getValidRules.
/**
* 获取合法的目标规则
*
* @param grayConfiguration 标签
* @param targetService 目标服务
* @param interfaceName 接口
* @return 目标规则
*/
public static List<Rule> getValidRules(GrayConfiguration grayConfiguration, String targetService, String interfaceName) {
if (GrayConfiguration.isInValid(grayConfiguration)) {
return Collections.emptyList();
}
Map<String, List<Rule>> routeRule = grayConfiguration.getRouteRule();
if (CollectionUtils.isEmpty(routeRule) || CollectionUtils.isEmpty(routeRule.get(targetService))) {
return Collections.emptyList();
}
List<Rule> list = new ArrayList<>();
for (Rule rule : routeRule.get(targetService)) {
if (isInvalidRule(rule, interfaceName)) {
continue;
}
// 去掉无效的规则
removeInvalidRules(rule.getMatch().getArgs());
// 去掉无效的路由
removeInvalidRoute(rule.getRoute());
list.add(rule);
}
list.sort(Comparator.comparingInt(Rule::getPrecedence));
return list;
}
use of com.huawei.route.common.gray.label.entity.Rule in project Sermant by huaweicloud.
the class AbstractDirectoryServiceImpl method selectInvokers.
/**
* 筛选灰度invoker
*
* @param obj RegistryDirectory
* @param arguments 参数
* @param result invokers
* @return invokers
* @see com.alibaba.dubbo.registry.integration.RegistryDirectory
* @see org.apache.dubbo.registry.integration.RegistryDirectory
* @see com.alibaba.dubbo.rpc.Invoker
* @see org.apache.dubbo.rpc.Invoker
*/
@Override
public Object selectInvokers(Object obj, Object[] arguments, Object result) {
if (arguments != null && arguments.length > 0) {
GrayConfiguration grayConfiguration = LabelCache.getLabel(GrayConstant.GRAY_LABEL_CACHE_NAME);
if (GrayConfiguration.isInValid(grayConfiguration)) {
return result;
}
Map<String, String> queryMap = ReflectUtils.getQueryMap(obj);
if (CollectionUtils.isEmpty(queryMap)) {
return result;
}
if (!CONSUMER_VALUE.equals(queryMap.get(CONSUMER_KEY))) {
return result;
}
String serviceInterface = queryMap.get(INTERFACE_KEY);
Object invocation = arguments[0];
String interfaceName = serviceInterface + "." + ReflectUtils.getMethodName(invocation);
String targetService = DubboCache.INSTANCE.getApplication(serviceInterface);
List<Rule> rules = RouterUtil.getValidRules(grayConfiguration, targetService, interfaceName);
List<Route> routes = RouterUtil.getRoutes(rules, ReflectUtils.getArguments(invocation));
if (CollectionUtils.isEmpty(routes)) {
return result;
}
return RuleStrategyHandler.WEIGHT.getTargetInvoker(routes, (List<Object>) result, grayConfiguration.getVersionFrom());
}
return result;
}
use of com.huawei.route.common.gray.label.entity.Rule in project Sermant by huaweicloud.
the class RouterUtil method getValidRules.
/**
* 获取有效规则
*
* @param grayConfiguration 灰度配置
* @param targetService 目标服务
* @param path 请求路径
* @return 有效规则
*/
public static List<Rule> getValidRules(GrayConfiguration grayConfiguration, String targetService, String path) {
if (GrayConfiguration.isInValid(grayConfiguration)) {
return Collections.emptyList();
}
Map<String, List<Rule>> routeRule = grayConfiguration.getRouteRule();
if (CollectionUtils.isEmpty(routeRule) || CollectionUtils.isEmpty(routeRule.get(targetService))) {
return Collections.emptyList();
}
List<Rule> list = new ArrayList<Rule>();
for (Rule rule : routeRule.get(targetService)) {
if (!isValidRule(rule, CurrentInstance.getInstance().getAppName(), path)) {
continue;
}
// 去掉无效的规则
Map<String, List<MatchRule>> headerRules = rule.getMatch().getHeaders();
if (headerRules != null) {
removeInValidRules(headerRules);
rule.getMatch().setHeaders(headerRules);
}
Map<String, List<MatchRule>> paramRules = rule.getMatch().getParameters();
if (paramRules != null) {
removeInValidRules(paramRules);
rule.getMatch().setParameters(paramRules);
}
Map<String, List<MatchRule>> cookieRules = rule.getMatch().getCookie();
if (cookieRules != null) {
removeInValidRules(cookieRules);
rule.getMatch().setCookie(cookieRules);
}
// 去掉无效的路由
Iterator<Route> routeIterator = rule.getRoute().iterator();
while (routeIterator.hasNext()) {
if (isInValidRoute(routeIterator.next())) {
routeIterator.remove();
}
}
list.add(rule);
}
Collections.sort(list, new Comparator<Rule>() {
@Override
public int compare(Rule o1, Rule o2) {
return o1.getPrecedence() - o2.getPrecedence();
}
});
return list;
}
use of com.huawei.route.common.gray.label.entity.Rule in project Sermant by huaweicloud.
the class RouterUtil method getRoutes.
/**
* 获取路由
*
* @param list 规则列表
* @param request 请求
* @return 路由
*/
public static List<Route> getRoutes(List<Rule> list, Request request) {
// 支持headers,parameters和cookie三种参数匹配方式且允许同时配置,全匹配应满足所有三种匹配方式规则
for (Rule rule : list) {
Match match = rule.getMatch();
boolean isFullMatch = match.isFullMatch();
// headers 参数匹配
Map<String, List<MatchRule>> headerRules = match.getHeaders();
boolean isMatchByHeader = true;
if (headerRules != null) {
isMatchByHeader = isMatchHeaderRule(headerRules, isFullMatch, request);
}
// parameters 参数匹配
Map<String, List<MatchRule>> paramRules = match.getParameters();
boolean isMatchByParam = true;
if (paramRules != null) {
isMatchByParam = isMatchParamRule(paramRules, isFullMatch, request);
}
// cookie 参数匹配
Map<String, List<MatchRule>> cookieRules = match.getCookie();
boolean isMatchByCookie = true;
if (cookieRules != null) {
isMatchByCookie = isMatchCookieRule(cookieRules, isFullMatch, request);
}
if (headerRules == null && paramRules == null && cookieRules == null) {
continue;
}
// 全匹配需要三种配置都匹配上
if (isFullMatch && isMatchByHeader && isMatchByParam && isMatchByCookie) {
return rule.getRoute();
}
// 非全匹配只要其中一种规则匹配上即可
if (!isFullMatch && (isMatchByHeader || isMatchByParam || isMatchByCookie)) {
return rule.getRoute();
}
}
return Collections.emptyList();
}
use of com.huawei.route.common.gray.label.entity.Rule in project Sermant by huaweicloud.
the class DefaultHttpClientServiceImpl method before.
@Override
public void before(Object obj, Method method, Object[] arguments, BeforeResult beforeResult) throws Exception {
GrayConfig grayConfig = PluginConfigManager.getPluginConfig(GrayConfig.class);
Request request = (Request) arguments[0];
String targetAppName = HostContext.get();
// 根据灰度规则重构请求地址
GrayConfiguration grayConfiguration = LabelCache.getLabel(grayConfig.getSpringCloudKey());
if (GrayConfiguration.isInValid(grayConfiguration)) {
return;
}
// 获得url路径参数解析前的原始path
URL url = new URL(request.url());
String path = url.getPath();
FeignResolvedUrl feignResolvedUrl = PathVarServiceImpl.URL_CONTEXT.get();
if (feignResolvedUrl != null) {
try {
path = path.replace(feignResolvedUrl.getUrl().split("[?]")[0], feignResolvedUrl.getOriginUrl()).split("[?]")[0];
} finally {
PathVarServiceImpl.URL_CONTEXT.remove();
}
}
// 获取匹配规则并替换url
List<Rule> rules = RouterUtil.getValidRules(grayConfiguration, targetAppName, path);
List<Route> routes = RouterUtil.getRoutes(rules, request);
RuleType ruleType = CollectionUtils.isEmpty(routes) ? RuleType.UPSTREAM : RuleType.WEIGHT;
Instances instance = ruleType.getTargetServiceInstance(routes, targetAppName, request.headers());
if (instance != null) {
String targetServiceHost = RouterUtil.getTargetHost(instance).orElse(null);
String version = instance.getCurrentTag().getVersion();
request = RouterUtil.rebuildUrl(targetServiceHost, version, request);
arguments[0] = request;
}
}
Aggregations