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

albumenj pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.0 by this push:
     new 75443e1  test: Add testcases for checking Injvm protocol in multiple 
registry center (#8418)
75443e1 is described below

commit 75443e1c8e842c2ce700e7dd4d01a16921edd278
Author: Xiong, Pin <[email protected]>
AuthorDate: Thu Aug 5 23:49:09 2021 -0500

    test: Add testcases for checking Injvm protocol in multiple registry center 
(#8418)
    
    1. Refactor the previous source code for checking Injvm protocol in single 
registry center
    2. Verify the exported services through the custom ServiceListener in 
multiple registry center
    3. Verify the exported exporters through the custom ExporterListener in 
multiple registry center
    4. Verify the filter chain through the custom Filter in multiple registry 
center
---
 ...=> AbstractRegistryCenterExporterListener.java} |  24 ++-
 ... => AbstractRegistryCenterServiceListener.java} |  13 +-
 .../multiple/MultipleZooKeeperServer.java          | 225 +++++++++++++++++++++
 ...ultipleRegistryCenterInjvmExporterListener.java |  33 +++
 .../injvm/MultipleRegistryCenterInjvmFilter.java}  |  12 +-
 ...ultipleRegistryCenterInjvmIntegrationTest.java} |  82 ++++----
 .../injvm/MultipleRegistryCenterInjvmService.java  |  26 +++
 .../MultipleRegistryCenterInjvmServiceImpl.java    |  30 +++
 ...MultipleRegistryCenterInjvmServiceListener.java |  34 ++++
 .../dubbo/integration/multiple/package-info.java   |  22 ++
 ...RegistryCenterDubboProtocolIntegrationTest.java |  37 ++--
 ...ingleRegistryCenterExportedServiceListener.java |  34 ++++
 .../SingleRegistryCenterInjvmExporterListener.java |  33 +++
 ...r.java => SingleRegistryCenterInjvmFilter.java} |   2 +-
 .../SingleRegistryCenterInjvmIntegrationTest.java  |  34 ++--
 .../SingleRegistryCenterInjvmServiceListener.java  |  34 ++++
 .../single/listener/ExportedServiceListener.java   |  61 ------
 .../org.apache.dubbo.config.ServiceListener        |   5 +-
 .../services/org.apache.dubbo.rpc.ExporterListener |   3 +-
 .../META-INF/services/org.apache.dubbo.rpc.Filter  |   3 +-
 20 files changed, 575 insertions(+), 172 deletions(-)

diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/listener/InjvmExporterListener.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/AbstractRegistryCenterExporterListener.java
similarity index 87%
rename from 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/listener/InjvmExporterListener.java
rename to 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/AbstractRegistryCenterExporterListener.java
index 6f3ace1..c23e400 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/listener/InjvmExporterListener.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/AbstractRegistryCenterExporterListener.java
@@ -14,11 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.integration.single.listener;
+package org.apache.dubbo.integration;
 
-import org.apache.dubbo.common.constants.CommonConstants;
-import org.apache.dubbo.common.extension.Activate;
-import 
org.apache.dubbo.integration.single.injvm.SingleRegistryCenterInjvmService;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.ExporterListener;
 import org.apache.dubbo.rpc.Filter;
@@ -27,10 +24,16 @@ import 
org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder;
 import org.apache.dubbo.rpc.listener.ListenerExporterWrapper;
 
 import java.lang.reflect.Field;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
 
