Routers zookeeper path (#3173)
* give router rule a more layered extensiable ZK path: * ../routers/condition * ../routers/tag * ../routers/otherRouter * Fix UT * Adjust ZK to handle layered routers path * Remove BlackWhiteListRule * Adjust code to avoid possible ConcurrentModificationException * revert router from layered path to flat path: /router/condition -> router-codition * adjust router path in UT * change suffix literal: router-condition to condition-router * change suffix literal: router-condition to condition-router
This commit is contained in:
parent
21e0227a44
commit
c679d0b9d4
|
|
@ -21,7 +21,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.configcenter.DynamicConfiguration;
|
||||
|
||||
/**
|
||||
* Application level router, "application.routers"
|
||||
* Application level router, "application.condition-router"
|
||||
*/
|
||||
public class AppRouter extends ListenableRouter {
|
||||
public static final String NAME = "APP_ROUTER";
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.rpc.cluster.router.condition.config;
|
||||
|
||||
import org.apache.dubbo.common.Constants;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
|
@ -32,22 +31,23 @@ import org.apache.dubbo.rpc.RpcException;
|
|||
import org.apache.dubbo.rpc.cluster.Router;
|
||||
import org.apache.dubbo.rpc.cluster.router.AbstractRouter;
|
||||
import org.apache.dubbo.rpc.cluster.router.condition.ConditionRouter;
|
||||
import org.apache.dubbo.rpc.cluster.router.condition.config.model.BlackWhiteListRule;
|
||||
import org.apache.dubbo.rpc.cluster.router.condition.config.model.ConditionRouterRule;
|
||||
import org.apache.dubbo.rpc.cluster.router.condition.config.model.ConditionRuleParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Abstract router which listens to dynamic configuration
|
||||
*/
|
||||
public abstract class ListenableRouter extends AbstractRouter implements ConfigurationListener {
|
||||
public static final String NAME = "LISTENABLE_ROUTER";
|
||||
private static final String RULE_SUFFIX = ".condition-router";
|
||||
public static final int DEFAULT_PRIORITY = 200;
|
||||
private static final Logger logger = LoggerFactory.getLogger(ListenableRouter.class);
|
||||
private ConditionRouterRule routerRule;
|
||||
private List<ConditionRouter> conditionRouters = new ArrayList<>();
|
||||
private List<ConditionRouter> conditionRouters = Collections.emptyList();
|
||||
|
||||
public ListenableRouter(DynamicConfiguration configuration, URL url, String ruleKey) {
|
||||
super(configuration, url);
|
||||
|
|
@ -64,11 +64,11 @@ public abstract class ListenableRouter extends AbstractRouter implements Configu
|
|||
|
||||
if (event.getChangeType().equals(ConfigChangeType.DELETED)) {
|
||||
routerRule = null;
|
||||
conditionRouters.clear();
|
||||
conditionRouters = Collections.emptyList();
|
||||
} else {
|
||||
try {
|
||||
routerRule = ConditionRuleParser.parse(event.getValue());
|
||||
generateConditions(routerRule, conditionRouters);
|
||||
generateConditions(routerRule);
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to parse the raw condition rule and it will not take effect, please check " +
|
||||
"if the condition rule matches with the template, the raw rule is:\n " + event.getValue(), e);
|
||||
|
|
@ -104,23 +104,12 @@ public abstract class ListenableRouter extends AbstractRouter implements Configu
|
|||
return routerRule != null && routerRule.isValid() && routerRule.isRuntime();
|
||||
}
|
||||
|
||||
private void generateConditions(ConditionRouterRule rule, List<ConditionRouter> routers) {
|
||||
private void generateConditions(ConditionRouterRule rule) {
|
||||
if (rule != null && rule.isValid()) {
|
||||
routers.clear();
|
||||
rule.getConditions().forEach(condition -> {
|
||||
// All sub rules have the same force, runtime value.
|
||||
ConditionRouter subRouter = new ConditionRouter(condition, rule.isForce(), rule.isEnabled());
|
||||
routers.add(subRouter);
|
||||
});
|
||||
|
||||
BlackWhiteListRule blackWhiteList = rule.getBlackWhiteList();
|
||||
if (blackWhiteList != null && blackWhiteList.isValid()) {
|
||||
blackWhiteList.getConditions().forEach(condition -> {
|
||||
// All sub rules have the same force, runtime value.
|
||||
ConditionRouter subRouter = new ConditionRouter(condition, true, blackWhiteList.isEnabled());
|
||||
routers.add(subRouter);
|
||||
});
|
||||
}
|
||||
this.conditionRouters = rule.getConditions()
|
||||
.stream()
|
||||
.map(condition -> new ConditionRouter(condition, rule.isForce(), rule.isEnabled()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -128,7 +117,7 @@ public abstract class ListenableRouter extends AbstractRouter implements Configu
|
|||
if (StringUtils.isEmpty(ruleKey)) {
|
||||
return;
|
||||
}
|
||||
String routerKey = ruleKey + Constants.ROUTERS_SUFFIX;
|
||||
String routerKey = ruleKey + RULE_SUFFIX;
|
||||
configuration.addListener(routerKey, this);
|
||||
String rule = configuration.getConfig(routerKey);
|
||||
if (rule != null) {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.configcenter.DynamicConfiguration;
|
||||
|
||||
/**
|
||||
* Service level router, "server-uniq-name.routers"
|
||||
* Service level router, "server-unique-name.condition-router"
|
||||
*/
|
||||
public class ServiceRouter extends ListenableRouter {
|
||||
public static final String NAME = "SERVICE_ROUTER";
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.cluster.router.condition.config.model;
|
||||
|
||||
import org.apache.dubbo.rpc.cluster.router.AbstractRouterRule;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class BlackWhiteListRule extends AbstractRouterRule {
|
||||
private List<String> conditions;
|
||||
|
||||
public List<String> getConditions() {
|
||||
return conditions;
|
||||
}
|
||||
|
||||
public void setConditions(List<String> conditions) {
|
||||
this.conditions = conditions;
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,6 @@ public class ConditionRouterRule extends AbstractRouterRule {
|
|||
public ConditionRouterRule() {
|
||||
}
|
||||
|
||||
private BlackWhiteListRule blackWhiteList;
|
||||
private List<String> conditions;
|
||||
|
||||
public List<String> getConditions() {
|
||||
|
|
@ -37,12 +36,4 @@ public class ConditionRouterRule extends AbstractRouterRule {
|
|||
public void setConditions(List<String> conditions) {
|
||||
this.conditions = conditions;
|
||||
}
|
||||
|
||||
public BlackWhiteListRule getBlackWhiteList() {
|
||||
return blackWhiteList;
|
||||
}
|
||||
|
||||
public void setBlackWhiteList(BlackWhiteListRule blackWhiteList) {
|
||||
this.blackWhiteList = blackWhiteList;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,10 +47,6 @@ public class ConditionRuleParser {
|
|||
rule.setValid(false);
|
||||
}
|
||||
|
||||
BlackWhiteListRule blackWhiteList = rule.getBlackWhiteList();
|
||||
if (blackWhiteList != null && CollectionUtils.isEmpty(blackWhiteList.getConditions())) {
|
||||
blackWhiteList.setValid(false);
|
||||
}
|
||||
return rule;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,13 +42,13 @@ import static org.apache.dubbo.common.Constants.FORCE_USE_TAG;
|
|||
import static org.apache.dubbo.common.Constants.TAG_KEY;
|
||||
|
||||
/**
|
||||
* TagRouter
|
||||
* TagRouter, "application.tag-router"
|
||||
*/
|
||||
public class TagRouter extends AbstractRouter implements Comparable<Router>, ConfigurationListener {
|
||||
public static final String NAME = "TAG_ROUTER";
|
||||
private static final int DEFAULT_PRIORITY = 100;
|
||||
private static final Logger logger = LoggerFactory.getLogger(TagRouter.class);
|
||||
private static final String RULE_PREFIX = ".tagrouters";
|
||||
private static final String RULE_SUFFIX = ".tag-router";
|
||||
|
||||
private TagRouterRule tagRouterRule;
|
||||
private String application;
|
||||
|
|
@ -198,9 +198,9 @@ public class TagRouter extends AbstractRouter implements Comparable<Router>, Con
|
|||
synchronized (this) {
|
||||
if (!providerApplication.equals(application)) {
|
||||
if (!StringUtils.isEmpty(application)) {
|
||||
configuration.removeListener(application + RULE_PREFIX, this);
|
||||
configuration.removeListener(application + RULE_SUFFIX, this);
|
||||
}
|
||||
String key = providerApplication + RULE_PREFIX;
|
||||
String key = providerApplication + RULE_SUFFIX;
|
||||
configuration.addListener(key, this);
|
||||
application = providerApplication;
|
||||
String rawRule = configuration.getConfig(key);
|
||||
|
|
|
|||
|
|
@ -20,11 +20,10 @@ import org.apache.curator.framework.CuratorFramework;
|
|||
import org.apache.curator.framework.CuratorFrameworkFactory;
|
||||
import org.apache.curator.retry.ExponentialBackoffRetry;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* FIXME This is not a formal UT
|
||||
*/
|
||||
@Ignore("FIXME This is not a formal UT")
|
||||
public class ConfigConditionRouterTest {
|
||||
private static CuratorFramework client;
|
||||
|
||||
|
|
@ -48,7 +47,7 @@ public class ConfigConditionRouterTest {
|
|||
" - method=notExitMethod => \n" +
|
||||
"...";
|
||||
try {
|
||||
String servicePath = "/dubbo/config/demo-consumer/routers";
|
||||
String servicePath = "/dubbo/config/demo-consumer/condition-router";
|
||||
if (client.checkExists().forPath(servicePath) == null) {
|
||||
client.create().creatingParentsIfNeeded().forPath(servicePath);
|
||||
}
|
||||
|
|
@ -72,7 +71,7 @@ public class ConfigConditionRouterTest {
|
|||
" - method=routeMethod1 => host=30.5.120.37\n" +
|
||||
"...";
|
||||
try {
|
||||
String servicePath = "/dubbo/config/demo-consumer/routers";
|
||||
String servicePath = "/dubbo/config/demo-consumer/condition-router";
|
||||
if (client.checkExists().forPath(servicePath) == null) {
|
||||
client.create().creatingParentsIfNeeded().forPath(servicePath);
|
||||
}
|
||||
|
|
@ -97,7 +96,7 @@ public class ConfigConditionRouterTest {
|
|||
"...";
|
||||
// String serviceStr = "";
|
||||
try {
|
||||
String servicePath = "/dubbo/config/org.apache.dubbo.demo.DemoService/routers";
|
||||
String servicePath = "/dubbo/config/org.apache.dubbo.demo.DemoService/condition-router";
|
||||
if (client.checkExists().forPath(servicePath) == null) {
|
||||
client.create().creatingParentsIfNeeded().forPath(servicePath);
|
||||
}
|
||||
|
|
@ -118,7 +117,7 @@ public class ConfigConditionRouterTest {
|
|||
"key: org.apache.dubbo.demo.DemoService\n" +
|
||||
"...";
|
||||
try {
|
||||
String servicePath = "/dubbo/config/org.apache.dubbo.demo.DemoService/routers";
|
||||
String servicePath = "/dubbo/config/org.apache.dubbo.demo.DemoService/condition-router";
|
||||
if (client.checkExists().forPath(servicePath) == null) {
|
||||
client.create().creatingParentsIfNeeded().forPath(servicePath);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,11 +20,10 @@ import org.apache.curator.framework.CuratorFramework;
|
|||
import org.apache.curator.framework.CuratorFrameworkFactory;
|
||||
import org.apache.curator.retry.ExponentialBackoffRetry;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* FIXME This is not a formal UT
|
||||
*/
|
||||
@Ignore("FIXME This is not a formal UT")
|
||||
public class TagRouterTest {
|
||||
private static CuratorFramework client;
|
||||
|
||||
|
|
@ -51,7 +50,7 @@ public class TagRouterTest {
|
|||
"...";
|
||||
// String serviceStr = "";
|
||||
try {
|
||||
String servicePath = "/dubbo/config/demo-provider/tagrouters";
|
||||
String servicePath = "/dubbo/config/demo-provider/tag-router";
|
||||
if (client.checkExists().forPath(servicePath) == null) {
|
||||
client.create().creatingParentsIfNeeded().forPath(servicePath);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ public class CacheListener implements TreeCacheListener {
|
|||
// TODO We limit the notification of config changes to a specific path level, for example
|
||||
// /dubbo/config/service/configurators, other config changes not in this level will not get notified,
|
||||
// say /dubbo/config/dubbo.properties
|
||||
if (data.getPath().split("/").length == 5) {
|
||||
if (data.getPath().split("/").length >= 5) {
|
||||
byte[] value = data.getData();
|
||||
String key = pathToKey(data.getPath());
|
||||
ConfigChangeType changeType;
|
||||
|
|
|
|||
|
|
@ -122,13 +122,18 @@ public class ZookeeperDynamicConfiguration implements DynamicConfiguration {
|
|||
|
||||
@Override
|
||||
public String getConfig(String key, String group, long timeout) throws IllegalStateException {
|
||||
// when group is not null, we are getting startup configs from Config Center
|
||||
// for example, group=dubbo, key=dubbo.properties
|
||||
/**
|
||||
* when group is not null, we are getting startup configs from Config Center, for example:
|
||||
* group=dubbo, key=dubbo.properties
|
||||
*/
|
||||
if (StringUtils.isNotEmpty(group)) {
|
||||
key = group + "/" + key;
|
||||
}
|
||||
// when group is null, we are fetching governance rules.
|
||||
// for example, key=org.apache.dubbo.DemoService.configurators
|
||||
/**
|
||||
* when group is null, we are fetching governance rules, for example:
|
||||
* 1. key=org.apache.dubbo.DemoService.configurators
|
||||
* 2. key = org.apache.dubbo.DemoService.condition-router
|
||||
*/
|
||||
else {
|
||||
int i = key.lastIndexOf(".");
|
||||
key = key.substring(0, i) + "/" + key.substring(i + 1);
|
||||
|
|
|
|||
Loading…
Reference in New Issue