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

iluo 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 a206dde  [Dubbo-3653] Enable etcd to support metadata center (#3943)
a206dde is described below

commit a206dde6cd65d4273adfd6c84dd3be711c3b5a5d
Author: Huxing Zhang <[email protected]>
AuthorDate: Sun May 5 15:13:45 2019 +0800

    [Dubbo-3653] Enable etcd to support metadata center (#3943)
    
    * Support etcd as metadata center
    
    * Fix key format error for consul/redis and UT failure
    
    * Fix UT failure
    
    * Fix UT failure
    
    * Fix UT failure
---
 dubbo-all/pom.xml                                  |   7 ++
 dubbo-bom/pom.xml                                  |   5 +
 .../support/etcd/EtcdDynamicConfigurationTest.java |   1 -
 dubbo-distribution/pom.xml                         |  50 ++++++++
 .../metadata/identifier/MetadataIdentifier.java    |   6 +-
 .../dubbo/metadata/store/MetadataReport.java       |   3 -
 .../metadata/support/AbstractMetadataReport.java   |  15 +--
 .../identifier/MetadataIdentifierTest.java         |  14 ++-
 .../store/test/JTestMetadataReport4Test.java       |   2 +-
 .../store/consul/ConsulMetadataReport.java         |   2 +-
 .../dubbo-metadata-report-etcd/pom.xml             |  53 +++++++++
 .../metadata/store/etcd/EtcdMetadataReport.java}   |  78 ++++++------
 .../store/etcd/EtcdMetadataReportFactory.java      |  50 ++++++++
 ...ache.dubbo.metadata.store.MetadataReportFactory |   1 +
 .../store/etcd/EtcdMetadata4TstService.java}       |  18 +--
 .../store/etcd/EtcdMetadataReportTest.java         | 132 +++++++++++++++++++++
 .../metadata/store/redis/RedisMetadataReport.java  |   2 +-
 .../store/redis/RedisMetadataReportTest.java       |   9 +-
 .../store/zookeeper/ZookeeperMetadataReport.java   |  18 +--
 .../zookeeper/ZookeeperMetadataReportTest.java     |   3 +-
 dubbo-metadata-report/pom.xml                      |   1 +
 21 files changed, 372 insertions(+), 98 deletions(-)

diff --git a/dubbo-all/pom.xml b/dubbo-all/pom.xml
index f1ed094..a5e674a 100644
--- a/dubbo-all/pom.xml
+++ b/dubbo-all/pom.xml
@@ -450,6 +450,13 @@
             <scope>compile</scope>
             <optional>true</optional>
         </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-etcd</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
 
         <!-- Transitive dependencies -->
         <dependency>
