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

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


The following commit(s) were added to refs/heads/master by this push:
     new f95e29a  [Dubbo-3846] Support Nacos as config center (#3988)
f95e29a is described below

commit f95e29a0e049046b066eec7e84643315dce5c0fb
Author: myPrecious <[email protected]>
AuthorDate: Thu May 9 22:23:03 2019 +0800

    [Dubbo-3846] Support Nacos as config center (#3988)
---
 dubbo-all/pom.xml                                  |   8 +
 dubbo-bom/pom.xml                                  |  10 +
 .../java/org/apache/dubbo/common/Constants.java    |   2 +
 .../dubbo-configcenter-nacos/pom.xml               |  45 ++++
 .../support/nacos/NacosDynamicConfiguration.java   | 265 +++++++++++++++++++++
 .../nacos/NacosDynamicConfigurationFactory.java    |  40 ++++
 ....dubbo.configcenter.DynamicConfigurationFactory |   1 +
 .../nacos/NacosDynamicConfigurationTest.java       | 136 +++++++++++
 dubbo-configcenter/pom.xml                         |   1 +
 .../integration/AbstractConfiguratorListener.java  |   3 +-
 10 files changed, 510 insertions(+), 1 deletion(-)

diff --git a/dubbo-all/pom.xml b/dubbo-all/pom.xml
index c353874..6dc00fb 100644
--- a/dubbo-all/pom.xml
+++ b/dubbo-all/pom.xml
@@ -417,6 +417,13 @@
         </dependency>
         <dependency>
             <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-nacos</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-configcenter-consul</artifactId>
             <version>${project.version}</version>
             <scope>compile</scope>
@@ -599,6 +606,7 @@
                                     
<include>org.apache.dubbo:dubbo-configcenter-zookeeper</include>
                                     
<include>org.apache.dubbo:dubbo-configcenter-consul</include>
                                     
<include>org.apache.dubbo:dubbo-configcenter-etcd</include>
+                                    
<include>org.apache.dubbo:dubbo-configcenter-nacos</include>
                                     
<include>org.apache.dubbo:dubbo-metadata-report-api</include>
                                     
<include>org.apache.dubbo:dubbo-metadata-definition</include>
                                     
<include>org.apache.dubbo:dubbo-metadata-report-redis</include>
diff --git a/dubbo-bom/pom.xml b/dubbo-bom/pom.xml
index a7e44dc..2b1e5fe 100644
--- a/dubbo-bom/pom.xml
+++ b/dubbo-bom/pom.xml
@@ -259,6 +259,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-registry-nacos</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-registry-sofa</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -404,6 +409,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-configcenter-nacos</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-metadata-definition</artifactId>
                 <version>${project.version}</version>
             </dependency>
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java 
b/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java
index cc52e77..31d5fc7 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java
@@ -200,6 +200,8 @@ public class Constants {
 
     public static final String PROPERTIES_CHAR_SEPERATOR = "-";
 
+    public static final String GROUP_CHAR_SEPERATOR = ":";
+
     public static final String HIDE_KEY_PREFIX = ".";
 
     public static final String DEFAULT_KEY_PREFIX = "default.";
diff --git a/dubbo-configcenter/dubbo-configcenter-nacos/pom.xml 
b/dubbo-configcenter/dubbo-configcenter-nacos/pom.xml
new file mode 100644
index 0000000..bd5397c
--- /dev/null
+++ b/dubbo-configcenter/dubbo-configcenter-nacos/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <parent>
+        <artifactId>dubbo-configcenter</artifactId>
+        <groupId>org.apache.dubbo</groupId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-configcenter-nacos</artifactId>
+    <packaging>jar</packaging>
+    <name>${project.artifactId}</name>
+    <description>The nacos implementation of the config-center 
api</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.nacos</groupId>
+            <artifactId>nacos-client</artifactId>
+        </dependency>
+    </dependencies>
+</project>
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
new file mode 100644
index 0000000..fdb536f
--- /dev/null
+++ 
b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
@@ -0,0 +1,265 @@
+/*
+ * 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.configcenter.support.nacos;
+
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.config.listener.AbstractSharedListener;
+import com.alibaba.nacos.api.exception.NacosException;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.configcenter.ConfigChangeEvent;
+import org.apache.dubbo.configcenter.ConfigChangeType;
+import org.apache.dubbo.configcenter.ConfigurationListener;
+import org.apache.dubbo.configcenter.DynamicConfiguration;
+
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
+import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
+import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
+import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
+import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
+import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
+import static 
com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
+import static org.apache.dubbo.common.Constants.BACKUP_KEY;
+import static org.apache.dubbo.common.Constants.CONFIG_NAMESPACE_KEY;
+import static org.apache.dubbo.common.Constants.GROUP_CHAR_SEPERATOR;
+import static org.apache.dubbo.common.Constants.PROPERTIES_CHAR_SEPERATOR;
+
+/**
+ * The nacos implementation of {@link DynamicConfiguration}
+ */
+public class NacosDynamicConfiguration implements DynamicConfiguration {
+
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+
+    /**
+     * The final root path would be: /$NAME_SPACE/config
+     */
+    private String rootPath;
+
+    /**
+     * The nacos configService
+     */
+
+    private ConfigService configService;
+
+    /**
+     * The map store the key to {@link NacosConfigListener} mapping
+     */
+    private final ConcurrentMap<String, NacosConfigListener> watchListenerMap;
+
+    NacosDynamicConfiguration(URL url) {
+        rootPath = url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP) + 
"-config";
+        buildConfigService(url);
+        watchListenerMap = new ConcurrentHashMap<>();
+    }
+
+    private ConfigService buildConfigService(URL url) {
+        Properties nacosProperties = buildNacosProperties(url);
+        try {
+            configService = NacosFactory.createConfigService(nacosProperties);
+        } catch (NacosException e) {
+            if (logger.isErrorEnabled()) {
+                logger.error(e.getErrMsg(), e);
+            }
+            throw new IllegalStateException(e);
+        }
+        return configService;
+    }
+
+    public void publishNacosConfig(String key, String value) {
+        try {
+            String[] keyAndGroup = getKeyAndGroup(key);
+            configService.publishConfig(keyAndGroup[0], keyAndGroup[1], value);
+        } catch (NacosException e) {
+            logger.error(e.getErrMsg());
+        }
+    }
+
+    private String[] getKeyAndGroup(String key) {
+        int i = key.lastIndexOf(GROUP_CHAR_SEPERATOR);
+        if (i < 0) {
+            return new String[]{key, null};
+        } else {
+            return new String[]{key.substring(0, i), key.substring(i+1)};
+        }
+    }
+
+    private Properties buildNacosProperties(URL url) {
+        Properties properties = new Properties();
+        setServerAddr(url, properties);
+        setProperties(url, properties);
+        return properties;
+    }
+
+    private void setServerAddr(URL url, Properties properties) {
+        StringBuilder serverAddrBuilder =
+                new StringBuilder(url.getHost()) // Host
+                        .append(":")
+                        .append(url.getPort()); // Port
+
+        // Append backup parameter as other servers
+        String backup = url.getParameter(BACKUP_KEY);
+        if (backup != null) {
+            serverAddrBuilder.append(",").append(backup);
+        }
+        String serverAddr = serverAddrBuilder.toString();
+        properties.put(SERVER_ADDR, serverAddr);
+    }
+
+    private void setProperties(URL url, Properties properties) {
+        putPropertyIfAbsent(url, properties, NAMESPACE);
+        putPropertyIfAbsent(url, properties, NACOS_NAMING_LOG_NAME);
+        putPropertyIfAbsent(url, properties, ENDPOINT);
+        putPropertyIfAbsent(url, properties, ACCESS_KEY);
+        putPropertyIfAbsent(url, properties, SECRET_KEY);
+        putPropertyIfAbsent(url, properties, CLUSTER_NAME);
+    }
+
+    private void putPropertyIfAbsent(URL url, Properties properties, String 
propertyName) {
+        String propertyValue = url.getParameter(propertyName);
+        if (StringUtils.isNotEmpty(propertyValue)) {
+            properties.setProperty(propertyName, propertyValue);
+        }
+    }
+
+    /**
+     * Ignores the group parameter.
+     *
+     * @param key   property key the native listener will listen on
+     * @param group to distinguish different set of properties
+     * @return
+     */
+    private NacosConfigListener createTargetListener(String key, String group) 
{
+        NacosConfigListener configListener = new NacosConfigListener();
+        configListener.fillContext(key, group);
+        return configListener;
+    }
+
+    @Override
+    public void addListener(String key, String group, ConfigurationListener 
listener) {
+        String[] keyAndGroup = getKeyAndGroup(key);
+        if (keyAndGroup[1] != null) {
+            group = keyAndGroup[1];
+        }
+        String finalGroup = group;
+        NacosConfigListener nacosConfigListener = 
watchListenerMap.computeIfAbsent(generateKey(key, group), k -> 
createTargetListener(key, finalGroup));
+        String keyInNacos = rootPath + PROPERTIES_CHAR_SEPERATOR + key;
+        nacosConfigListener.addListener(listener);
+        try {
+            configService.addListener(keyInNacos, group, nacosConfigListener);
+            System.out.println("1");
+        } catch (NacosException e) {
+            logger.error(e.getMessage());
+        }
+    }
+
+    private String generateKey(String key, String group) {
+        if (StringUtils.isNotEmpty(group)) {
+            key = key + GROUP_CHAR_SEPERATOR + group;
+        }
+        return key;
+    }
+
+    @Override
+    public void removeListener(String key, String group, ConfigurationListener 
listener) {
+        NacosConfigListener eventListener = 
watchListenerMap.get(generateKey(key, group));
+        if (eventListener != null) {
+            eventListener.removeListener(listener);
+        }
+    }
+
+    @Override
+    public String getConfig(String key, String group, long timeout) throws 
IllegalStateException {
+        key = generateKey(key, group);
+        return (String) getInternalProperty(rootPath + 
PROPERTIES_CHAR_SEPERATOR + key);
+    }
+
+    @Override
+    public Object getInternalProperty(String key) {
+        try {
+            String[] keyAndGroup = getKeyAndGroup(key);
+            return configService.getConfig(keyAndGroup[0], keyAndGroup[1], 
5000L);
+        } catch (NacosException e) {
+            logger.error(e.getMessage());
+        }
+        return null;
+    }
+
+    public class NacosConfigListener extends AbstractSharedListener {
+
+        private Set<ConfigurationListener> listeners = new 
CopyOnWriteArraySet<>();
+        /**
+         * cache data to store old value
+         */
+        private Map<String, String> cacheData = new ConcurrentHashMap<>();
+
+        @Override
+        public Executor getExecutor() {
+            return null;
+        }
+
+        /**
+         * receive
+         *
+         * @param dataId     data ID
+         * @param group      group
+         * @param configInfo content
+         */
+        @Override
+        public void innerReceive(String dataId, String group, String 
configInfo) {
+            String oldValue = cacheData.get(dataId);
+            ConfigChangeEvent event = new ConfigChangeEvent(dataId, 
configInfo, getChangeType(configInfo, oldValue));
+            if (configInfo == null) {
+                cacheData.remove(dataId);
+            } else {
+                cacheData.put(dataId, configInfo);
+            }
+            listeners.forEach(listener -> listener.process(event));
+        }
+
+        void addListener(ConfigurationListener configurationListener) {
+
+            this.listeners.add(configurationListener);
+        }
+
+        void removeListener(ConfigurationListener configurationListener) {
+            this.listeners.remove(configurationListener);
+        }
+
+        private ConfigChangeType getChangeType(String configInfo, String 
oldValue) {
+            if (StringUtils.isBlank(configInfo)) {
+                return ConfigChangeType.DELETED;
+            }
+            if (StringUtils.isBlank(oldValue)) {
+                return ConfigChangeType.ADDED;
+            }
+            return ConfigChangeType.MODIFIED;
+        }
+    }
+
+}
diff --git 
a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationFactory.java
 
b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationFactory.java
new file mode 100644
index 0000000..2246741
--- /dev/null
+++ 
b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationFactory.java
@@ -0,0 +1,40 @@
+/*
+ * 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.configcenter.support.nacos;
+
+import com.alibaba.nacos.api.PropertyKeyConst;
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.configcenter.AbstractDynamicConfigurationFactory;
+import org.apache.dubbo.configcenter.DynamicConfiguration;
+
+/**
+ * The nacos implementation of {@link AbstractDynamicConfigurationFactory}
+ */
+public class NacosDynamicConfigurationFactory extends 
AbstractDynamicConfigurationFactory {
+
+    @Override
+    protected DynamicConfiguration createDynamicConfiguration(URL url) {
+        URL nacosURL = url;
+        if 
(Constants.DUBBO.equals(url.getParameter(PropertyKeyConst.NAMESPACE))) {
+            // Nacos use empty string as default name space, replace default 
namespace "dubbo" to ""
+            nacosURL = url.removeParameter(PropertyKeyConst.NAMESPACE);
+        }
+        return new NacosDynamicConfiguration(nacosURL);
+    }
+}
diff --git 
a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.configcenter.DynamicConfigurationFactory
 
b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.configcenter.DynamicConfigurationFactory
new file mode 100644
index 0000000..b9c75a4
--- /dev/null
+++ 
b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.configcenter.DynamicConfigurationFactory
@@ -0,0 +1 @@
+nacos=org.apache.dubbo.configcenter.support.nacos.NacosDynamicConfigurationFactory
\ No newline at end of file
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
new file mode 100644
index 0000000..f5ac1d3
--- /dev/null
+++ 
b/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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.configcenter.support.nacos;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.configcenter.ConfigChangeEvent;
+import org.apache.dubbo.configcenter.ConfigurationListener;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Disabled;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Unit test for nacos config center support
+ */
+@Disabled
+public class NacosDynamicConfigurationTest {
+
+    private static NacosDynamicConfiguration config;
+
+    @Test
+    public void testGetConfig() throws Exception {
+
+        put("dubbo-config-org.apache.dubbo.nacos.testService.configurators", 
"hello");
+        Thread.sleep(200);
+        put("dubbo-config-dubbo.properties:test", "aaa=bbb");
+        Thread.sleep(200);
+        Assertions.assertEquals("hello", 
config.getConfig("org.apache.dubbo.nacos.testService.configurators"));
+        Assertions.assertEquals("aaa=bbb", 
config.getConfig("dubbo.properties", "test"));
+    }
+
+    @Test
+    public void testAddListener() throws Exception {
+        CountDownLatch latch = new CountDownLatch(4);
+        TestListener listener1 = new TestListener(latch);
+        TestListener listener2 = new TestListener(latch);
+        TestListener listener3 = new TestListener(latch);
+        TestListener listener4 = new TestListener(latch);
+
+
+        config.addListener("AService.configurators", listener1);
+        config.addListener("AService.configurators", listener2);
+        config.addListener("testapp.tagrouters", listener3);
+        config.addListener("testapp.tagrouters", listener4);
+
+        put("dubbo-config-AService.configurators", "new value1");
+        Thread.sleep(200);
+        put("dubbo-config-testapp.tagrouters", "new value2");
+        Thread.sleep(200);
+        put("dubbo-config-testapp", "new value3");
+        Thread.sleep(5000);
+
+        latch.await();
+
+        Assertions.assertEquals(1, 
listener1.getCount("dubbo-config-AService.configurators"));
+        Assertions.assertEquals(1, 
listener2.getCount("dubbo-config-AService.configurators"));
+        Assertions.assertEquals(1, 
listener3.getCount("dubbo-config-testapp.tagrouters"));
+        Assertions.assertEquals(1, 
listener4.getCount("dubbo-config-testapp.tagrouters"));
+
+        Assertions.assertEquals("new value1", listener1.getValue());
+        Assertions.assertEquals("new value1", listener2.getValue());
+        Assertions.assertEquals("new value2", listener3.getValue());
+        Assertions.assertEquals("new value2", listener4.getValue());
+
+    }
+
+    private void put(String key, String value) {
+        try {
+            config.publishNacosConfig(key, value);
+        } catch (Exception e) {
+            System.out.println("Error put value to nacos.");
+        }
+    }
+
+    @BeforeAll
+    public static void setUp() {
+        String urlForDubbo = "nacos://" + "127.0.0.1:8848" + 
"/org.apache.dubbo.nacos.testService";
+        // timeout in 15 seconds.
+        URL url = URL.valueOf(urlForDubbo)
+                .addParameter(Constants.SESSION_TIMEOUT_KEY, 15000);
+        config = new NacosDynamicConfiguration(url);
+    }
+
+    @AfterAll
+    public static void tearDown() {
+    }
+
+    private class TestListener implements ConfigurationListener {
+        private CountDownLatch latch;
+        private String value;
+        private Map<String, Integer> countMap = new HashMap<>();
+
+        public TestListener(CountDownLatch latch) {
+            this.latch = latch;
+        }
+
+        @Override
+        public void process(ConfigChangeEvent event) {
+            System.out.println(this + ": " + event);
+            Integer count = countMap.computeIfAbsent(event.getKey(), k -> new 
Integer(0));
+            countMap.put(event.getKey(), ++count);
+            value = event.getValue();
+            latch.countDown();
+        }
+
+        public int getCount(String key) {
+            return countMap.get(key);
+        }
+
+        public String getValue() {
+            return value;
+        }
+    }
+
+}
diff --git a/dubbo-configcenter/pom.xml b/dubbo-configcenter/pom.xml
index c6fb983..0de20d3 100644
--- a/dubbo-configcenter/pom.xml
+++ b/dubbo-configcenter/pom.xml
@@ -35,5 +35,6 @@
         <module>dubbo-configcenter-apollo</module>
         <module>dubbo-configcenter-consul</module>
         <module>dubbo-configcenter-etcd</module>
+        <module>dubbo-configcenter-nacos</module>
     </modules>
 </project>
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 8b0b43f..3aea7e6 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,6 +16,7 @@
  */
 package org.apache.dubbo.registry.integration;
 
+import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.StringUtils;
@@ -41,7 +42,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);
+        String rawConfig = dynamicConfiguration.getConfig(key, 
Constants.DUBBO);
         if (!StringUtils.isEmpty(rawConfig)) {
             process(new ConfigChangeEvent(key, rawConfig));
         }

Reply via email to