This is an automated email from the ASF dual-hosted git repository.

huxing pushed a commit to branch 2.7.3-release
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/2.7.3-release by this push:
     new c4e9495  unify config-center model (#4388)
c4e9495 is described below

commit c4e94958fd886994d2dfb78f28f0a77c52a5e7e7
Author: ken.lj <ken.lj...@gmail.com>
AuthorDate: Thu Jul 4 17:20:38 2019 +0800

    unify config-center model (#4388)
    
    * unify config-center model
    * change ut to meet the new model
    * add back the wrongly deleted line
---
 .../router/condition/config/ListenableRouter.java  |  2 +-
 .../router/condition/config/ServiceRouter.java     |  2 +-
 .../dubbo/rpc/cluster/router/tag/TagRouter.java    |  4 +-
 .../src/main/java/org/apache/dubbo/common/URL.java | 33 +++++++++----
 .../dubbo/common/constants/CommonConstants.java    |  2 +
 .../test/java/org/apache/dubbo/common/URLTest.java | 15 ++++++
 .../dubbo/config/AbstractInterfaceConfig.java      | 24 +++++-----
 .../dubbo/configcenter/DynamicConfiguration.java   | 44 ++++++++---------
 .../support/nop/NopDynamicConfiguration.java       |  4 +-
 .../mock/MockDynamicConfiguration.java             |  4 +-
 .../support/apollo/ApolloDynamicConfiguration.java | 10 +---
 .../consul/ConsulDynamicConfiguration.java         | 38 +++++++--------
 .../support/etcd/EtcdDynamicConfiguration.java     | 27 +++++------
 .../support/etcd/EtcdDynamicConfigurationTest.java |  5 +-
 .../support/nacos/NacosDynamicConfiguration.java   | 56 +++++-----------------
 .../nacos/NacosDynamicConfigurationTest.java       | 26 +++++-----
 .../support/zookeeper/CacheListener.java           | 13 +++--
 .../zookeeper/ZookeeperDynamicConfiguration.java   | 49 +++++++------------
 .../ZookeeperDynamicConfigurationTest.java         | 29 ++++++-----
 .../integration/AbstractConfiguratorListener.java  |  3 +-
 .../registry/integration/RegistryDirectory.java    | 12 ++---
 .../registry/integration/RegistryProtocol.java     | 38 +++++++--------
 .../apache/dubbo/registry/nacos/NacosRegistry.java | 18 +------
 23 files changed, 204 insertions(+), 254 deletions(-)

diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableRouter.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableRouter.java
index 564f371..0fe66b0 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableRouter.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ListenableRouter.java
@@ -119,7 +119,7 @@ public abstract class ListenableRouter extends 
AbstractRouter implements Configu
         }
         String routerKey = ruleKey + RULE_SUFFIX;
         configuration.addListener(routerKey, this);
-        String rule = configuration.getConfig(routerKey);
+        String rule = configuration.getRule(routerKey, 
DynamicConfiguration.DEFAULT_GROUP);
         if (StringUtils.isNotEmpty(rule)) {
             this.process(new ConfigChangeEvent(routerKey, rule));
         }
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ServiceRouter.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ServiceRouter.java
index ed3748e..071a07e 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ServiceRouter.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/config/ServiceRouter.java
@@ -30,7 +30,7 @@ public class ServiceRouter extends ListenableRouter {
     private static final int SERVICE_ROUTER_DEFAULT_PRIORITY = 140;
 
     public ServiceRouter(DynamicConfiguration configuration, URL url) {
-        super(configuration, url, url.getEncodedServiceKey());
+        super(configuration, url, DynamicConfiguration.getRuleKey(url));
         this.priority = SERVICE_ROUTER_DEFAULT_PRIORITY;
     }
 }
diff --git 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
index c6387fe..c96f6a2 100644
--- 
a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
+++ 
b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
@@ -40,8 +40,8 @@ import java.util.List;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
-import static org.apache.dubbo.rpc.cluster.Constants.TAG_KEY;
 import static org.apache.dubbo.rpc.Constants.FORCE_USE_TAG;
+import static org.apache.dubbo.rpc.cluster.Constants.TAG_KEY;
 
 /**
  * TagRouter, "application.tag-router"
@@ -249,7 +249,7 @@ public class TagRouter extends AbstractRouter implements 
ConfigurationListener {
                 String key = providerApplication + RULE_SUFFIX;
                 configuration.addListener(key, this);
                 application = providerApplication;
-                String rawRule = configuration.getConfig(key);
+                String rawRule = configuration.getRule(key, 
DynamicConfiguration.DEFAULT_GROUP);
                 if (StringUtils.isNotEmpty(rawRule)) {
                     this.process(new ConfigChangeEvent(key, rawRule));
                 }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java 
b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
index bf8e62c..8da1f53 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
@@ -40,20 +40,20 @@ import java.util.Map;
 import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 
-import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PORT_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
 import static 
org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
 import static 
org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY_PREFIX;
 import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PASSWORD_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PORT_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PASSWORD_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.USERNAME_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
 
 /**
  * URL - Uniform Resource Locator (Immutable, ThreadSafe)
@@ -1246,14 +1246,27 @@ class URL implements Serializable {
     }
 
     /**
-     * The format is '{group}*{interfaceName}:{version}'
-     *
+     * The format is "{interface}:[version]:[group]"
      * @return
      */
-    public String getEncodedServiceKey() {
-        String serviceKey = this.getServiceKey();
-        serviceKey = serviceKey.replaceFirst("/", "*");
-        return serviceKey;
+    public String getColonSeparatedKey() {
+        StringBuilder serviceNameBuilder = new StringBuilder();
+        append(serviceNameBuilder, INTERFACE_KEY, true);
+        append(serviceNameBuilder, VERSION_KEY, false);
+        append(serviceNameBuilder, GROUP_KEY, false);
+        return serviceNameBuilder.toString();
+    }
+
+    private void append(StringBuilder target, String parameterName, boolean 
first) {
+        String parameterValue = this.getParameter(parameterName);
+        if (!StringUtils.isBlank(parameterValue)) {
+            if (!first) {
+                target.append(":");
+            }
+            target.append(parameterValue);
+        } else {
+            target.append(":");
+        }
     }
 
     /**
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
index d005ae9..8a9d870 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
@@ -42,6 +42,8 @@ public interface CommonConstants {
 
     String COMMA_SEPARATOR = ",";
 
+    String DOT_SEPARATOR = ".";
+
     Pattern COMMA_SPLIT_PATTERN = Pattern.compile("\\s*[,]+\\s*");
 
     public final static String PATH_SEPARATOR = "/";
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java 
b/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java
index 377bf89..7e05847 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/URLTest.java
@@ -705,4 +705,19 @@ public class URLTest {
         URL url5 = 
URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&group=group1&version=1.0.0");
         Assertions.assertEquals("group1/context/path:1.0.0", 
url5.getPathKey());
     }
+
+    @Test
+    public void testGetColonSeparatedKey() {
+        URL url1 = 
URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&group=group&version=1.0.0");
+        
Assertions.assertEquals("org.apache.dubbo.test.interfaceName:1.0.0:group", 
url1.getColonSeparatedKey());
+
+        URL url2 = 
URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&version=1.0.0");
+        Assertions.assertEquals("org.apache.dubbo.test.interfaceName:1.0.0:", 
url2.getColonSeparatedKey());
+
+        URL url3 = 
URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName&group=group");
+        Assertions.assertEquals("org.apache.dubbo.test.interfaceName::group", 
url3.getColonSeparatedKey());
+
+        URL url4 = 
URL.valueOf("10.20.130.230:20880/context/path?interface=org.apache.dubbo.test.interfaceName");
+        Assertions.assertEquals("org.apache.dubbo.test.interfaceName::", 
url4.getColonSeparatedKey());
+    }
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
index b725608..f1710bc 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
@@ -53,31 +53,30 @@ import java.util.Map;
 import java.util.Set;
 
 import static 
org.apache.dubbo.common.config.ConfigurationUtils.parseProperties;
-import static org.apache.dubbo.rpc.cluster.Constants.TAG_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
+import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
 import static 
org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
 import static 
org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
+import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
 import static org.apache.dubbo.common.constants.CommonConstants.FILE_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
+import static 
org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
+import static 
org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SECONDS_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
+import static 
org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTOCOL;
+import static 
org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
 import static org.apache.dubbo.config.Constants.DUBBO_IP_TO_REGISTRY;
-import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
 import static org.apache.dubbo.config.Constants.LAYER_KEY;
 import static org.apache.dubbo.config.Constants.LISTENER_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
-import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
 import static org.apache.dubbo.config.Constants.REGISTRIES_SUFFIX;
-import static 
org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
-import static 
org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SECONDS_KEY;
 import static org.apache.dubbo.monitor.Constants.LOGSTAT_PROTOCOL;
+import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
 import static org.apache.dubbo.registry.Constants.REGISTER_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
-import static 
org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTOCOL;
 import static org.apache.dubbo.registry.Constants.SUBSCRIBE_KEY;
 import static org.apache.dubbo.remoting.Constants.DUBBO_VERSION_KEY;
 import static org.apache.dubbo.rpc.Constants.INVOKER_LISTENER_KEY;
@@ -86,7 +85,8 @@ import static org.apache.dubbo.rpc.Constants.PROXY_KEY;
 import static org.apache.dubbo.rpc.Constants.REFERENCE_FILTER_KEY;
 import static org.apache.dubbo.rpc.Constants.RETURN_PREFIX;
 import static org.apache.dubbo.rpc.Constants.THROW_PREFIX;
-import static 
org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
+import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.TAG_KEY;
 
 /**
  * AbstractDefaultConfig
@@ -287,12 +287,12 @@ public abstract class AbstractInterfaceConfig extends 
AbstractMethodConfig {
                 return;
             }
             DynamicConfiguration dynamicConfiguration = 
getDynamicConfiguration(configCenter.toUrl());
-            String configContent = 
dynamicConfiguration.getConfigs(configCenter.getConfigFile(), 
configCenter.getGroup());
+            String configContent = 
dynamicConfiguration.getProperties(configCenter.getConfigFile(), 
configCenter.getGroup());
 
             String appGroup = application != null ? application.getName() : 
null;
             String appConfigContent = null;
             if (StringUtils.isNotEmpty(appGroup)) {
-                appConfigContent = dynamicConfiguration.getConfigs
+                appConfigContent = dynamicConfiguration.getProperties
                         
(StringUtils.isNotEmpty(configCenter.getAppConfigFile()) ? 
configCenter.getAppConfigFile() : configCenter.getConfigFile(),
                          appGroup
                         );
diff --git 
a/dubbo-configcenter/dubbo-configcenter-api/src/main/java/org/apache/dubbo/configcenter/DynamicConfiguration.java
 
b/dubbo-configcenter/dubbo-configcenter-api/src/main/java/org/apache/dubbo/configcenter/DynamicConfiguration.java
index 23fc0f5..357632c 100644
--- 
a/dubbo-configcenter/dubbo-configcenter-api/src/main/java/org/apache/dubbo/configcenter/DynamicConfiguration.java
+++ 
b/dubbo-configcenter/dubbo-configcenter-api/src/main/java/org/apache/dubbo/configcenter/DynamicConfiguration.java
@@ -16,6 +16,7 @@
  */
 package org.apache.dubbo.configcenter;
 
+import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.config.Configuration;
 import org.apache.dubbo.common.config.Environment;
 
@@ -79,29 +80,19 @@ public interface DynamicConfiguration extends Configuration 
{
     void removeListener(String key, String group, ConfigurationListener 
listener);
 
     /**
-     * Get the configuration mapped to the given key
-     *
-     * @param key the key to represent a configuration
-     * @return target configuration mapped to the given key
-     */
-    default String getConfig(String key) {
-        return getConfig(key, null, -1L);
-    }
-
-    /**
-     * Get the configuration mapped to the given key and the given group
+     * Get the governance rule mapped to the given key and the given group
      *
      * @param key   the key to represent a configuration
      * @param group the group where the key belongs to
      * @return target configuration mapped to the given key and the given group
      */
-    default String getConfig(String key, String group) {
-        return getConfig(key, group, -1L);
+    default String getRule(String key, String group) {
+        return getRule(key, group, -1L);
     }
 
     /**
-     * Get the configuration mapped to the given key and the given group. If 
the
-     * configuration fails to fetch after timeout exceeds, 
IllegalStateException will be thrown.
+     * Get the governance rule mapped to the given key and the given group. If 
the
+     * rule fails to return after timeout exceeds, IllegalStateException will 
be thrown.
      *
      * @param key     the key to represent a configuration
      * @param group   the group where the key belongs to
@@ -109,23 +100,21 @@ public interface DynamicConfiguration extends 
Configuration {
      * @return target configuration mapped to the given key and the given 
group, IllegalStateException will be thrown
      * if timeout exceeds.
      */
-    String getConfig(String key, String group, long timeout) throws 
IllegalStateException;
+    String getRule(String key, String group, long timeout) throws 
IllegalStateException;
 
     /**
-     * {@see #getConfig(String, String, long)}
-     *
      * This method are mostly used to get a compound config file, such as a 
complete dubbo.properties file.
+     * Also {@see #getConfig(String, String)}
      */
-    default String getConfigs(String key, String group) throws 
IllegalStateException {
-        return getConfigs(key, group, -1L);
+    default String getProperties(String key, String group) throws 
IllegalStateException {
+        return getProperties(key, group, -1L);
     }
 
     /**
-     * {@see #getConfig(String, String, long)}
-     *
      * This method are mostly used to get a compound config file, such as a 
complete dubbo.properties file.
+     * Also {@see #getConfig(String, String, long)}
      */
-    String getConfigs(String key, String group, long timeout) throws 
IllegalStateException;
+    String getProperties(String key, String group, long timeout) throws 
IllegalStateException;
 
     /**
      * Find DynamicConfiguration instance
@@ -138,4 +127,13 @@ public interface DynamicConfiguration extends 
Configuration {
                 .getDefaultExtension()
                 .getDynamicConfiguration(null));
     }
+
+     /**
+     * The format is '{interfaceName}:[version]:[group]'
+     *
+     * @return
+     */
+     static String getRuleKey(URL url) {
+        return url.getColonSeparatedKey();
+    }
 }
diff --git 
a/dubbo-configcenter/dubbo-configcenter-api/src/main/java/org/apache/dubbo/configcenter/support/nop/NopDynamicConfiguration.java
 
b/dubbo-configcenter/dubbo-configcenter-api/src/main/java/org/apache/dubbo/configcenter/support/nop/NopDynamicConfiguration.java
index dbb91fd..6316821 100644
--- 
a/dubbo-configcenter/dubbo-configcenter-api/src/main/java/org/apache/dubbo/configcenter/support/nop/NopDynamicConfiguration.java
+++ 
b/dubbo-configcenter/dubbo-configcenter-api/src/main/java/org/apache/dubbo/configcenter/support/nop/NopDynamicConfiguration.java
@@ -47,12 +47,12 @@ public class NopDynamicConfiguration implements 
DynamicConfiguration {
     }
 
     @Override
-    public String getConfig(String key, String group, long timeout) throws 
IllegalStateException {
+    public String getRule(String key, String group, long timeout) throws 
IllegalStateException {
         return null;
     }
 
     @Override
-    public String getConfigs(String key, String group, long timeout) throws 
IllegalStateException {
+    public String getProperties(String key, String group, long timeout) throws 
IllegalStateException {
         return null;
     }
 }
diff --git 
a/dubbo-configcenter/dubbo-configcenter-api/src/test/java/org/apache/dubbo/configcenter/mock/MockDynamicConfiguration.java
 
b/dubbo-configcenter/dubbo-configcenter-api/src/test/java/org/apache/dubbo/configcenter/mock/MockDynamicConfiguration.java
index 05ce68b..773fcb4 100644
--- 
a/dubbo-configcenter/dubbo-configcenter-api/src/test/java/org/apache/dubbo/configcenter/mock/MockDynamicConfiguration.java
+++ 
b/dubbo-configcenter/dubbo-configcenter-api/src/test/java/org/apache/dubbo/configcenter/mock/MockDynamicConfiguration.java
@@ -43,12 +43,12 @@ public class MockDynamicConfiguration implements 
DynamicConfiguration {
     }
 
     @Override
-    public String getConfig(String key, String group, long timeout) throws 
IllegalStateException {
+    public String getRule(String key, String group, long timeout) throws 
IllegalStateException {
         return null;
     }
 
     @Override
-    public String getConfigs(String key, String group, long timeout) throws 
IllegalStateException {
+    public String getProperties(String key, String group, long timeout) throws 
IllegalStateException {
         return null;
     }
 }
diff --git 
a/dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java
 
b/dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java
index f67c1e0..f2ba351 100644
--- 
a/dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java
+++ 
b/dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java
@@ -134,13 +134,8 @@ public class ApolloDynamicConfiguration implements 
DynamicConfiguration {
         }
     }
 
-    /**
-     * This method will be used to:
-     * 1. get configuration file at startup phase
-     * 2. get all kinds of Dubbo rules
-     */
     @Override
-    public String getConfig(String key, String group, long timeout) throws 
IllegalStateException {
+    public String getRule(String key, String group, long timeout) throws 
IllegalStateException {
         if (StringUtils.isNotEmpty(group)) {
             if (group.equals(url.getParameter(APPLICATION_KEY))) {
                 return ConfigService.getAppConfig().getProperty(key, null);
@@ -152,7 +147,7 @@ public class ApolloDynamicConfiguration implements 
DynamicConfiguration {
     }
 
     @Override
-    public String getConfigs(String key, String group, long timeout) throws 
IllegalStateException {
+    public String getProperties(String key, String group, long timeout) throws 
IllegalStateException {
         if(StringUtils.isEmpty(group)) {
             return dubboConfigFile.getContent();
         }
@@ -177,7 +172,6 @@ public class ApolloDynamicConfiguration implements 
DynamicConfiguration {
         return dubboConfig.getProperty(key, null);
     }
 
-
     /**
      * Ignores the group parameter.
      *
diff --git 
a/dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
 
b/dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
index 2e67bbd..f57f639 100644
--- 
a/dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
+++ 
b/dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
@@ -40,8 +40,8 @@ import java.util.concurrent.ExecutorService;
 
 import static java.util.concurrent.Executors.newCachedThreadPool;
 import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
-import static org.apache.dubbo.configcenter.Constants.CONFIG_NAMESPACE_KEY;
 import static org.apache.dubbo.configcenter.ConfigChangeType.ADDED;
+import static org.apache.dubbo.configcenter.Constants.CONFIG_NAMESPACE_KEY;
 
 /**
  * config center implementation for consul
@@ -74,9 +74,10 @@ public class ConsulDynamicConfiguration implements 
DynamicConfiguration {
     @Override
     public void addListener(String key, String group, ConfigurationListener 
listener) {
         logger.info("register listener " + listener.getClass() + " for config 
with key: " + key + ", group: " + group);
-        ConsulKVWatcher watcher = watchers.putIfAbsent(key, new 
ConsulKVWatcher(key));
+        String normalizedKey = convertKey(group, key);
+        ConsulKVWatcher watcher = watchers.putIfAbsent(normalizedKey, new 
ConsulKVWatcher(normalizedKey));
         if (watcher == null) {
-            watcher = watchers.get(key);
+            watcher = watchers.get(normalizedKey);
             watcherService.submit(watcher);
         }
         watcher.addListener(listener);
@@ -85,27 +86,23 @@ public class ConsulDynamicConfiguration implements 
DynamicConfiguration {
     @Override
     public void removeListener(String key, String group, ConfigurationListener 
listener) {
         logger.info("unregister listener " + listener.getClass() + " for 
config with key: " + key + ", group: " + group);
-        ConsulKVWatcher watcher = watchers.get(key);
+        ConsulKVWatcher watcher = watchers.get(convertKey(group, key));
         if (watcher != null) {
             watcher.removeListener(listener);
         }
     }
 
     @Override
-    public String getConfig(String key, String group, long timeout) throws 
IllegalStateException {
-        if (StringUtils.isNotEmpty(group)) {
-            key = group + PATH_SEPARATOR + key;
-        } else {
-            int i = key.lastIndexOf(".");
-            key = key.substring(0, i) + PATH_SEPARATOR + key.substring(i + 1);
-        }
-
-        return (String) getInternalProperty(rootPath + PATH_SEPARATOR + key);
+    public String getRule(String key, String group, long timeout) throws 
IllegalStateException {
+        return (String) getInternalProperty(convertKey(group, key));
     }
 
     @Override
-    public String getConfigs(String key, String group, long timeout) throws 
IllegalStateException {
-        return getConfig(key, group, timeout);
+    public String getProperties(String key, String group, long timeout) throws 
IllegalStateException {
+        if (StringUtils.isEmpty(group)) {
+            group = DEFAULT_GROUP;
+        }
+        return (String) getInternalProperty(convertKey(group, key));
     }
 
     @Override
@@ -130,6 +127,10 @@ public class ConsulDynamicConfiguration implements 
DynamicConfiguration {
         return null;
     }
 
+    private String convertKey(String group, String key) {
+        return rootPath + PATH_SEPARATOR + group + PATH_SEPARATOR + key;
+    }
+
     private int buildWatchTimeout(URL url) {
         return url.getParameter(WATCH_TIMEOUT, DEFAULT_WATCH_TIMEOUT) / 1000;
     }
@@ -141,7 +142,7 @@ public class ConsulDynamicConfiguration implements 
DynamicConfiguration {
         private boolean existing = false;
 
         public ConsulKVWatcher(String key) {
-            this.key = convertKey(key);
+            this.key = key;
             this.listeners = new HashSet<>();
         }
 
@@ -200,11 +201,6 @@ public class ConsulDynamicConfiguration implements 
DynamicConfiguration {
             this.listeners.remove(listener);
         }
 
-        private String convertKey(String key) {
-            int index = key.lastIndexOf('.');
-            return rootPath + PATH_SEPARATOR + key.substring(0, index) + 
PATH_SEPARATOR + key.substring(index + 1);
-        }
-
         private void stop() {
             running = false;
         }
diff --git 
a/dubbo-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java
 
b/dubbo-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java
index 10c50b6..1b10105 100644
--- 
a/dubbo-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java
+++ 
b/dubbo-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java
@@ -64,7 +64,7 @@ public class EtcdDynamicConfiguration implements 
DynamicConfiguration {
     private final ConcurrentMap<ConfigurationListener, EtcdConfigWatcher> 
watchListenerMap;
 
     EtcdDynamicConfiguration(URL url) {
-        rootPath = "/" + url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP) 
+ "/config";
+        rootPath = PATH_SEPARATOR + url.getParameter(CONFIG_NAMESPACE_KEY, 
DEFAULT_GROUP) + "/config";
         etcdClient = new JEtcdClient(url);
         etcdClient.addStateListener(state -> {
             if (state == StateListener.CONNECTED) {
@@ -81,7 +81,7 @@ public class EtcdDynamicConfiguration implements 
DynamicConfiguration {
     @Override
     public void addListener(String key, String group, ConfigurationListener 
listener) {
         if (watchListenerMap.get(listener) == null) {
-            String normalizedKey = convertKey(key);
+            String normalizedKey = convertKey(group, key);
             EtcdConfigWatcher watcher = new EtcdConfigWatcher(normalizedKey, 
listener);
             watchListenerMap.put(listener, watcher);
             watcher.watch();
@@ -94,21 +94,17 @@ public class EtcdDynamicConfiguration implements 
DynamicConfiguration {
         watcher.cancelWatch();
     }
 
-    // TODO Abstract the logic into super class
     @Override
-    public String getConfig(String key, String group, long timeout) throws 
IllegalStateException {
-        if (StringUtils.isNotEmpty(group)) {
-            key = group + PATH_SEPARATOR + key;
-        } else {
-            int i = key.lastIndexOf(".");
-            key = key.substring(0, i) + PATH_SEPARATOR + key.substring(i + 1);
-        }
-        return (String) getInternalProperty(rootPath + PATH_SEPARATOR + key);
+    public String getRule(String key, String group, long timeout) throws 
IllegalStateException {
+        return (String) getInternalProperty(convertKey(group, key));
     }
 
     @Override
-    public String getConfigs(String key, String group, long timeout) throws 
IllegalStateException {
-        return getConfig(key, group, timeout);
+    public String getProperties(String key, String group, long timeout) throws 
IllegalStateException {
+        if (StringUtils.isEmpty(group)) {
+            group = DEFAULT_GROUP;
+        }
+        return (String) getInternalProperty(convertKey(group, key));
     }
 
     @Override
@@ -117,9 +113,8 @@ public class EtcdDynamicConfiguration implements 
DynamicConfiguration {
     }
 
 
-    private String convertKey(String key) {
-        int index = key.lastIndexOf('.');
-        return rootPath + PATH_SEPARATOR + key.substring(0, index) + 
PATH_SEPARATOR + key.substring(index + 1);
+    private String convertKey(String group, String key) {
+        return rootPath + PATH_SEPARATOR + group + PATH_SEPARATOR + key;
     }
 
     private void recover() {
diff --git 
a/dubbo-configcenter/dubbo-configcenter-etcd/src/test/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationTest.java
 
b/dubbo-configcenter/dubbo-configcenter-etcd/src/test/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationTest.java
index d56f3c4..6cd1058 100644
--- 
a/dubbo-configcenter/dubbo-configcenter-etcd/src/test/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationTest.java
+++ 
b/dubbo-configcenter/dubbo-configcenter-etcd/src/test/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationTest.java
@@ -20,6 +20,7 @@ package org.apache.dubbo.configcenter.support.etcd;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.configcenter.ConfigChangeEvent;
 import org.apache.dubbo.configcenter.ConfigurationListener;
+import org.apache.dubbo.configcenter.DynamicConfiguration;
 
 import io.etcd.jetcd.ByteSequence;
 import io.etcd.jetcd.Client;
@@ -57,8 +58,8 @@ public class EtcdDynamicConfigurationTest {
 
         put("/dubbo/config/org.apache.dubbo.etcd.testService/configurators", 
"hello");
         put("/dubbo/config/test/dubbo.properties", "aaa=bbb");
-        Assert.assertEquals("hello", 
config.getConfig("org.apache.dubbo.etcd.testService.configurators"));
-        Assert.assertEquals("aaa=bbb", config.getConfig("dubbo.properties", 
"test"));
+        Assert.assertEquals("hello", 
config.getRule("org.apache.dubbo.etcd.testService.configurators", 
DynamicConfiguration.DEFAULT_GROUP));
+        Assert.assertEquals("aaa=bbb", config.getRule("dubbo.properties", 
"test"));
     }
 
     @Test
diff --git 
a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
 
b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
index fa04c00..edd0be0 100644
--- 
a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
+++ 
b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
@@ -139,38 +139,12 @@ public class NacosDynamicConfiguration implements 
DynamicConfiguration {
         return configListener;
     }
 
-
-    /**
-     * FIXME: 2019-05-30 to remove this function
-     * Nacos server does not support * as valid character of data-id.
-     * If a Dubbo service specifies group. For example:
-     *
-     *  <dubbo:service interface="org.apache.dubbo.demo.DemoService" 
ref="demoService"
-     *      version="1.0.0.test" group="test"/>
-     *
-     * The key passed to NacosDynamicConfiguration will be sth. like:
-     *   test*org.apache.dubbo.demo.DemoService:1.0.0.test.configurators
-     *
-     * See logic in org.apache.dubbo.common.URL#getEncodedServiceKey()
-     *
-     * The purpose of this function is to convert the * into :, to keep align 
with
-     * the implementation in NacosRegistry.
-     *
-     * In the future this logic should be removed if Dubbo core can handle 
this.
-     * @param key
-     * @return
-     */
-    private String normalizedKey(String key) {
-        return key.replaceFirst("\\*", ":");
-    }
-
     @Override
     public void addListener(String key, String group, ConfigurationListener 
listener) {
-        String normalizedKey = normalizedKey(key);
-        NacosConfigListener nacosConfigListener = 
watchListenerMap.computeIfAbsent(normalizedKey, k -> 
createTargetListener(normalizedKey, group));
+        NacosConfigListener nacosConfigListener = 
watchListenerMap.computeIfAbsent(key, k -> createTargetListener(key, group));
         nacosConfigListener.addListener(listener);
         try {
-            configService.addListener(normalizedKey, group, 
nacosConfigListener);
+            configService.addListener(key, group, nacosConfigListener);
         } catch (NacosException e) {
             logger.error(e.getMessage());
         }
@@ -178,27 +152,20 @@ public class NacosDynamicConfiguration implements 
DynamicConfiguration {
 
     @Override
     public void removeListener(String key, String group, ConfigurationListener 
listener) {
-        String normalizedKey = normalizedKey(key);
-        NacosConfigListener eventListener = 
watchListenerMap.get(normalizedKey);
+        NacosConfigListener eventListener = watchListenerMap.get(key);
         if (eventListener != null) {
             eventListener.removeListener(listener);
         }
     }
 
-    /**
-     * FIXME the model of Zookeeper and Nacos is inconsistent, need to remove 
this function in next release.
-     */
-    @Override
-    public String getConfig(String key) {
-        return getConfig(key, DEFAULT_GROUP, -1L);
-    }
-
     @Override
-    public String getConfig(String key, String group, long timeout) throws 
IllegalStateException {
+    public String getRule(String key, String group, long timeout) throws 
IllegalStateException {
         try {
-            String normalizedKey = normalizedKey(key);
             long nacosTimeout = timeout < 0 ?  DEFAULT_TIMEOUT : timeout;
-            return configService.getConfig(normalizedKey, group, nacosTimeout);
+            if (StringUtils.isEmpty(group)) {
+                group = DEFAULT_GROUP;
+            }
+            return configService.getConfig(key, group, nacosTimeout);
         } catch (NacosException e) {
             logger.error(e.getMessage());
         }
@@ -206,15 +173,14 @@ public class NacosDynamicConfiguration implements 
DynamicConfiguration {
     }
 
     @Override
-    public String getConfigs(String key, String group, long timeout) throws 
IllegalStateException {
-        return getConfig(key, group, timeout);
+    public String getProperties(String key, String group, long timeout) throws 
IllegalStateException {
+        return getRule(key, group, timeout);
     }
 
     @Override
     public Object getInternalProperty(String key) {
         try {
-            String normalizedKey = normalizedKey(key);
-            return configService.getConfig(normalizedKey, DEFAULT_GROUP, 
DEFAULT_TIMEOUT);
+            return configService.getConfig(key, DEFAULT_GROUP, 
DEFAULT_TIMEOUT);
         } catch (NacosException e) {
             logger.error(e.getMessage());
         }
diff --git 
a/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
 
b/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
index 28fa234..78c1211 100644
--- 
a/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
+++ 
b/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
@@ -17,14 +17,14 @@
 
 package org.apache.dubbo.configcenter.support.nacos;
 
-import com.alibaba.nacos.api.NacosFactory;
-import com.alibaba.nacos.api.config.ConfigService;
-import com.alibaba.nacos.api.exception.NacosException;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.configcenter.ConfigChangeEvent;
 import org.apache.dubbo.configcenter.ConfigurationListener;
-
 import org.apache.dubbo.configcenter.DynamicConfiguration;
+
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.exception.NacosException;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -57,11 +57,11 @@ public class NacosDynamicConfigurationTest {
         Thread.sleep(200);
         put("dubbo.properties", "test", "aaa=bbb");
         Thread.sleep(200);
-        put("xxxx:org.apache.dubbo.demo.DemoService:1.0.0.test.configurators", 
"helloworld");
+        put("org.apache.dubbo.demo.DemoService:1.0.0.test:xxxx.configurators", 
"helloworld");
         Thread.sleep(200);
-        Assertions.assertEquals("hello", 
config.getConfig("org.apache.dubbo.nacos.testService.configurators"));
-        Assertions.assertEquals("aaa=bbb", 
config.getConfig("dubbo.properties", "test"));
-        Assertions.assertEquals("helloworld", 
config.getConfig("xxxx*org.apache.dubbo.demo.DemoService:1.0.0.test.configurators"));
+        Assertions.assertEquals("hello", 
config.getRule("org.apache.dubbo.nacos.testService.configurators", 
DynamicConfiguration.DEFAULT_GROUP));
+        Assertions.assertEquals("aaa=bbb", config.getRule("dubbo.properties", 
"test"));
+        Assertions.assertEquals("helloworld", 
config.getRule("org.apache.dubbo.demo.DemoService:1.0.0.test:xxxx.configurators",
 DynamicConfiguration.DEFAULT_GROUP));
     }
 
     @Test
@@ -75,12 +75,12 @@ public class NacosDynamicConfigurationTest {
 
         config.addListener("AService.configurators", listener1);
         config.addListener("AService.configurators", listener2);
-        config.addListener("testapp.tagrouters", listener3);
-        config.addListener("testapp.tagrouters", listener4);
+        config.addListener("testapp.tag-router", listener3);
+        config.addListener("testapp.tag-router", listener4);
 
         put("AService.configurators", "new value1");
         Thread.sleep(200);
-        put("testapp.tagrouters", "new value2");
+        put("testapp.tag-router", "new value2");
         Thread.sleep(200);
         put("testapp", "new value3");
         Thread.sleep(5000);
@@ -89,8 +89,8 @@ public class NacosDynamicConfigurationTest {
 
         Assertions.assertEquals(1, 
listener1.getCount("AService.configurators"));
         Assertions.assertEquals(1, 
listener2.getCount("AService.configurators"));
-        Assertions.assertEquals(1, listener3.getCount("testapp.tagrouters"));
-        Assertions.assertEquals(1, listener4.getCount("testapp.tagrouters"));
+        Assertions.assertEquals(1, listener3.getCount("testapp.tag-router"));
+        Assertions.assertEquals(1, listener4.getCount("testapp.tag-router"));
 
         Assertions.assertEquals("new value1", listener1.getValue());
         Assertions.assertEquals("new value1", listener2.getValue());
diff --git 
a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/CacheListener.java
 
b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/CacheListener.java
index 3eaa96b..78bee12 100644
--- 
a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/CacheListener.java
+++ 
b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/CacheListener.java
@@ -30,6 +30,9 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.concurrent.CountDownLatch;
 
+import static org.apache.dubbo.common.constants.CommonConstants.DOT_SEPARATOR;
+import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
+
 /**
  *
  */
@@ -69,7 +72,8 @@ public class CacheListener implements DataListener {
         if (StringUtils.isEmpty(path)) {
             return path;
         }
-        return path.replace(rootPath + "/", "").replaceAll("/", ".");
+        String groupKey = path.replace(rootPath + PATH_SEPARATOR, 
"").replaceAll(PATH_SEPARATOR, DOT_SEPARATOR);
+        return groupKey.substring(groupKey.indexOf(DOT_SEPARATOR) + 1);
     }
 
 
@@ -88,9 +92,8 @@ public class CacheListener implements DataListener {
             return;
         }
 
-        // 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
+        // TODO We only care the changes happened on a specific path level, 
for example
+        //  /dubbo/config/dubbo/configurators, other config changes not in 
this level will be ignored,
         if (path.split("/").length >= MIN_PATH_DEPTH) {
             String key = pathToKey(path);
             ConfigChangeType changeType;
@@ -109,7 +112,7 @@ public class CacheListener implements DataListener {
             }
 
             ConfigChangeEvent configChangeEvent = new ConfigChangeEvent(key, 
(String) value, changeType);
-            Set<ConfigurationListener> listeners = keyListeners.get(key);
+            Set<ConfigurationListener> listeners = keyListeners.get(path);
             if (CollectionUtils.isNotEmpty(listeners)) {
                 listeners.forEach(listener -> 
listener.process(configChangeEvent));
             }
diff --git 
a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java
 
b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java
index a06537b..6231e61 100644
--- 
a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java
+++ 
b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java
@@ -31,6 +31,7 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 
+import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
 import static org.apache.dubbo.configcenter.Constants.CONFIG_NAMESPACE_KEY;
 
 /**
@@ -51,7 +52,7 @@ public class ZookeeperDynamicConfiguration implements 
DynamicConfiguration {
 
     ZookeeperDynamicConfiguration(URL url, ZookeeperTransporter 
zookeeperTransporter) {
         this.url = url;
-        rootPath = "/" + url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP) 
+ "/config";
+        rootPath = PATH_SEPARATOR + url.getParameter(CONFIG_NAMESPACE_KEY, 
DEFAULT_GROUP) + "/config";
 
         initializedLatch = new CountDownLatch(1);
         this.cacheListener = new CacheListener(rootPath, initializedLatch);
@@ -81,47 +82,29 @@ public class ZookeeperDynamicConfiguration implements 
DynamicConfiguration {
      */
     @Override
     public void addListener(String key, String group, ConfigurationListener 
listener) {
-        cacheListener.addListener(key, listener);
+        cacheListener.addListener(getPathKey(group, key), listener);
     }
 
     @Override
     public void removeListener(String key, String group, ConfigurationListener 
listener) {
-        cacheListener.removeListener(key, listener);
+        cacheListener.removeListener(getPathKey(group, key), listener);
     }
 
     @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
-         */
-        if (StringUtils.isNotEmpty(group)) {
-            key = group + "/" + key;
-        }
-        /**
-         * 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);
-        }
-
-        return (String) getInternalProperty(rootPath + "/" + key);
+    public String getRule(String key, String group, long timeout) throws 
IllegalStateException {
+        return (String) getInternalProperty(getPathKey(group, key));
     }
 
-    /**
-     * For zookeeper, {@link #getConfig(String, String, long)} and {@link 
#getConfigs(String, String, long)} have the same meaning.
-     *
-     * @param key
-     * @param group
-     * @param timeout
-     * @return
-     * @throws IllegalStateException
-     */
     @Override
-    public String getConfigs(String key, String group, long timeout) throws 
IllegalStateException {
-        return (String) getConfig(key, group, timeout);
+    public String getProperties(String key, String group, long timeout) throws 
IllegalStateException {
+        // use global group 'dubbo' if no group specified
+        if (StringUtils.isEmpty(group)) {
+            group = DEFAULT_GROUP;
+        }
+        return (String) getInternalProperty(getPathKey(group, key));
+    }
+
+    private String getPathKey(String group, String key) {
+        return rootPath + PATH_SEPARATOR + group + PATH_SEPARATOR + key;
     }
 }
diff --git 
a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/test/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationTest.java
 
b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/test/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationTest.java
index 64e0bec..7891dc0 100644
--- 
a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/test/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationTest.java
+++ 
b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/test/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationTest.java
@@ -58,10 +58,10 @@ public class ZookeeperDynamicConfigurationTest {
 
         try {
             setData("/dubbo/config/dubbo/dubbo.properties", "The content from 
dubbo.properties");
-            setData("/dubbo/config/group*service:version/configurators", "The 
content from configurators");
+            setData("/dubbo/config/dubbo/service:version:group.configurators", 
"The content from configurators");
             setData("/dubbo/config/appname", "The content from higer level 
node");
-            setData("/dubbo/config/appname/tagrouters", "The content from 
appname tagrouters");
-            setData("/dubbo/config/never.change.DemoService/configurators", 
"Never change value from configurators");
+            setData("/dubbo/config/dubbo/appname.tag-router", "The content 
from appname tagrouters");
+            
setData("/dubbo/config/dubbo/never.change.DemoService.configurators", "Never 
change value from configurators");
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -86,8 +86,7 @@ public class ZookeeperDynamicConfigurationTest {
 
     @Test
     public void testGetConfig() throws Exception {
-        Assertions.assertEquals("Never change value from configurators", 
configuration.getConfig("never.change.DemoService.configurators"));
-        Assertions.assertEquals("The content from dubbo.properties", 
configuration.getConfigs("dubbo.properties", "dubbo"));
+        Assertions.assertEquals("The content from dubbo.properties", 
configuration.getProperties("dubbo.properties", "dubbo"));
     }
 
     @Test
@@ -97,24 +96,24 @@ public class ZookeeperDynamicConfigurationTest {
         TestListener listener2 = new TestListener(latch);
         TestListener listener3 = new TestListener(latch);
         TestListener listener4 = new TestListener(latch);
-        configuration.addListener("group*service:version.configurators", 
listener1);
-        configuration.addListener("group*service:version.configurators", 
listener2);
-        configuration.addListener("appname.tagrouters", listener3);
-        configuration.addListener("appname.tagrouters", listener4);
+        configuration.addListener("service:version:group.configurators", 
listener1);
+        configuration.addListener("service:version:group.configurators", 
listener2);
+        configuration.addListener("appname.tag-router", listener3);
+        configuration.addListener("appname.tag-router", listener4);
 
-        setData("/dubbo/config/group*service:version/configurators", "new 
value1");
+        setData("/dubbo/config/dubbo/service:version:group.configurators", 
"new value1");
         Thread.sleep(100);
-        setData("/dubbo/config/appname/tagrouters", "new value2");
+        setData("/dubbo/config/dubbo/appname.tag-router", "new value2");
         Thread.sleep(100);
         setData("/dubbo/config/appname", "new value3");
 
         Thread.sleep(5000);
 
         latch.await();
-        Assertions.assertEquals(1, 
listener1.getCount("group*service:version.configurators"));
-        Assertions.assertEquals(1, 
listener2.getCount("group*service:version.configurators"));
-        Assertions.assertEquals(1, listener3.getCount("appname.tagrouters"));
-        Assertions.assertEquals(1, listener4.getCount("appname.tagrouters"));
+        Assertions.assertEquals(1, 
listener1.getCount("service:version:group.configurators"));
+        Assertions.assertEquals(1, 
listener2.getCount("service:version:group.configurators"));
+        Assertions.assertEquals(1, listener3.getCount("appname.tag-router"));
+        Assertions.assertEquals(1, listener4.getCount("appname.tag-router"));
 
         Assertions.assertEquals("new value1", listener1.getValue());
         Assertions.assertEquals("new value1", listener2.getValue());
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java
index 5258d24..9b6c685 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/AbstractConfiguratorListener.java
@@ -16,7 +16,6 @@
  */
 package org.apache.dubbo.registry.integration;
 
-import org.apache.dubbo.common.constants.CommonConstants;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.StringUtils;
@@ -42,7 +41,7 @@ public abstract class AbstractConfiguratorListener implements 
ConfigurationListe
     protected final void initWith(String key) {
         DynamicConfiguration dynamicConfiguration = 
DynamicConfiguration.getDynamicConfiguration();
         dynamicConfiguration.addListener(key, this);
-        String rawConfig = dynamicConfiguration.getConfig(key, 
CommonConstants.DUBBO);
+        String rawConfig = dynamicConfiguration.getRule(key, 
DynamicConfiguration.DEFAULT_GROUP);
         if (!StringUtils.isEmpty(rawConfig)) {
             genConfiguratorsFromRawRule(rawConfig);
         }
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
index f74931b..692621e 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
@@ -58,22 +58,19 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 
-import static org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
 import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.DISABLED_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
 import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
-import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.APP_DYNAMIC_CONFIGURATORS_CATEGORY;
 import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.COMPATIBLE_CONFIG_KEY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.CONFIGURATORS_CATEGORY;
-import static org.apache.dubbo.registry.Constants.CONFIGURATORS_SUFFIX;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_CATEGORY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.DYNAMIC_CONFIGURATORS_CATEGORY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
@@ -81,6 +78,9 @@ import static 
org.apache.dubbo.common.constants.RegistryConstants.PROVIDERS_CATE
 import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.ROUTERS_CATEGORY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.ROUTE_PROTOCOL;
+import static org.apache.dubbo.registry.Constants.CONFIGURATORS_SUFFIX;
+import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
 
 
 /**
@@ -711,7 +711,7 @@ public class RegistryDirectory<T> extends 
AbstractDirectory<T> implements Notify
         ReferenceConfigurationListener(RegistryDirectory directory, URL url) {
             this.directory = directory;
             this.url = url;
-            this.initWith(url.getEncodedServiceKey() + CONFIGURATORS_SUFFIX);
+            this.initWith(DynamicConfiguration.getRuleKey(url) + 
CONFIGURATORS_SUFFIX);
         }
 
         @Override
diff --git 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
index b9ad1b3..e477674 100644
--- 
a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
+++ 
b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java
@@ -52,58 +52,58 @@ import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutorService;
 
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
-import static org.apache.dubbo.rpc.cluster.Constants.LOADBALANCE_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.WARMUP_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.WEIGHT_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
 import static 
org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
 import static 
org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
 import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
 import static 
org.apache.dubbo.common.constants.CommonConstants.HIDE_KEY_PREFIX;
 import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.common.constants.FilterConstants.VALIDATION_KEY;
 import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP;
-import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.EXPORT_KEY;
 import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE;
 import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT;
-import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
-import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
-import static org.apache.dubbo.common.constants.FilterConstants.VALIDATION_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
 import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.CONFIGURATORS_CATEGORY;
-import static org.apache.dubbo.registry.Constants.CONFIGURATORS_SUFFIX;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.CONSUMERS_CATEGORY;
-import static org.apache.dubbo.registry.Constants.CONSUMER_PROTOCOL;
-import static org.apache.dubbo.registry.Constants.DEFAULT_REGISTRY;
-import static org.apache.dubbo.registry.Constants.EXTRA_KEYS_KEY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.OVERRIDE_PROTOCOL;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.PROVIDERS_CATEGORY;
-import static org.apache.dubbo.registry.Constants.PROVIDER_PROTOCOL;
-import static org.apache.dubbo.registry.Constants.REGISTER_KEY;
 import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTOCOL;
 import static 
org.apache.dubbo.common.constants.RegistryConstants.ROUTERS_CATEGORY;
+import static org.apache.dubbo.common.utils.UrlUtils.classifyUrls;
+import static org.apache.dubbo.registry.Constants.CONFIGURATORS_SUFFIX;
+import static org.apache.dubbo.registry.Constants.CONSUMER_PROTOCOL;
+import static org.apache.dubbo.registry.Constants.DEFAULT_REGISTRY;
+import static org.apache.dubbo.registry.Constants.EXTRA_KEYS_KEY;
+import static org.apache.dubbo.registry.Constants.PROVIDER_PROTOCOL;
+import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
+import static org.apache.dubbo.registry.Constants.REGISTER_KEY;
 import static org.apache.dubbo.registry.Constants.SIMPLIFIED_KEY;
 import static org.apache.dubbo.remoting.Constants.BIND_IP_KEY;
 import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
 import static org.apache.dubbo.remoting.Constants.CHECK_KEY;
 import static org.apache.dubbo.remoting.Constants.CODEC_KEY;
-import static org.apache.dubbo.remoting.Constants.EXCHANGER_KEY;
-import static org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY;
 import static org.apache.dubbo.remoting.Constants.CONNECTIONS_KEY;
 import static org.apache.dubbo.remoting.Constants.DUBBO_VERSION_KEY;
+import static org.apache.dubbo.remoting.Constants.EXCHANGER_KEY;
+import static org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY;
 import static org.apache.dubbo.rpc.Constants.DEPRECATED_KEY;
 import static org.apache.dubbo.rpc.Constants.INTERFACES;
 import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
 import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
-import static org.apache.dubbo.common.utils.UrlUtils.classifyUrls;
+import static org.apache.dubbo.rpc.cluster.Constants.EXPORT_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.LOADBALANCE_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.WARMUP_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.WEIGHT_KEY;
 
 /**
  * RegistryProtocol
@@ -592,7 +592,7 @@ public class RegistryProtocol implements Protocol {
         public ServiceConfigurationListener(URL providerUrl, OverrideListener 
notifyListener) {
             this.providerUrl = providerUrl;
             this.notifyListener = notifyListener;
-            this.initWith(providerUrl.getEncodedServiceKey() + 
CONFIGURATORS_SUFFIX);
+            this.initWith(DynamicConfiguration.getRuleKey(providerUrl) + 
CONFIGURATORS_SUFFIX);
         }
 
         private <T> URL overrideUrl(URL providerUrl) {
diff --git 
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java
 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java
index c396455..b364df4 100644
--- 
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java
+++ 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java
@@ -52,7 +52,6 @@ import java.util.stream.Collectors;
 import static java.util.Collections.singleton;
 import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
 import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
@@ -455,24 +454,11 @@ public class NacosRegistry extends FailbackRegistry {
     }
 
     private String getServiceName(URL url) {
-        String category = url.getParameter(CATEGORY_KEY, DEFAULT_CATEGORY);
-        return getServiceName(url, category);
+        return getServiceName(url, url.getParameter(CATEGORY_KEY, 
DEFAULT_CATEGORY));
     }
 
     private String getServiceName(URL url, String category) {
-        StringBuilder serviceNameBuilder = new StringBuilder(category);
-        append(serviceNameBuilder, url, INTERFACE_KEY);
-        append(serviceNameBuilder, url, VERSION_KEY);
-        append(serviceNameBuilder, url, GROUP_KEY);
-        return serviceNameBuilder.toString();
-    }
-
-    private void append(StringBuilder target, URL url, String parameterName) {
-        target.append(SERVICE_NAME_SEPARATOR);
-        String parameterValue = url.getParameter(parameterName);
-        if (!StringUtils.isBlank(parameterValue)) {
-            target.append(parameterValue);
-        }
+        return category + SERVICE_NAME_SEPARATOR + url.getColonSeparatedKey();
     }
 
     private void execute(NamingServiceCallback callback) {

Reply via email to