diff --git a/dubbo-bom/pom.xml b/dubbo-bom/pom.xml
index 148b49a..2a6ef72 100644
--- a/dubbo-bom/pom.xml
+++ b/dubbo-bom/pom.xml
@@ -359,6 +359,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
+                <artifactId>dubbo-metadata-report-etcd</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo-configcenter-api</artifactId>
                 <version>${project.version}</version>
             </dependency>
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 4e305ea..0f07cab 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
@@ -120,7 +120,6 @@ public class EtcdDynamicConfigurationTest {
 
     private void put(String key, String value) {
         try {
-
             client.getKVClient().put(ByteSequence.from(key, UTF_8), 
ByteSequence.from(value, UTF_8)).get();
         } catch (Exception e) {
             System.out.println("Error put value to etcd.");
diff --git a/dubbo-distribution/pom.xml b/dubbo-distribution/pom.xml
index e92363d..76e73a3 100644
--- a/dubbo-distribution/pom.xml
+++ b/dubbo-distribution/pom.xml
@@ -187,6 +187,56 @@
         </dependency>
         <dependency>
             <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-zookeeper</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-apollo</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-consul</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-configcenter-etcd</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-zookeeper</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-redis</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-consul</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-etcd</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-monitor-api</artifactId>
             <version>${project.version}</version>
         </dependency>
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/identifier/MetadataIdentifier.java
 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/identifier/MetadataIdentifier.java
index fca21bf..457b3b6 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/identifier/MetadataIdentifier.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/identifier/MetadataIdentifier.java
@@ -23,8 +23,10 @@ import org.apache.dubbo.common.URL;
  * 2018/10/25
  */
 public class MetadataIdentifier {
+
     public static final String SEPARATOR = ":";
     final static String DEFAULT_PATH_TAG = "metadata";
+    final static String META_DATA_STORE_TAG = ".metaData";
 
     private String serviceInterface;
     private String version;
@@ -53,9 +55,9 @@ public class MetadataIdentifier {
 
     public String getUniqueKey(KeyTypeEnum keyType) {
         if (keyType == KeyTypeEnum.PATH) {
-            return getFilePathKey();
+            return getFilePathKey() + Constants.PATH_SEPARATOR + 
DEFAULT_PATH_TAG;
         }
-        return getIdentifierKey();
+        return getIdentifierKey() + META_DATA_STORE_TAG;
     }
 
     public String getIdentifierKey() {
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/store/MetadataReport.java
 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/store/MetadataReport.java
index 922f97c..1afcc83 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/store/MetadataReport.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/store/MetadataReport.java
@@ -26,9 +26,6 @@ import java.util.Map;
  */
 public interface MetadataReport {
 
-    public static final String META_DATA_STORE_TAG = ".metaData";
-
-
     void storeProviderMetadata(MetadataIdentifier providerMetadataIdentifier, 
FullServiceDefinition serviceDefinition);
 
     void storeConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, 
Map<String, String> serviceParameterMap);
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/support/AbstractMetadataReport.java
 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/support/AbstractMetadataReport.java
index 95b44f4..16daa2e 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/support/AbstractMetadataReport.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/support/AbstractMetadataReport.java
@@ -56,6 +56,7 @@ import java.util.concurrent.atomic.AtomicLong;
  */
 public abstract class AbstractMetadataReport implements MetadataReport {
 
+    protected final static String DEFAULT_ROOT = "dubbo";
 
     private static final int ONE_DAY_IN_MIll = 60 * 24 * 60 * 1000;
     private static final int FOUR_HOURS_IN_MIll = 60 * 4 * 60 * 1000;
@@ -216,12 +217,7 @@ public abstract class AbstractMetadataReport implements 
MetadataReport {
         if (syncReport) {
             storeProviderMetadataTask(providerMetadataIdentifier, 
serviceDefinition);
         } else {
-            reportCacheExecutor.execute(new Runnable() {
-                @Override
-                public void run() {
-                    storeProviderMetadataTask(providerMetadataIdentifier, 
serviceDefinition);
-                }
-            });
+            reportCacheExecutor.execute(() -> 
storeProviderMetadataTask(providerMetadataIdentifier, serviceDefinition));
         }
     }
 
@@ -249,12 +245,7 @@ public abstract class AbstractMetadataReport implements 
MetadataReport {
         if (syncReport) {
             storeConsumerMetadataTask(consumerMetadataIdentifier, 
serviceParameterMap);
         } else {
-            reportCacheExecutor.execute(new Runnable() {
-                @Override
-                public void run() {
-                    storeConsumerMetadataTask(consumerMetadataIdentifier, 
serviceParameterMap);
-                }
-            });
+            reportCacheExecutor.execute(() -> 
storeConsumerMetadataTask(consumerMetadataIdentifier, serviceParameterMap));
         }
     }
 
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/test/java/org/apache/dubbo/metadata/identifier/MetadataIdentifierTest.java
 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/test/java/org/apache/dubbo/metadata/identifier/MetadataIdentifierTest.java
index 40fab45..ca415b4 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/test/java/org/apache/dubbo/metadata/identifier/MetadataIdentifierTest.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/test/java/org/apache/dubbo/metadata/identifier/MetadataIdentifierTest.java
@@ -21,6 +21,8 @@ import org.apache.dubbo.common.Constants;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
+import static 
org.apache.dubbo.metadata.identifier.MetadataIdentifier.META_DATA_STORE_TAG;
+
 /**
  * 2019/1/7
  */
@@ -34,10 +36,16 @@ public class MetadataIdentifierTest {
         String application = "vic.zk.md";
         MetadataIdentifier providerMetadataIdentifier = new 
MetadataIdentifier(interfaceName, version, group, Constants.PROVIDER_SIDE, 
application);
         
System.out.println(providerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH));
-        
Assertions.assertEquals(providerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH),
 "metadata" + Constants.PATH_SEPARATOR + interfaceName + 
Constants.PATH_SEPARATOR + (version == null ? "" : (version + 
Constants.PATH_SEPARATOR))
-                + (group == null ? "" : (group + Constants.PATH_SEPARATOR)) + 
Constants.PROVIDER_SIDE + Constants.PATH_SEPARATOR + application);
+        
Assertions.assertEquals(providerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH),
+                "metadata" + Constants.PATH_SEPARATOR + interfaceName + 
Constants.PATH_SEPARATOR +
+                        (version == null ? "" : (version + 
Constants.PATH_SEPARATOR))
+                + (group == null ? "" : (group + Constants.PATH_SEPARATOR)) + 
Constants.PROVIDER_SIDE
+                        + Constants.PATH_SEPARATOR + application + 
Constants.PATH_SEPARATOR + "metadata");
         
System.out.println(providerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY));
         
Assertions.assertEquals(providerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY),
-                interfaceName + MetadataIdentifier.SEPARATOR + (version == 
null ? "" : version + MetadataIdentifier.SEPARATOR) + (group == null ? "" : 
group + MetadataIdentifier.SEPARATOR) + Constants.PROVIDER_SIDE + 
MetadataIdentifier.SEPARATOR + application);
+                interfaceName + MetadataIdentifier.SEPARATOR +
+                        (version == null ? "" : version + 
MetadataIdentifier.SEPARATOR)
+                        + (group == null ? "" : group + 
MetadataIdentifier.SEPARATOR)
+                        + Constants.PROVIDER_SIDE + 
MetadataIdentifier.SEPARATOR + application + META_DATA_STORE_TAG);
     }
 }
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/test/java/org/apache/dubbo/metadata/store/test/JTestMetadataReport4Test.java
 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/test/java/org/apache/dubbo/metadata/store/test/JTestMetadataReport4Test.java