-@Activate(group = CommonConstants.PROVIDER, order = 1000)
-public class InjvmExporterListener implements ExporterListener {
+/**
+ * The abstraction of {@link ExporterListener} is to record exported 
exporters, which should be extended by different sub-classes.
+ */
+public abstract class AbstractRegistryCenterExporterListener implements 
ExporterListener {
 
     /**
      * Exported exporters.
@@ -43,6 +46,11 @@ public class InjvmExporterListener implements 
ExporterListener {
     private Set<Filter> filters = new HashSet<>();
 
     /**
+     * Returns the interface of exported service.
+     */
+    protected abstract Class<?> getInterface();
+
+    /**
      * {@inheritDoc}
      */
     @Override
@@ -50,7 +58,7 @@ public class InjvmExporterListener implements 
ExporterListener {
         ListenerExporterWrapper listenerExporterWrapper = 
(ListenerExporterWrapper) exporter;
         FilterChainBuilder.FilterChainNode filterChainNode = 
(FilterChainBuilder.FilterChainNode) listenerExporterWrapper.getInvoker();
         if (filterChainNode == null ||
-            filterChainNode.getInterface() != 
SingleRegistryCenterInjvmService.class) {
+            filterChainNode.getInterface() != getInterface()) {
             return;
         }
         exportedExporters.add(exporter);
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/listener/InjvmServiceListener.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/AbstractRegistryCenterServiceListener.java
similarity index 81%
rename from 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/listener/InjvmServiceListener.java
rename to 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/AbstractRegistryCenterServiceListener.java
index 0764b78..438e228 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/listener/InjvmServiceListener.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/AbstractRegistryCenterServiceListener.java
@@ -14,30 +14,33 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.integration.single.listener;
+package org.apache.dubbo.integration;
 
 import org.apache.dubbo.config.ServiceConfig;
 import org.apache.dubbo.config.ServiceListener;
-import 
org.apache.dubbo.integration.single.injvm.SingleRegistryCenterInjvmService;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
 /**
- * This implementation of {@link ServiceListener} is to record exported 
services with injvm protocol.
+ * This implementation of {@link ServiceListener} is to record exported 
services, which should be extended by different sub-classes.
  */
-public class InjvmServiceListener implements ServiceListener {
+public abstract class AbstractRegistryCenterServiceListener implements 
ServiceListener {
 
     private List<ServiceConfig> exportedServices = new ArrayList<>(2);
 
     /**
+     * Return the interface name of exported service.
+     */
+    protected abstract Class<?> getInterface();
+    /**
      * {@inheritDoc}
      */
     @Override
     public void exported(ServiceConfig sc) {
         //All exported services will be added
-        if (sc.getInterfaceClass() == SingleRegistryCenterInjvmService.class) {
+        if (sc.getInterfaceClass() == getInterface()) {
             exportedServices.add(sc);
         }
     }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/MultipleZooKeeperServer.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/MultipleZooKeeperServer.java
new file mode 100644
index 0000000..8780b70
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/MultipleZooKeeperServer.java
@@ -0,0 +1,225 @@
+/*
+ * 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.integration.multiple;
+
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.zookeeper.server.ServerConfig;
+import org.apache.zookeeper.server.ZooKeeperServerMain;
+import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.Properties;
+import java.util.UUID;
+
+/**
+ * The zookeeper server is just for testing.
+ * Also there is only one static instance, which can be created.
+ * <p>
+ * Note: It can only be used if the following conditions are satisfied
+ * <p>1. Integration testcase instead of unit testcase
+ * <p>2. You can use only one zookeeper instance per Package, because the 
zookeeper is a static global instance.
+ */
+public class MultipleZooKeeperServer {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(MultipleZooKeeperServer.class);
+
+    /**
+     * Define a static zookeeper instance.
+     */
+    private static volatile InnerZooKeeper INSTANCE_ONE;
+
+    /**
+     * Define a static zookeeper instance.
+     */
+    private static volatile InnerZooKeeper INSTANCE_TWO;
+
+    /**
+     * Start the zookeeper instances.
+     */
+    public static void start() {
+        if (INSTANCE_ONE == null) {
+            INSTANCE_ONE = new 
InnerZooKeeper("multiple-zookeeper-server-one-for-test",
+                NetUtils.getAvailablePort());
+            INSTANCE_ONE.start();
+        }
+        if (INSTANCE_TWO == null) {
+            INSTANCE_TWO = new 
InnerZooKeeper("multiple-zookeeper-server-two-for-test",
+                NetUtils.getAvailablePort());
+            INSTANCE_TWO.start();
+        }
+    }
+
+    /**
+     * Returns the zookeeper-one server's port.
+     */
+    public static int getPortOne() {
+        return INSTANCE_ONE.getClientPort();
+    }
+
+    /**
+     * Returns the zookeeper-two server's port.
+     */
+    public static int getPortTwo() {
+        return INSTANCE_TWO.getClientPort();
+    }
+
+    /**
+     * Checks if all zookeeper servers are running.
+     */
+    public static boolean isRunning() {
+        return INSTANCE_ONE.isRunning() && INSTANCE_TWO.isRunning();
+    }
+
+    /**
+     * Shutdown all zookeeper instances.
+     */
+    public static void shutdown() {
+        if (INSTANCE_ONE != null) {
+            INSTANCE_ONE.shutdown();
+            INSTANCE_ONE = null;
+        }
+
+        if (INSTANCE_TWO != null) {
+            INSTANCE_TWO.shutdown();
+            INSTANCE_TWO = null;
+        }
+    }
+
+    /**
+     * from: 
https://github.com/spring-projects/spring-xd/blob/v1.3.1.RELEASE/spring-xd-dirt/src/main/java/org/springframework/xd/dirt/zookeeper/ZooKeeperUtils.java
+     * <p>
+     * Helper class to start an embedded instance of standalone (non 
clustered) ZooKeeper.
+     * <p>
+     * NOTE: at least an external standalone server (if not an ensemble) are 
recommended, even for
+     */
+    private static class InnerZooKeeper {
+
+        /**
+         * ZooKeeper client port. This will be determined dynamically upon 
startup.
+         */
+        private final int clientPort;
+
+        /**
+         * ZooKeeper name.
+         */
+        private final String zookeeperName;
+
+        /**
+         * Thread for running the ZooKeeper server.
+         */
+        private volatile Thread zkServerThread;
+
+        /**
+         * ZooKeeper server.
+         */
+        private volatile ZooKeeperServerMain zkServer;
+
+        /**
+         * Construct an EmbeddedZooKeeper with the provided port.
+         *
+         * @param zookeeperName zookeeper name
+         * @param clientPort port for ZooKeeper server to bind to
+         */
+        public InnerZooKeeper(String zookeeperName, int clientPort) {
+            this.zookeeperName = zookeeperName;
+            this.clientPort = clientPort;
+        }
+
+        /**
+         * Returns the port that clients should use to connect to this 
embedded server.
+         *
+         * @return dynamically determined client port
+         */
+        public int getClientPort() {
+            return this.clientPort;
+        }
+
+        /**
+         * Checks if the zookeeper server is running.
+         */
+        public boolean isRunning() {
+            return (zkServerThread != null);
+        }
+
+        /**
+         * Start the ZooKeeper server in a background thread.
+         * <p>
+         * any exceptions thrown during startup or execution.
+         */
+        private synchronized void start() {
+            if (zkServerThread == null) {
+                zkServerThread = new Thread(() -> {
+                    try {
+                        Properties properties = new Properties();
+                        File file = new 
File(System.getProperty("java.io.tmpdir")
+                            + File.separator + UUID.randomUUID());
+                        file.deleteOnExit();
+                        properties.setProperty("dataDir", 
file.getAbsolutePath());
+                        properties.setProperty("clientPort", 
String.valueOf(clientPort));
+
+                        QuorumPeerConfig quorumPeerConfig = new 
QuorumPeerConfig();
+                        quorumPeerConfig.parseProperties(properties);
+
+                        zkServer = new ZooKeeperServerMain();
+                        ServerConfig configuration = new ServerConfig();
+                        configuration.readFrom(quorumPeerConfig);
+
+                        zkServer.runFromConfig(configuration);
+                    } catch (Exception e) {
+                        logger.error("Exception running embedded ZooKeeper", 
e);
+                    }
+                }, zookeeperName);
+                zkServerThread.setDaemon(true);
+                zkServerThread.start();
+            }
+        }
+
+        /**
+         * Shutdown the ZooKeeper server.
+         */
+        private synchronized void shutdown() {
+            if (zkServerThread != null) {
+                // The shutdown method is protected...thus this hack to invoke 
it.
+                // This will log an exception on shutdown; see
+                // https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for 
details.
+                try {
+                    Method shutdown = 
ZooKeeperServerMain.class.getDeclaredMethod("shutdown");
+                    shutdown.setAccessible(true);
+                    shutdown.invoke(zkServer);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+
+                // It is expected that the thread will exit after
+                // the server is shutdown; this will block until
+                // the shutdown is complete.
+                try {
+                    zkServerThread.join(5000);
+                    zkServerThread = null;
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    logger.warn("Interrupted while waiting for embedded 
ZooKeeper to exit");
+                    // abandoning zk thread
+                    zkServerThread = null;
+                }
+            }
+        }
+    }
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmExporterListener.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmExporterListener.java
new file mode 100644
index 0000000..1820a12
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmExporterListener.java
@@ -0,0 +1,33 @@
+/*
+ * 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.integration.multiple.injvm;
+
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.integration.AbstractRegistryCenterExporterListener;
+
+@Activate(group = CommonConstants.PROVIDER, order = 1000)
+public class MultipleRegistryCenterInjvmExporterListener extends 
AbstractRegistryCenterExporterListener {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Class<?> getInterface() {
+        return MultipleRegistryCenterInjvmService.class;
+    }
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/InjvmFilter.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmFilter.java
similarity index 85%
copy from 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/InjvmFilter.java
copy to 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmFilter.java
index cb45038..658924d 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/InjvmFilter.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmFilter.java
@@ -14,18 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.integration.single.injvm;
+package org.apache.dubbo.integration.multiple.injvm;
 
 import org.apache.dubbo.common.constants.CommonConstants;
 import org.apache.dubbo.common.extension.Activate;
-import org.apache.dubbo.rpc.Filter;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.*;
 
-@Activate(group = CommonConstants.PROVIDER, order = 10000)
-public class InjvmFilter implements Filter,Filter.Listener {
+@Activate(group = CommonConstants.PROVIDER, order = 10200)
+public class MultipleRegistryCenterInjvmFilter implements 
Filter,Filter.Listener{
 
     /**
      * The filter is called or not
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmIntegrationTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmIntegrationTest.java
similarity index 67%
copy from 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmIntegrationTest.java
copy to 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmIntegrationTest.java
index 052f9dd..815c759 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmIntegrationTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmIntegrationTest.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.integration.single.injvm;
+package org.apache.dubbo.integration.multiple.injvm;
 
 import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.config.ServiceConfig;
@@ -25,15 +25,13 @@ import org.apache.dubbo.config.RegistryConfig;
 import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.integration.IntegrationTest;
-import org.apache.dubbo.integration.single.SingleZooKeeperServer;
-import org.apache.dubbo.integration.single.listener.InjvmExporterListener;
-import org.apache.dubbo.integration.single.listener.InjvmServiceListener;
+import org.apache.dubbo.integration.multiple.MultipleZooKeeperServer;
+import 
org.apache.dubbo.integration.single.injvm.SingleRegistryCenterInjvmService;
 import org.apache.dubbo.rpc.ExporterListener;
 import org.apache.dubbo.rpc.Filter;
 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 org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -44,59 +42,59 @@ import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
 /**
  * The testcases are only for checking the process of exporting provider using 
injvm protocol.
  */
-public class SingleRegistryCenterInjvmIntegrationTest implements 
IntegrationTest {
+public class MultipleRegistryCenterInjvmIntegrationTest implements 
IntegrationTest {
 
-    private static final Logger logger = 
LoggerFactory.getLogger(SingleRegistryCenterInjvmIntegrationTest.class);
+    private static final Logger logger = 
LoggerFactory.getLogger(MultipleRegistryCenterInjvmIntegrationTest.class);
 
     /**
      * Define the provider application name.
      */
-    private static String PROVIDER_APPLICATION_NAME = 
"single-registry-center-provider-for-injvm-protocol";
+    private static String PROVIDER_APPLICATION_NAME = 
"multiple-registry-center-provider-for-injvm-protocol";
 
     /**
      * The name for getting the specified instance, which is loaded using SPI.
      */
-    private static String SPI_NAME = "singleConfigCenterInjvm";
+    private static String SPI_NAME = "multipleConfigCenterInjvm";
+
     /**
      * Define the {@link ServiceConfig} instance.
      */
-    private ServiceConfig<SingleRegistryCenterInjvmService> serviceConfig;
+    private ServiceConfig<MultipleRegistryCenterInjvmService> serviceConfig;
 
     /**
      * The listener to record exported services
      */
-    private InjvmServiceListener serviceListener;
+    private MultipleRegistryCenterInjvmServiceListener serviceListener;
 
     /**
      * The listener to record exported exporters.
      */
-    private InjvmExporterListener exporterListener;
+    private MultipleRegistryCenterInjvmExporterListener exporterListener;
 
     /**
      * The filter for checking filter chain.
      */
-    private InjvmFilter filter;
+    private MultipleRegistryCenterInjvmFilter filter;
 
     @BeforeEach
     public void setUp() throws Exception {
         logger.info(getClass().getSimpleName() + " testcase is beginning...");
         DubboBootstrap.reset();
-        //start zookeeper only once
-        logger.info(SingleZooKeeperServer.getZookeeperServerName() + " is 
beginning to start...");
-        SingleZooKeeperServer.start();
-        logger.info(SingleZooKeeperServer.getZookeeperServerName() + " has 
started.");
+        //start all zookeeper services only once
+        MultipleZooKeeperServer.start();
 
         // initialize service config
-        serviceConfig = new ServiceConfig<SingleRegistryCenterInjvmService>();
-        serviceConfig.setInterface(SingleRegistryCenterInjvmService.class);
-        serviceConfig.setRef(new SingleRegistryCenterInjvmServiceImpl());
+        serviceConfig = new ServiceConfig<>();
+        serviceConfig.setInterface(MultipleRegistryCenterInjvmService.class);
+        serviceConfig.setRef(new MultipleRegistryCenterInjvmServiceImpl());
         serviceConfig.setAsync(false);
         serviceConfig.setScope(SCOPE_LOCAL);
 
         // initailize bootstrap
         DubboBootstrap.getInstance()
             .application(new ApplicationConfig(PROVIDER_APPLICATION_NAME))
-            .registry(new RegistryConfig("N/A"))
+            .registry(new RegistryConfig("zookeeper://127.0.0.1:" + 
MultipleZooKeeperServer.getPortOne()))
+            .registry(new RegistryConfig("zookeeper://127.0.0.1:" + 
MultipleZooKeeperServer.getPortTwo()))
             .protocol(new ProtocolConfig("injvm"))
             .service(serviceConfig);
     }
@@ -113,9 +111,9 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
      */
     private void beforeExport() {
         // ---------------initialize--------------- //
-        serviceListener = (InjvmServiceListener) 
ExtensionLoader.getExtensionLoader(ServiceListener.class).getExtension(SPI_NAME);
-        exporterListener = (InjvmExporterListener) 
ExtensionLoader.getExtensionLoader(ExporterListener.class).getExtension(SPI_NAME);
-        filter = (InjvmFilter) 
ExtensionLoader.getExtensionLoader(Filter.class).getExtension(SPI_NAME);
+        serviceListener = (MultipleRegistryCenterInjvmServiceListener) 
ExtensionLoader.getExtensionLoader(ServiceListener.class).getExtension(SPI_NAME);
+        exporterListener = (MultipleRegistryCenterInjvmExporterListener) 
ExtensionLoader.getExtensionLoader(ExporterListener.class).getExtension(SPI_NAME);
+        filter = (MultipleRegistryCenterInjvmFilter) 
ExtensionLoader.getExtensionLoader(Filter.class).getExtension(SPI_NAME);
 
         // ---------------checkpoints--------------- //
         // There is nothing in ServiceListener
@@ -129,7 +127,6 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
     /**
      * {@inheritDoc}
      */
-    @Test
     @Override
     public void integrate() {
         beforeExport();
@@ -139,7 +136,7 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
         referenceConfig.setInterface(SingleRegistryCenterInjvmService.class);
         referenceConfig.setBootstrap(DubboBootstrap.getInstance());
         referenceConfig.setScope(SCOPE_LOCAL);
-        referenceConfig.get().hello("Dubbo");
+        referenceConfig.get().hello("Dubbo in multiple registry center");
         afterInvoke();
     }
 
@@ -147,41 +144,42 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
      * There are some checkpoints need to check after exported as follow:
      * <ul>
      *     <li>The exported service is only one or not</li>
-     *     <li>The exported service is SingleRegistryCenterInjvmService or 
not</li>
-     *     <li>The SingleRegistryCenterInjvmService is exported or not</li>
+     *     <li>The exported service is MultipleRegistryCenterInjvmService or 
not</li>
+     *     <li>The MultipleRegistryCenterInjvmService is exported or not</li>
      *     <li>The exported exporter is only one or not</li>
-     *     <li>The exported exporter contains InjvmFilter or not</li>
+     *     <li>The exported exporter contains 
MultipleRegistryCenterInjvmFilter or not</li>
      * </ul>
      */
     private void afterExport() {
         // The exported service is only one
         
Assertions.assertEquals(serviceListener.getExportedServices().size(),1);
-        // The exported service is SingleRegistryCenterInjvmService
+        // The exported service is MultipleRegistryCenterInjvmService
         
Assertions.assertEquals(serviceListener.getExportedServices().get(0).getInterfaceClass(),
-            SingleRegistryCenterInjvmService.class);
-        // The SingleRegistryCenterInjvmService is exported
+            MultipleRegistryCenterInjvmService.class);
+        // The MultipleRegistryCenterInjvmService is exported
         
Assertions.assertTrue(serviceListener.getExportedServices().get(0).isExported());
         // The exported exporter is only one
         
Assertions.assertEquals(exporterListener.getExportedExporters().size(),1);
-        // The exported exporter contains InjvmFilter
+        // The exported exporter contains MultipleRegistryCenterInjvmFilter
         Assertions.assertTrue(exporterListener.getFilters().contains(filter));
     }
 
     /**
      * There are some checkpoints need to check after invoked as follow:
      * <ul>
-     *     <li>The InjvmFilter has called or not</li>
-     *     <li>The InjvmFilter exists error after invoked</li>
-     *     <li>The InjvmFilter's response is right or not</li>
+     *     <li>The MultipleRegistryCenterInjvmFilter has called or not</li>
+     *     <li>The MultipleRegistryCenterInjvmFilter exists error after 
invoked</li>
+     *     <li>The MultipleRegistryCenterInjvmFilter's response is right or 
not</li>
      * </ul>
      */
     private void afterInvoke(){
-        // The InjvmFilter has called
+        // The MultipleRegistryCenterInjvmFilter has called
         Assertions.assertTrue(filter.hasCalled());
-        // The InjvmFilter doesn't exist error
+        // The MultipleRegistryCenterInjvmFilter doesn't exist error
         Assertions.assertFalse(filter.hasError());
-        // Check the InjvmFilter's response
-        Assertions.assertEquals("Hello Dubbo",filter.getResponse());
+        // Check the MultipleRegistryCenterInjvmFilter's response
+        Assertions.assertEquals("Hello Dubbo in multiple registry center",
+            filter.getResponse());
     }
 
     @AfterEach
@@ -194,8 +192,6 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
         serviceListener = null;
         logger.info(getClass().getSimpleName() + " testcase is ending...");
         // destroy zookeeper only once
-        logger.info(SingleZooKeeperServer.getZookeeperServerName() + " is 
beginning to shutdown...");
-        SingleZooKeeperServer.shutdown();
-        logger.info(SingleZooKeeperServer.getZookeeperServerName() + " has 
shutdown.");
+        MultipleZooKeeperServer.shutdown();
     }
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmService.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmService.java
new file mode 100644
index 0000000..fba0451
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmService.java
@@ -0,0 +1,26 @@
+/*
+ * 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.integration.multiple.injvm;
+/**
+ * This interface is used to check if the exported injvm protocol works well 
or not.
+ */
+public interface MultipleRegistryCenterInjvmService {
+    /**
+     * The simple method for testing.
+     */
+    String hello(String name);
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
new file mode 100644
index 0000000..f04a5ea
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceImpl.java
@@ -0,0 +1,30 @@
+/*
+ * 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.integration.multiple.injvm;
+
+/**
+ * The simple implementation for {@link MultipleRegistryCenterInjvmService}
+ */
+public class MultipleRegistryCenterInjvmServiceImpl implements 
MultipleRegistryCenterInjvmService {
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String hello(String name) {
+        return null;
+    }
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceListener.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceListener.java
new file mode 100644
index 0000000..766fa18
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/injvm/MultipleRegistryCenterInjvmServiceListener.java
@@ -0,0 +1,34 @@
+/*
+ * 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.integration.multiple.injvm;
+
+import org.apache.dubbo.config.ServiceListener;
+import org.apache.dubbo.integration.AbstractRegistryCenterServiceListener;
+
+/**
+ * This implementation of {@link ServiceListener} is to record exported 
services with injvm protocol in multiple registry center.
+ */
+public class MultipleRegistryCenterInjvmServiceListener extends 
AbstractRegistryCenterServiceListener {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Class<?> getInterface() {
+        return MultipleRegistryCenterInjvmService.class;
+    }
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/package-info.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/package-info.java
new file mode 100644
index 0000000..c186c7d
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+/**
+ * There are two scenario in integration testcases.<p>
+ * The one is single registry center, the other is multiple registry 
centers.<p>
+ * The purpose of all of testcases in this package is to test for multiple 
registry center.
+ */
+package org.apache.dubbo.integration.multiple;
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterDubboProtocolIntegrationTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterDubboProtocolIntegrationTest.java
index 079b040..fa62302 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterDubboProtocolIntegrationTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterDubboProtocolIntegrationTest.java
@@ -27,9 +27,7 @@ import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.ServiceListener;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.integration.IntegrationTest;
-import org.apache.dubbo.integration.single.listener.ExportedServiceListener;
 import org.apache.dubbo.metadata.MetadataInfo;
-import org.apache.dubbo.metadata.MetadataService;
 import org.apache.dubbo.metadata.WritableMetadataService;
 import org.apache.dubbo.registry.ListenerRegistryWrapper;
 import org.apache.dubbo.registry.Registry;
@@ -96,9 +94,9 @@ public class SingleRegistryCenterDubboProtocolIntegrationTest 
implements Integra
     private SingleRegistryCenterIntegrationService 
singleRegistryCenterIntegrationService;
 
     /**
-     * Define the {@link ExportedServiceListener} instance to obtain the 
exported services.
+     * Define the {@link SingleRegistryCenterExportedServiceListener} instance 
to obtain the exported services.
      */
-    private ExportedServiceListener exportedServiceListener;
+    private SingleRegistryCenterExportedServiceListener 
singleRegistryCenterExportedServiceListener;
 
     @BeforeEach
     public void setUp() throws Exception {
@@ -162,7 +160,7 @@ public class 
SingleRegistryCenterDubboProtocolIntegrationTest implements Integra
         // DubboBootstrap is shutdown or not
         Assertions.assertFalse(DubboBootstrap.getInstance().isShutdown());
         // The ServiceListener is loaded by SPI or not
-        Assertions.assertNull(exportedServiceListener);
+        Assertions.assertNull(singleRegistryCenterExportedServiceListener);
     }
 
     /**
@@ -263,26 +261,17 @@ public class 
SingleRegistryCenterDubboProtocolIntegrationTest implements Integra
         // The matchKey of MetadataInfo's service is right or not
         Assertions.assertEquals(serviceInfo.getMatchKey(), key);
         // The exported services are right or not
-        // 1. The exported service must contain 
SingleRegistryCenterIntegrationService and MetadataService
+        // 1. The exported service must contain 
SingleRegistryCenterIntegrationService
         // 2. The exported service's interface must be 
SingleRegistryCenterIntegrationService.class
-        // 3. All exported service must be exported
-        exportedServiceListener = (ExportedServiceListener) 
ExtensionLoader.getExtensionLoader(ServiceListener.class).getExtension("exported");
-        Assertions.assertNotNull(exportedServiceListener);
-        
Assertions.assertEquals(exportedServiceListener.getExportedServices().size(), 
2);
-        ServiceConfig singleRegistryCenterServiceConfig = null;
-        ServiceConfig metadataServiceServiceConfig = null;
-        for (ServiceConfig exportedServiceConfig: 
exportedServiceListener.getExportedServices()) {
-            if(exportedServiceConfig.getInterfaceClass() == 
SingleRegistryCenterIntegrationService.class){
-                singleRegistryCenterServiceConfig = exportedServiceConfig;
-            }
-            if(exportedServiceConfig.getInterfaceClass() == 
MetadataService.class){
-                metadataServiceServiceConfig = exportedServiceConfig;
-            }
-        }
+        // 3. All exported services must be exported
+        singleRegistryCenterExportedServiceListener = 
(SingleRegistryCenterExportedServiceListener) 
ExtensionLoader.getExtensionLoader(ServiceListener.class).getExtension("exported");
+        Assertions.assertNotNull(singleRegistryCenterExportedServiceListener);
+        
Assertions.assertEquals(singleRegistryCenterExportedServiceListener.getExportedServices().size(),
 1);
+        Assertions.assertEquals(SingleRegistryCenterIntegrationService.class,
+            
singleRegistryCenterExportedServiceListener.getExportedServices().get(0).getInterfaceClass());
+        ServiceConfig singleRegistryCenterServiceConfig = 
singleRegistryCenterExportedServiceListener.getExportedServices().get(0);
         Assertions.assertNotNull(singleRegistryCenterServiceConfig);
-        Assertions.assertNotNull(metadataServiceServiceConfig);
         Assertions.assertTrue(singleRegistryCenterServiceConfig.isExported());
-        Assertions.assertTrue(metadataServiceServiceConfig.isExported());
     }
 
     /**
@@ -395,8 +384,8 @@ public class 
SingleRegistryCenterDubboProtocolIntegrationTest implements Integra
         serviceConfig = null;
         referenceConfig = null;
         // The exported service has been unexported
-        
Assertions.assertTrue(exportedServiceListener.getExportedServices().isEmpty());
-        exportedServiceListener = null;
+        
Assertions.assertTrue(singleRegistryCenterExportedServiceListener.getExportedServices().isEmpty());
+        singleRegistryCenterExportedServiceListener = null;
         logger.info(getClass().getSimpleName() + " testcase is ending...");
         // destroy zookeeper only once
         logger.info(SingleZooKeeperServer.getZookeeperServerName() + " is 
beginning to shutdown...");
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterExportedServiceListener.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterExportedServiceListener.java
new file mode 100644
index 0000000..37a733a
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterExportedServiceListener.java
@@ -0,0 +1,34 @@
+/*
+ * 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.integration.single;
+
+import org.apache.dubbo.config.ServiceListener;
+import org.apache.dubbo.integration.AbstractRegistryCenterServiceListener;
+
+/**
+ * This implementation of {@link ServiceListener} is to record exported 
services in single registry center.
+ */
+public class SingleRegistryCenterExportedServiceListener extends 
AbstractRegistryCenterServiceListener {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Class<?> getInterface() {
+        return SingleRegistryCenterIntegrationService.class;
+    }
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmExporterListener.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmExporterListener.java
new file mode 100644
index 0000000..4edec5f
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmExporterListener.java
@@ -0,0 +1,33 @@
+/*
+ * 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.integration.single.injvm;
+
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.integration.AbstractRegistryCenterExporterListener;
+
+@Activate(group = CommonConstants.PROVIDER, order = 1000)
+public class SingleRegistryCenterInjvmExporterListener extends 
AbstractRegistryCenterExporterListener {
+
+    /**
+     * Returns the interface of exported service.
+     */
+    @Override
+    protected Class<?> getInterface() {
+        return SingleRegistryCenterInjvmService.class;
+    }
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/InjvmFilter.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmFilter.java
similarity index 96%
rename from 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/InjvmFilter.java
rename to 
dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmFilter.java
index cb45038..a27a7b9 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/InjvmFilter.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmFilter.java
@@ -25,7 +25,7 @@ import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.Result;
 
 @Activate(group = CommonConstants.PROVIDER, order = 10000)
-public class InjvmFilter implements Filter,Filter.Listener {
+public class SingleRegistryCenterInjvmFilter implements Filter,Filter.Listener 
{
 
     /**
      * The filter is called or not
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmIntegrationTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmIntegrationTest.java
index 052f9dd..429da7b 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmIntegrationTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmIntegrationTest.java
@@ -26,8 +26,6 @@ import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.integration.IntegrationTest;
 import org.apache.dubbo.integration.single.SingleZooKeeperServer;
-import org.apache.dubbo.integration.single.listener.InjvmExporterListener;
-import org.apache.dubbo.integration.single.listener.InjvmServiceListener;
 import org.apache.dubbo.rpc.ExporterListener;
 import org.apache.dubbo.rpc.Filter;
 import org.junit.jupiter.api.AfterEach;
@@ -65,17 +63,17 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
     /**
      * The listener to record exported services
      */
-    private InjvmServiceListener serviceListener;
+    private SingleRegistryCenterInjvmServiceListener serviceListener;
 
     /**
      * The listener to record exported exporters.
      */
-    private InjvmExporterListener exporterListener;
+    private SingleRegistryCenterInjvmExporterListener exporterListener;
 
     /**
      * The filter for checking filter chain.
      */
-    private InjvmFilter filter;
+    private SingleRegistryCenterInjvmFilter filter;
 
     @BeforeEach
     public void setUp() throws Exception {
@@ -87,7 +85,7 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
         logger.info(SingleZooKeeperServer.getZookeeperServerName() + " has 
started.");
 
         // initialize service config
-        serviceConfig = new ServiceConfig<SingleRegistryCenterInjvmService>();
+        serviceConfig = new ServiceConfig<>();
         serviceConfig.setInterface(SingleRegistryCenterInjvmService.class);
         serviceConfig.setRef(new SingleRegistryCenterInjvmServiceImpl());
         serviceConfig.setAsync(false);
@@ -96,7 +94,7 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
         // initailize bootstrap
         DubboBootstrap.getInstance()
             .application(new ApplicationConfig(PROVIDER_APPLICATION_NAME))
-            .registry(new RegistryConfig("N/A"))
+            .registry(new RegistryConfig("zookeeper://127.0.0.1:" + 
SingleZooKeeperServer.getPort()))
             .protocol(new ProtocolConfig("injvm"))
             .service(serviceConfig);
     }
@@ -113,9 +111,9 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
      */
     private void beforeExport() {
         // ---------------initialize--------------- //
-        serviceListener = (InjvmServiceListener) 
ExtensionLoader.getExtensionLoader(ServiceListener.class).getExtension(SPI_NAME);
-        exporterListener = (InjvmExporterListener) 
ExtensionLoader.getExtensionLoader(ExporterListener.class).getExtension(SPI_NAME);
-        filter = (InjvmFilter) 
ExtensionLoader.getExtensionLoader(Filter.class).getExtension(SPI_NAME);
+        serviceListener = (SingleRegistryCenterInjvmServiceListener) 
ExtensionLoader.getExtensionLoader(ServiceListener.class).getExtension(SPI_NAME);
+        exporterListener = (SingleRegistryCenterInjvmExporterListener) 
ExtensionLoader.getExtensionLoader(ExporterListener.class).getExtension(SPI_NAME);
+        filter = (SingleRegistryCenterInjvmFilter) 
ExtensionLoader.getExtensionLoader(Filter.class).getExtension(SPI_NAME);
 
         // ---------------checkpoints--------------- //
         // There is nothing in ServiceListener
@@ -150,7 +148,7 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
      *     <li>The exported service is SingleRegistryCenterInjvmService or 
not</li>
      *     <li>The SingleRegistryCenterInjvmService is exported or not</li>
      *     <li>The exported exporter is only one or not</li>
-     *     <li>The exported exporter contains InjvmFilter or not</li>
+     *     <li>The exported exporter contains SingleRegistryCenterInjvmFilter 
or not</li>
      * </ul>
      */
     private void afterExport() {
@@ -163,24 +161,24 @@ public class SingleRegistryCenterInjvmIntegrationTest 
implements IntegrationTest
         
Assertions.assertTrue(serviceListener.getExportedServices().get(0).isExported());
         // The exported exporter is only one
         
Assertions.assertEquals(exporterListener.getExportedExporters().size(),1);
-        // The exported exporter contains InjvmFilter
+        // The exported exporter contains SingleRegistryCenterInjvmFilter
         Assertions.assertTrue(exporterListener.getFilters().contains(filter));
     }
 
     /**
      * There are some checkpoints need to check after invoked as follow:
      * <ul>
-     *     <li>The InjvmFilter has called or not</li>
-     *     <li>The InjvmFilter exists error after invoked</li>
-     *     <li>The InjvmFilter's response is right or not</li>
+     *     <li>The SingleRegistryCenterInjvmFilter has called or not</li>
+     *     <li>The SingleRegistryCenterInjvmFilter exists error after 
invoked</li>
+     *     <li>The SingleRegistryCenterInjvmFilter's response is right or 
not</li>
      * </ul>
      */
     private void afterInvoke(){
-        // The InjvmFilter has called
+        // The SingleRegistryCenterInjvmFilter has called
         Assertions.assertTrue(filter.hasCalled());
-        // The InjvmFilter doesn't exist error
+        // The SingleRegistryCenterInjvmFilter doesn't exist error
         Assertions.assertFalse(filter.hasError());
-        // Check the InjvmFilter's response
+        // Check the SingleRegistryCenterInjvmFilter's response
         Assertions.assertEquals("Hello Dubbo",filter.getResponse());
     }
 
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmServiceListener.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmServiceListener.java
new file mode 100644
index 0000000..b1ff898
--- /dev/null
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/injvm/SingleRegistryCenterInjvmServiceListener.java
@@ -0,0 +1,34 @@
+/*
+ * 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.integration.single.injvm;
+
+import org.apache.dubbo.config.ServiceListener;
+import org.apache.dubbo.integration.AbstractRegistryCenterServiceListener;
+
+/**
+ * This implementation of {@link ServiceListener} is to record exported 
services with injvm protocol in single registry center.
+ */
+public class SingleRegistryCenterInjvmServiceListener extends 
AbstractRegistryCenterServiceListener {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Class<?> getInterface() {
+        return SingleRegistryCenterInjvmService.class;
+    }
+}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/listener/ExportedServiceListener.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/listener/ExportedServiceListener.java
deleted file mode 100644
index a8bf95b..0000000
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/listener/ExportedServiceListener.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.integration.single.listener;
-
-import org.apache.dubbo.config.ServiceConfig;
-import org.apache.dubbo.config.ServiceListener;
-import 
org.apache.dubbo.integration.single.SingleRegistryCenterIntegrationService;
-import org.apache.dubbo.metadata.MetadataService;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * This implementation of {@link ServiceListener} is to record exported 
services
- */
-public class ExportedServiceListener implements ServiceListener {
-
-    private List<ServiceConfig> exportedServices = new ArrayList<>(2);
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void exported(ServiceConfig sc) {
-        //All exported services will be added
-        if(sc.getInterfaceClass()== MetadataService.class ||
-        sc.getInterfaceClass() == 
SingleRegistryCenterIntegrationService.class){
-            exportedServices.add(sc);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void unexported(ServiceConfig sc) {
-        //remove the exported services.
-        exportedServices.remove(sc);
-    }
-
-    /**
-     * Return all exported services.
-     */
-    public List<ServiceConfig> getExportedServices(){
-        return Collections.unmodifiableList(exportedServices);
-    }
-}
diff --git 
a/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.config.ServiceListener
 
b/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.config.ServiceListener
index aac2dca..b7e2dab 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.config.ServiceListener
+++ 
b/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.config.ServiceListener
@@ -1,3 +1,4 @@
 mock=org.apache.dubbo.config.mock.MockServiceListener
-exported=org.apache.dubbo.integration.single.listener.ExportedServiceListener
-singleConfigCenterInjvm=org.apache.dubbo.integration.single.listener.InjvmServiceListener
+exported=org.apache.dubbo.integration.single.SingleRegistryCenterExportedServiceListener
+singleConfigCenterInjvm=org.apache.dubbo.integration.single.injvm.SingleRegistryCenterInjvmServiceListener
+multipleConfigCenterInjvm=org.apache.dubbo.integration.multiple.injvm.MultipleRegistryCenterInjvmServiceListener
diff --git 
a/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.rpc.ExporterListener
 
b/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.rpc.ExporterListener
index 1b9f72d..51f85f7 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.rpc.ExporterListener
+++ 
b/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.rpc.ExporterListener
@@ -16,4 +16,5 @@
 #
 
 mockexporterlistener=org.apache.dubbo.config.mock.MockExporterListener
-singleConfigCenterInjvm=org.apache.dubbo.integration.single.listener.InjvmExporterListener
+singleConfigCenterInjvm=org.apache.dubbo.integration.single.injvm.SingleRegistryCenterInjvmExporterListener
+multipleConfigCenterInjvm=org.apache.dubbo.integration.multiple.injvm.MultipleRegistryCenterInjvmExporterListener
diff --git 
a/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.rpc.Filter
 
b/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.rpc.Filter
index ea35520..9bf8f99 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.rpc.Filter
+++ 
b/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.rpc.Filter
@@ -1,2 +1,3 @@
 mockfilter=org.apache.dubbo.config.mock.MockFilter
-singleConfigCenterInjvm=org.apache.dubbo.integration.single.injvm.InjvmFilter
+singleConfigCenterInjvm=org.apache.dubbo.integration.single.injvm.SingleRegistryCenterInjvmFilter
+multipleConfigCenterInjvm=org.apache.dubbo.integration.multiple.injvm.MultipleRegistryCenterInjvmFilter

Reply via email to