예제 #1
0
  static Map<Long, RouteRule> route2RouteRule(
      List<Route> routes, Map<String, List<String>> clusters) {
    Map<Long, RouteRule> rules = new HashMap<Long, RouteRule>();
    // route -> RouteRule
    if (routes != null && routes.size() > 0) {
      for (Route route : routes) {
        rules.put(route.getId(), RouteRule.parseQuitely(route));
      }
    }
    // expand the cluster parameters into conditions of routerule
    if (clusters != null && clusters.size() > 0) {
      Map<Long, RouteRule> rrs = new HashMap<Long, RouteRule>();
      for (Map.Entry<Long, RouteRule> entry : rules.entrySet()) {
        RouteRule rr = entry.getValue();

        Map<String, RouteRule.MatchPair> when =
            RouteRuleUtils.expandCondition(
                rr.getWhenCondition(), "consumer.cluster", "consumer.host", clusters);
        Map<String, RouteRule.MatchPair> then =
            RouteRuleUtils.expandCondition(
                rr.getThenCondition(), "provider.cluster", "provider.host", clusters);

        rrs.put(entry.getKey(), RouteRule.createFromCondition(when, then));
      }
      rules = rrs;
    }
    return rules;
  }
예제 #2
0
  public static boolean matchRoute(
      String consumerAddress,
      String consumerQueryUrl,
      Route route,
      Map<String, List<String>> clusters) {
    RouteRule rule = RouteRule.parseQuitely(route);
    Map<String, RouteRule.MatchPair> when =
        RouteRuleUtils.expandCondition(
            rule.getWhenCondition(), "consumer.cluster", "consumer.host", clusters);
    Map<String, String> consumerSample = ParseUtils.parseQuery("consumer.", consumerQueryUrl);

    final int index = consumerAddress.lastIndexOf(":");
    String consumerHost = null;
    if (index != -1) {
      consumerHost = consumerAddress.substring(0, index);
    } else {
      consumerHost = consumerAddress;
    }
    consumerSample.put("consumer.host", consumerHost);

    return RouteRuleUtils.isMatchCondition(when, consumerSample, consumerSample);
  }
예제 #3
0
  static Map<String, Map<String, String>> getUrlsMatchedCondition(
      Map<String, RouteRule.MatchPair> condition,
      Map<String, String> parameters,
      Map<String, Map<String, String>> url2Sample) {
    Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>();
    for (Map.Entry<String, Map<String, String>> entry : url2Sample.entrySet()) {
      Map<String, String> sample = entry.getValue();

      Map<String, String> params = new HashMap<String, String>();
      params.putAll(sample);
      params.putAll(parameters);

      if (RouteRuleUtils.isMatchCondition(condition, params, sample)) {
        result.put(entry.getKey(), entry.getValue());
      }
    }
    return result;
  }
예제 #4
0
 static Route getFirstRouteMatchedWhenConditionOfRule(
     String serviceName,
     Map<String, String> consumerSample,
     List<Route> routes,
     Map<Long, RouteRule> routeRuleMap) {
   if (serviceName == null || serviceName.length() == 0) {
     return null;
   }
   if (routes != null && routes.size() > 0) {
     for (Route route : routes) {
       if (isSerivceNameMatched(route.getService(), serviceName)) {
         RouteRule rule = routeRuleMap.get(route.getId());
         // 当满足when条件时
         if (rule != null
             && RouteRuleUtils.isMatchCondition(
                 rule.getWhenCondition(), consumerSample, consumerSample)) {
           return route; // 第一个满足即返回
         }
       }
     }
   }
   return null;
 }
예제 #5
0
  // FIXME clusters和routes的合并,可以在clusters或routes变化时预先做
  // FIXME 从Util方法中分离出Cache的操作
  public static Map<String, String> route(
      String serviceName,
      String consumerAddress,
      String consumerQueryUrl,
      Map<String, String> serviceUrls,
      List<Route> routes,
      Map<String, List<String>> clusters,
      List<Route> routed) {
    if (serviceUrls == null || serviceUrls.size() == 0) {
      return serviceUrls;
    }
    if (routes == null || routes.isEmpty()) {
      return serviceUrls;
    }

    Map<Long, RouteRule> rules = route2RouteRule(routes, clusters);

    final Map<String, String> consumerSample = ParseUtils.parseQuery("consumer.", consumerQueryUrl);
    final int index = consumerAddress.lastIndexOf(":");
    final String consumerHost;
    if (consumerAddress != null && index != -1) {
      consumerHost = consumerAddress.substring(0, index);
    } else {
      consumerHost = consumerAddress;
    }
    consumerSample.put("consumer.host", consumerHost);

    Map<String, Map<String, String>> url2ProviderSample =
        new HashMap<String, Map<String, String>>();
    for (Map.Entry<String, String> entry : serviceUrls.entrySet()) {
      URI uri;
      try {
        uri = new URI(entry.getKey());
      } catch (URISyntaxException e) {
        throw new IllegalStateException(
            "fail to parse url(" + entry.getKey() + "):" + e.getMessage(), e);
      }
      Map<String, String> sample = new HashMap<String, String>();
      sample.putAll(ParseUtils.parseQuery("provider.", entry.getValue()));
      sample.put("provider.protocol", uri.getScheme());
      sample.put("provider.host", uri.getHost());
      sample.put("provider.port", String.valueOf(uri.getPort()));

      url2ProviderSample.put(entry.getKey(), sample);
    }

    Map<String, Set<String>> url2Methods = new HashMap<String, Set<String>>();

    // consumer可以通过consumer.methods Key指定需要的方法
    String methodsString = consumerSample.get("consumer.methods");
    String[] methods =
        methodsString == null || methodsString.length() == 0
            ? new String[] {Route.ALL_METHOD}
            : methodsString.split(ParseUtils.METHOD_SPLIT);
    for (String method : methods) {
      consumerSample.put("method", method);
      // NOTE:
      // <*方法>只配置 <no method key>
      // method1方法匹配 <no method key> 和 <method = method1>, 此时要把<no method key>的Route的优先级降低即可
      if (routes != null && routes.size() > 0) {
        for (Route route : routes) {
          if (isSerivceNameMatched(route.getService(), serviceName)) {
            RouteRule rule = rules.get(route.getId());
            // 当满足when条件时
            if (rule != null
                && RouteRuleUtils.isMatchCondition(
                    rule.getWhenCondition(), consumerSample, consumerSample)) {
              if (routed != null && !routed.contains(route)) {
                routed.add(route);
              }
              Map<String, RouteRule.MatchPair> then = rule.getThenCondition();
              if (then != null) {
                Map<String, Map<String, String>> tmp =
                    getUrlsMatchedCondition(then, consumerSample, url2ProviderSample);
                // 如果规则的结果是空,则该规则无效,使用所有Provider
                if (route.isForce() || !tmp.isEmpty()) {
                  url2ProviderSample = tmp;
                }
              }
            }
          }
        }
      }
      for (String url : url2ProviderSample.keySet()) {
        Set<String> mts = url2Methods.get(url);
        if (mts == null) {
          mts = new HashSet<String>();
          url2Methods.put(url, mts);
        }
        mts.add(method);
      }
    } // end of for methods

    return appendMethodsToUrls(serviceUrls, url2Methods);
  }