Search in sources :

Example 1 with Rule

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;
}
Also used : ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) MatchRule(com.huawei.route.common.gray.label.entity.MatchRule) Rule(com.huawei.route.common.gray.label.entity.Rule)

Example 2 with Rule

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;
}
Also used : GrayConfiguration(com.huawei.route.common.gray.label.entity.GrayConfiguration) Rule(com.huawei.route.common.gray.label.entity.Rule) Route(com.huawei.route.common.gray.label.entity.Route)

Example 3 with Rule

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;
}
Also used : ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) MatchRule(com.huawei.route.common.gray.label.entity.MatchRule) Rule(com.huawei.route.common.gray.label.entity.Rule) Route(com.huawei.route.common.gray.label.entity.Route)

Example 4 with Rule

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();
}
Also used : ArrayList(java.util.ArrayList) List(java.util.List) MatchRule(com.huawei.route.common.gray.label.entity.MatchRule) Rule(com.huawei.route.common.gray.label.entity.Rule) ValueMatch(com.huawei.route.common.gray.label.entity.ValueMatch) Match(com.huawei.route.common.gray.label.entity.Match)

Example 5 with Rule

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;
    }
}
Also used : Instances(com.huawei.route.common.gray.addr.entity.Instances) GrayConfig(com.huawei.route.common.gray.config.GrayConfig) Request(feign.Request) GrayConfiguration(com.huawei.route.common.gray.label.entity.GrayConfiguration) FeignResolvedUrl(com.huawei.gray.feign.context.FeignResolvedUrl) RuleType(com.huawei.gray.feign.rule.RuleType) Rule(com.huawei.route.common.gray.label.entity.Rule) URL(java.net.URL) Route(com.huawei.route.common.gray.label.entity.Route)

Aggregations

Rule (com.huawei.route.common.gray.label.entity.Rule)7 GrayConfiguration (com.huawei.route.common.gray.label.entity.GrayConfiguration)4 Route (com.huawei.route.common.gray.label.entity.Route)4 List (java.util.List)4 MatchRule (com.huawei.route.common.gray.label.entity.MatchRule)3 ArrayList (java.util.ArrayList)3 RuleStrategyEnum (com.huawei.gray.dubbo.strategy.RuleStrategyEnum)1 FeignResolvedUrl (com.huawei.gray.feign.context.FeignResolvedUrl)1 RuleType (com.huawei.gray.feign.rule.RuleType)1 Instances (com.huawei.route.common.gray.addr.entity.Instances)1 GrayConfig (com.huawei.route.common.gray.config.GrayConfig)1 Match (com.huawei.route.common.gray.label.entity.Match)1 ValueMatch (com.huawei.route.common.gray.label.entity.ValueMatch)1 Request (feign.Request)1 URL (java.net.URL)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 URL (org.apache.dubbo.common.URL)1 Invocation (org.apache.dubbo.rpc.Invocation)1 Invoker (org.apache.dubbo.rpc.Invoker)1