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; }
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); }
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; }
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; }
// 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); }