index 76778ce..f5c1296 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/test/java/org/apache/dubbo/metadata/store/test/JTestMetadataReport4Test.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-api/src/test/java/org/apache/dubbo/metadata/store/test/JTestMetadataReport4Test.java
@@ -54,7 +54,7 @@ public class JTestMetadataReport4Test extends 
AbstractMetadataReport {
 
     @Override
     protected void doStoreConsumerMetadata(MetadataIdentifier 
consumerMetadataIdentifier, String serviceParameterString) {
-        store.put(consumerMetadataIdentifier.getIdentifierKey(), 
serviceParameterString);
+        
store.put(consumerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY),
 serviceParameterString);
     }
 
     public static String getProviderKey(URL url) {
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java
 
b/dubbo-metadata-report/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java
index 7bc6e7e..42a2f60 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java
@@ -55,7 +55,7 @@ public class ConsulMetadataReport extends 
AbstractMetadataReport {
 
     private void storeMetadata(MetadataIdentifier identifier, String v) {
         try {
-            client.setKVValue(identifier.getIdentifierKey() + 
META_DATA_STORE_TAG, v);
+            
client.setKVValue(identifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY),
 v);
         } catch (Throwable t) {
             logger.error("Failed to put " + identifier + " to consul " + v + 
", cause: " + t.getMessage(), t);
             throw new RpcException("Failed to put " + identifier + " to consul 
" + v + ", cause: " + t.getMessage(), t);
diff --git a/dubbo-metadata-report/dubbo-metadata-report-etcd/pom.xml 
b/dubbo-metadata-report/dubbo-metadata-report-etcd/pom.xml
new file mode 100644
index 0000000..6ab0c1e
--- /dev/null
+++ b/dubbo-metadata-report/dubbo-metadata-report-etcd/pom.xml
@@ -0,0 +1,53 @@
+<?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-metadata-report</artifactId>
+        <groupId>org.apache.dubbo</groupId>
+        <version>2.7.2-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-metadata-report-etcd</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-report-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-etcd3</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.etcd</groupId>
+            <artifactId>jetcd-launcher</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>testcontainers</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
 
b/dubbo-metadata-report/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java
similarity index 57%
copy from 
dubbo-metadata-report/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
copy to 
dubbo-metadata-report/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java
index 8194e1a..0a472f5 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java
@@ -14,35 +14,48 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.metadata.store.zookeeper;
+
+/*
+ * 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.metadata.store.etcd;
 
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
 import org.apache.dubbo.metadata.support.AbstractMetadataReport;
-import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
-import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
-
-import java.util.List;
+import org.apache.dubbo.remoting.etcd.jetcd.JEtcdClient;
 
 /**
- * ZookeeperMetadataReport
+ * Report Metadata to Etcd
  */
-public class ZookeeperMetadataReport extends AbstractMetadataReport {
-
-    private final static Logger logger = 
LoggerFactory.getLogger(ZookeeperMetadataReport.class);
+public class EtcdMetadataReport extends AbstractMetadataReport {
 
-    private final static String DEFAULT_ROOT = "dubbo";
-    private final static String METADATA_NODE_NAME = "service.data";
+    private final static Logger logger = 
LoggerFactory.getLogger(EtcdMetadataReport.class);
 
     private final String root;
 
-    final ZookeeperClient zkClient;
+    /**
+     * The etcd client
+     */
+    private final JEtcdClient etcdClient;
 
-    public ZookeeperMetadataReport(URL url, ZookeeperTransporter 
zookeeperTransporter) {
+    public EtcdMetadataReport(URL url) {
         super(url);
         if (url.isAnyHost()) {
             throw new IllegalStateException("registry address == null");
@@ -52,24 +65,7 @@ public class ZookeeperMetadataReport extends 
AbstractMetadataReport {
             group = Constants.PATH_SEPARATOR + group;
         }
         this.root = group;
-        zkClient = zookeeperTransporter.connect(url);
-    }
-
-    void deletePath(String category) {
-        List<String> urlStrs = zkClient.getChildren(category);
-        if (CollectionUtils.isEmpty(urlStrs)) {
-            return;
-        }
-        for (String urlStr : urlStrs) {
-            zkClient.delete(category + Constants.PATH_SEPARATOR + urlStr);
-        }
-    }
-
-    String toRootDir() {
-        if (root.equals(Constants.PATH_SEPARATOR)) {
-            return root;
-        }
-        return root + Constants.PATH_SEPARATOR;
+        etcdClient = new JEtcdClient(url);
     }
 
     @Override
@@ -82,13 +78,21 @@ public class ZookeeperMetadataReport extends 
AbstractMetadataReport {
         storeMetadata(consumerMetadataIdentifier, value);
     }
 
-    private void storeMetadata(MetadataIdentifier metadataIdentifier, String 
v) {
-        zkClient.create(getNodePath(metadataIdentifier), v, false);
+    private void storeMetadata(MetadataIdentifier identifier, String v) {
+        String key = getNodeKey(identifier);
+        if (!etcdClient.put(key, v)) {
+            logger.error("Failed to put " + identifier + " to etcd, value: " + 
v);
+        }
     }
 
-    String getNodePath(MetadataIdentifier metadataIdentifier) {
-        return toRootDir() + 
metadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH) + 
Constants.PATH_SEPARATOR + METADATA_NODE_NAME;
+    String getNodeKey(MetadataIdentifier identifier) {
+        return toRootDir() + 
identifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH);
     }
 
-
+    String toRootDir() {
+        if (root.equals(Constants.PATH_SEPARATOR)) {
+            return root;
+        }
+        return root + Constants.PATH_SEPARATOR;
+    }
 }
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportFactory.java
 
b/dubbo-metadata-report/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportFactory.java
new file mode 100644
index 0000000..f0572b6
--- /dev/null
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportFactory.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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.metadata.store.etcd;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.metadata.store.MetadataReport;
+import org.apache.dubbo.metadata.support.AbstractMetadataReportFactory;
+
+/**
+ * MetadataReportFactory to create an Etcd based {@link MetadataReport}.
+ */
+public class EtcdMetadataReportFactory extends AbstractMetadataReportFactory {
+
+    @Override
+    public MetadataReport createMetadataReport(URL url) {
+        return new EtcdMetadataReport(url);
+    }
+
+}
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.store.MetadataReportFactory
 
b/dubbo-metadata-report/dubbo-metadata-report-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.store.MetadataReportFactory
new file mode 100644
index 0000000..9a3c98c
--- /dev/null
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.store.MetadataReportFactory
@@ -0,0 +1 @@
+etcd=org.apache.dubbo.metadata.store.etcd.EtcdMetadataReportFactory
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/store/MetadataReport.java
 
b/dubbo-metadata-report/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadata4TstService.java
similarity index 59%
copy from 
dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/store/MetadataReport.java
copy to 
dubbo-metadata-report/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadata4TstService.java
index 922f97c..1de21ce 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/store/MetadataReport.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadata4TstService.java
@@ -14,23 +14,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.metadata.store;
 
-
-import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
-import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
-
-import java.util.Map;
+package org.apache.dubbo.metadata.store.etcd;
 
 /**
+ * Test interface for Etcd metadata report
  */
-public interface MetadataReport {
-
-    public static final String META_DATA_STORE_TAG = ".metaData";
-
-
-    void storeProviderMetadata(MetadataIdentifier providerMetadataIdentifier, 
FullServiceDefinition serviceDefinition);
+public interface EtcdMetadata4TstService {
 
-    void storeConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, 
Map<String, String> serviceParameterMap);
+    int getCounter();
 
+    void printResult(String var);
 }
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportTest.java
 
b/dubbo-metadata-report/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportTest.java
new file mode 100644
index 0000000..e6f6b02
--- /dev/null
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.metadata.store.etcd;
+
+import com.google.gson.Gson;
+import io.etcd.jetcd.ByteSequence;
+import io.etcd.jetcd.Client;
+import io.etcd.jetcd.kv.GetResponse;
+import io.etcd.jetcd.launcher.EtcdCluster;
+import io.etcd.jetcd.launcher.EtcdClusterFactory;
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
+import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
+import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Unit test for etcd metadata report
+ */
+public class EtcdMetadataReportTest {
+
+    private static final String TEST_SERVICE = 
"org.apache.dubbo.metadata.store.etcd.EtcdMetadata4TstService";
+
+    private EtcdCluster etcdCluster = 
EtcdClusterFactory.buildCluster(getClass().getSimpleName(), 1, false, false);
+    private Client etcdClientForTest;
+    private EtcdMetadataReport etcdMetadataReport;
+    private URL registryUrl;
+    private EtcdMetadataReportFactory etcdMetadataReportFactory;
+
+    @BeforeEach
+    public void setUp() {
+        etcdCluster.start();
+        etcdClientForTest = 
Client.builder().endpoints(etcdCluster.getClientEndpoints()).build();
+        List<URI> clientEndPoints = etcdCluster.getClientEndpoints();
+        this.registryUrl = URL.valueOf("etcd://" + 
clientEndPoints.get(0).getHost() + ":" + clientEndPoints.get(0).getPort());
+        etcdMetadataReportFactory = new EtcdMetadataReportFactory();
+        this.etcdMetadataReport = (EtcdMetadataReport) 
etcdMetadataReportFactory.createMetadataReport(registryUrl);
+    }
+
+    @AfterEach
+    public void tearDown() throws Exception {
+        etcdCluster.close();
+    }
+
+    @Test
+    public void testStoreProvider() throws Exception {
+        String version = "1.0.0";
+        String group = null;
+        String application = "etcd-metdata-report-test";
+        MetadataIdentifier providerIdentifier =
+                storeProvider(etcdMetadataReport, TEST_SERVICE, version, 
group, application);
+
+        CompletableFuture<GetResponse> response = 
etcdClientForTest.getKVClient().get(ByteSequence.from(
+                etcdMetadataReport.getNodeKey(providerIdentifier), 
StandardCharsets.UTF_8));
+        String fileContent = 
response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
+        Assertions.assertNotNull(fileContent);
+
+        Gson gson = new Gson();
+        FullServiceDefinition fullServiceDefinition = 
gson.fromJson(fileContent, FullServiceDefinition.class);
+        
Assertions.assertEquals(fullServiceDefinition.getParameters().get("paramTest"), 
"etcdTest");
+    }
+
+    @Test
+    public void testStoreConsumer() throws Exception {
+        String version = "1.0.0";
+        String group = null;
+        String application = "etc-metadata-report-consumer-test";
+        MetadataIdentifier consumerIdentifier = 
storeConsumer(etcdMetadataReport, TEST_SERVICE, version, group, application);
+
+        CompletableFuture<GetResponse> response = 
etcdClientForTest.getKVClient().get(ByteSequence.from(
+                etcdMetadataReport.getNodeKey(consumerIdentifier), 
StandardCharsets.UTF_8));
+        String fileContent = 
response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
+        Assertions.assertNotNull(fileContent);
+        Assertions.assertEquals(fileContent, 
"{\"paramConsumerTest\":\"etcdConsumer\"}");
+    }
+
+    private MetadataIdentifier storeProvider(EtcdMetadataReport 
etcdMetadataReport, String interfaceName, String version,
+                                             String group, String application)
+            throws ClassNotFoundException, InterruptedException {
+        URL url = URL.valueOf("xxx://" + 
NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName +
+                "?paramTest=etcdTest&version=" + version + "&application="
+                + application + (group == null ? "" : "&group=" + group));
+
+        MetadataIdentifier providerMetadataIdentifier =
+                new MetadataIdentifier(interfaceName, version, group, 
Constants.PROVIDER_SIDE, application);
+        Class interfaceClass = Class.forName(interfaceName);
+        FullServiceDefinition fullServiceDefinition =
+                ServiceDefinitionBuilder.buildFullDefinition(interfaceClass, 
url.getParameters());
+
+        etcdMetadataReport.storeProviderMetadata(providerMetadataIdentifier, 
fullServiceDefinition);
+        Thread.sleep(1000);
+        return providerMetadataIdentifier;
+    }
+
+    private MetadataIdentifier storeConsumer(EtcdMetadataReport 
etcdMetadataReport, String interfaceName,
+                                             String version, String group, 
String application) throws InterruptedException {
+
+        MetadataIdentifier consumerIdentifier = new 
MetadataIdentifier(interfaceName, version, group, Constants.CONSUMER_SIDE, 
application);
+        Map<String, String> tmp = new HashMap<>();
+        tmp.put("paramConsumerTest", "etcdConsumer");
+        etcdMetadataReport.storeConsumerMetadata(consumerIdentifier, tmp);
+        Thread.sleep(1000);
+        return consumerIdentifier;
+    }
+}
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java
 
b/dubbo-metadata-report/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java
index 42d8880..b00295c 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java
@@ -54,7 +54,7 @@ public class RedisMetadataReport extends 
AbstractMetadataReport {
 
     private void storeMetadata(MetadataIdentifier metadataIdentifier, String 
v) {
         try (Jedis jedis = pool.getResource()) {
-            jedis.set(metadataIdentifier.getIdentifierKey() + 
META_DATA_STORE_TAG, v);
+            
jedis.set(metadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY),
 v);
         } catch (Throwable e) {
             logger.error("Failed to put " + metadataIdentifier + " to redis " 
+ v + ", cause: " + e.getMessage(), e);
             throw new RpcException("Failed to put " + metadataIdentifier + " 
to redis " + v + ", cause: " + e.getMessage(), e);
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java
 
b/dubbo-metadata-report/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java
index 4984bde..5a6d4f5 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java
@@ -39,7 +39,6 @@ import java.util.HashMap;
 import java.util.Map;
 
 import static org.apache.dubbo.common.Constants.SYNC_REPORT_KEY;
-import static 
org.apache.dubbo.metadata.store.MetadataReport.META_DATA_STORE_TAG;
 
 /**
  * 2018/10/9
@@ -93,7 +92,7 @@ public class RedisMetadataReportTest {
         Jedis jedis = null;
         try {
             jedis = redisMetadataReport.pool.getResource();
-            String keyTmp = 
providerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY)
 + META_DATA_STORE_TAG;
+            String keyTmp = 
providerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY);
             String value = jedis.get(keyTmp);
             if (value == null) {
                 Thread.sleep(moreTime);
@@ -109,7 +108,7 @@ public class RedisMetadataReportTest {
             throw new RpcException("Failed to put to redis . cause: " + 
e.getMessage(), e);
         } finally {
             if (jedis != null) {
-                
jedis.del(providerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY)
 + META_DATA_STORE_TAG);
+                
jedis.del(providerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY));
             }
             redisMetadataReport.pool.close();
         }
@@ -133,7 +132,7 @@ public class RedisMetadataReportTest {
         Jedis jedis = null;
         try {
             jedis = redisMetadataReport.pool.getResource();
-            String keyTmp = 
consumerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY)
 + META_DATA_STORE_TAG;
+            String keyTmp = 
consumerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY);
             String value = jedis.get(keyTmp);
             if (value == null) {
                 Thread.sleep(moreTime);
@@ -144,7 +143,7 @@ public class RedisMetadataReportTest {
             throw new RpcException("Failed to put to redis . cause: " + 
e.getMessage(), e);
         } finally {
             if (jedis != null) {
-                
jedis.del(consumerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY)
 + META_DATA_STORE_TAG);
+                
jedis.del(consumerMetadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY));
             }
             redisMetadataReport.pool.close();
         }
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
 
b/dubbo-metadata-report/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
index 8194e1a..de26faf 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
@@ -20,14 +20,11 @@ import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
 import org.apache.dubbo.metadata.support.AbstractMetadataReport;
 import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
 import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
 
-import java.util.List;
-
 /**
  * ZookeeperMetadataReport
  */
@@ -35,9 +32,6 @@ public class ZookeeperMetadataReport extends 
AbstractMetadataReport {
 
     private final static Logger logger = 
LoggerFactory.getLogger(ZookeeperMetadataReport.class);
 
-    private final static String DEFAULT_ROOT = "dubbo";
-    private final static String METADATA_NODE_NAME = "service.data";
-
     private final String root;
 
     final ZookeeperClient zkClient;
@@ -55,16 +49,6 @@ public class ZookeeperMetadataReport extends 
AbstractMetadataReport {
         zkClient = zookeeperTransporter.connect(url);
     }
 
-    void deletePath(String category) {
-        List<String> urlStrs = zkClient.getChildren(category);
-        if (CollectionUtils.isEmpty(urlStrs)) {
-            return;
-        }
-        for (String urlStr : urlStrs) {
-            zkClient.delete(category + Constants.PATH_SEPARATOR + urlStr);
-        }
-    }
-
     String toRootDir() {
         if (root.equals(Constants.PATH_SEPARATOR)) {
             return root;
@@ -87,7 +71,7 @@ public class ZookeeperMetadataReport extends 
AbstractMetadataReport {
     }
 
     String getNodePath(MetadataIdentifier metadataIdentifier) {
-        return toRootDir() + 
metadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH) + 
Constants.PATH_SEPARATOR + METADATA_NODE_NAME;
+        return toRootDir() + 
metadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH);
     }
 
 
diff --git 
a/dubbo-metadata-report/dubbo-metadata-report-zookeeper/src/test/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportTest.java
 
b/dubbo-metadata-report/dubbo-metadata-report-zookeeper/src/test/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportTest.java
index c9ed9cf..da1e87b 100644
--- 
a/dubbo-metadata-report/dubbo-metadata-report-zookeeper/src/test/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportTest.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-report-zookeeper/src/test/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportTest.java
@@ -29,7 +29,6 @@ import org.apache.curator.test.TestingServer;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
 import java.util.HashMap;
@@ -62,7 +61,7 @@ public class ZookeeperMetadataReportTest {
 
     private void deletePath(MetadataIdentifier metadataIdentifier, 
ZookeeperMetadataReport zookeeperMetadataReport) {
         String category = zookeeperMetadataReport.toRootDir() + 
metadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH);
-        zookeeperMetadataReport.deletePath(category);
+        zookeeperMetadataReport.zkClient.delete(category);
     }
 
     @Test
diff --git a/dubbo-metadata-report/pom.xml b/dubbo-metadata-report/pom.xml
index 6d47af4..3cb254a 100644
--- a/dubbo-metadata-report/pom.xml
+++ b/dubbo-metadata-report/pom.xml
@@ -30,6 +30,7 @@
         <module>dubbo-metadata-report-redis</module>
         <module>dubbo-metadata-definition</module>
         <module>dubbo-metadata-report-consul</module>
+        <module>dubbo-metadata-report-etcd</module>
     </modules>
 
 

Reply via email to