You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2021/06/20 12:01:33 UTC

[dubbo-spi-extensions] branch master updated: Refactor modules (#33)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new b0f48a2  Refactor modules (#33)
b0f48a2 is described below

commit b0f48a201ba0b4cc9a0a66de5a8cd2aedca11a88
Author: Albumen Kevin <jh...@gmail.com>
AuthorDate: Sun Jun 20 20:01:24 2021 +0800

    Refactor modules (#33)
    
    * refactor parent pom
    
    * remove dubbo-test module
    
    * add broadcast 1
    
    * remove old modules
    
    * add modules
    
    * update Github Actions
    
    * remove timeout key
    
    * add asf license header
    
    * fix checkstyle
    
    * add tools build
    
    * change ref
---
 .asf.yaml                                          |   21 +-
 ...rg.apache.dubbo.remoting.Codec => .editorconfig |   17 +-
 ...remoting.telnet.TelnetHandler => .gitattributes |    6 +-
 .github/workflows/ci.yml                           |   65 +-
 LICENSE                                            |    2 +-
 codestyle/checkstyle-suppressions.xml              |    4 +-
 codestyle/checkstyle.xml                           |    4 +
 codestyle/checkstyle_unix.xml                      |   10 +
 codestyle/dubbo_codestyle_for_idea.xml             |    2 +-
 dubbo-all/pom.xml                                  | 1057 ----
 dubbo-api-docs/dubbo-api-docs-annotations/pom.xml  |    2 +-
 dubbo-api-docs/dubbo-api-docs-core/pom.xml         |    4 +-
 .../core/DubboApiDocsAnnotationScanner.java        |   51 +-
 .../apache/dubbo/apidocs/utils/ClassTypeUtil.java  |  142 +-
 .../dubbo-api-docs-examples/examples-api/pom.xml   |    4 +-
 .../examples-provider-sca/pom.xml                  |    7 +-
 .../src/main/resources/dubbo.properties            |    2 +-
 .../examples-provider/pom.xml                      |   12 +-
 dubbo-api-docs/dubbo-api-docs-examples/pom.xml     |    4 +-
 dubbo-api-docs/pom.xml                             |  169 +-
 .../dubbo-cluster-broadcast-1}/pom.xml             |   30 +-
 .../rpc/cluster/support/BroadcastCluster1.java     |   19 +-
 .../cluster/support/BroadcastCluster1Invoker.java  |  180 +
 .../dubbo/rpc/cluster/support/BroadcastResult.java |   99 +
 .../internal/org.apache.dubbo.rpc.cluster.Cluster  |    1 +
 .../pom.xml                                        |   17 +-
 .../log4j.xml => dubbo-common-extensions/pom.xml   |   28 +-
 .../pom.xml                                        |   27 +-
 .../dubbo-apache-release/pom.xml                   |   87 +
 .../src/assembly/bin-release.xml                   |   35 +-
 .../src/assembly/source-release.xml                |   57 +
 dubbo-extensions-distribution/dubbo-bom/pom.xml    |  146 +
 .../pom.xml                                        |   53 +-
 .../pom.xml                                        |   18 +-
 .../pom.xml                                        |   18 +-
 .../pom.xml                                        |   18 +-
 .../pom.xml                                        |   17 +-
 .../log4j.xml => dubbo-rpc-extensions/pom.xml      |   27 +-
 .../pom.xml                                        |   17 +-
 .../dubbo-configcenter-consul/pom.xml              |   47 -
 .../consul/ConsulDynamicConfiguration.java         |  218 -
 .../consul/ConsulDynamicConfigurationFactory.java  |   32 -
 ...config.configcenter.DynamicConfigurationFactory |    1 -
 .../consul/ConsulDynamicConfigurationTest.java     |  109 -
 .../dubbo-configcenter-etcd/pom.xml                |   74 -
 .../support/etcd/EtcdDynamicConfiguration.java     |  197 -
 .../etcd/EtcdDynamicConfigurationFactory.java      |   33 -
 ...config.configcenter.DynamicConfigurationFactory |    1 -
 .../support/etcd/EtcdDynamicConfigurationTest.java |  154 -
 dubbo-spi-configcenter/pom.xml                     |   36 -
 .../dubbo/container/log4j/Log4jContainer.java      |  103 -
 .../internal/org.apache.dubbo.container.Container  |    1 -
 .../dubbo/container/log4j/Log4jContainerTest.java  |   36 -
 .../dubbo-container-logback/pom.xml                |   42 -
 .../dubbo/container/logback/LogbackContainer.java  |  108 -
 .../internal/org.apache.dubbo.container.Container  |    1 -
 .../container/logback/LogbackContainerTest.java    |   47 -
 .../dubbo-metadata-report-consul/pom.xml           |   41 -
 .../store/consul/ConsulMetadataReport.java         |  135 -
 .../store/consul/ConsulMetadataReportFactory.java  |   32 -
 ...che.dubbo.metadata.report.MetadataReportFactory |    1 -
 .../dubbo-metadata-report-etcd/pom.xml             |   69 -
 .../metadata/store/etcd/EtcdMetadataReport.java    |  150 -
 .../store/etcd/EtcdMetadataReportFactory.java      |   50 -
 ...che.dubbo.metadata.report.MetadataReportFactory |    1 -
 .../store/etcd/EtcdMetadata4TstService.java        |   28 -
 .../store/etcd/EtcdMetadataReportTest.java         |  259 -
 dubbo-spi-registry/dubbo-registry-consul/pom.xml   |   62 -
 .../registry/consul/AbstractConsulRegistry.java    |   39 -
 .../dubbo/registry/consul/ConsulRegistry.java      |  360 --
 .../registry/consul/ConsulRegistryFactory.java     |   32 -
 .../registry/consul/ConsulServiceDiscovery.java    |  397 --
 .../org.apache.dubbo.registry.RegistryFactory      |    1 -
 ...g.apache.dubbo.registry.client.ServiceDiscovery |    1 -
 .../dubbo/registry/consul/ConsulRegistryTest.java  |  135 -
 .../consul/ConsulServiceDiscoveryTest.java         |  108 -
 dubbo-spi-registry/dubbo-registry-default/pom.xml  |   68 -
 .../apache/dubbo/registry/dubbo/DubboRegistry.java |  161 -
 .../dubbo/registry/dubbo/DubboRegistryFactory.java |  118 -
 .../org.apache.dubbo.registry.RegistryFactory      |    1 -
 .../registry/dubbo/AbstractRegistryService.java    |  237 -
 .../apache/dubbo/registry/dubbo/DemoService.java   |   27 -
 .../dubbo/registry/dubbo/DemoServiceImpl.java      |   32 -
 .../dubbo/registry/dubbo/DubboRegistryTest.java    |  155 -
 .../apache/dubbo/registry/dubbo/MockChannel.java   |  141 -
 .../apache/dubbo/registry/dubbo/MockedClient.java  |  298 --
 .../registry/dubbo/RegistryDirectoryTest.java      | 1143 -----
 .../dubbo/registry/dubbo/RegistryProtocolTest.java |  233 -
 .../registry/dubbo/RegistryStatusCheckerTest.java  |   69 -
 .../registry/dubbo/SimpleRegistryExporter.java     |   87 -
 .../registry/dubbo/SimpleRegistryService.java      |  146 -
 .../src/test/resources/log4j.xml                   |   38 -
 dubbo-spi-registry/dubbo-registry-etcd3/pom.xml    |   51 -
 .../apache/dubbo/registry/etcd/EtcdRegistry.java   |  359 --
 .../dubbo/registry/etcd/EtcdRegistryFactory.java   |   36 -
 .../dubbo/registry/etcd/EtcdServiceDiscovery.java  |  211 -
 .../org.apache.dubbo.registry.RegistryFactory      |    1 -
 ...g.apache.dubbo.registry.client.ServiceDiscovery |    1 -
 .../dubbo/registry/etcd/EtcdRegistryTest.java      |  327 --
 .../registry/etcd/EtcdServiceDiscoveryTest.java    |  124 -
 dubbo-spi-registry/dubbo-registry-eureka/pom.xml   |   85 -
 .../eureka/ConfigurableEurekaInstanceConfig.java   |  369 --
 .../registry/eureka/EurekaServiceDiscovery.java    |  282 --
 .../apache/dubbo/registry/eureka/package-info.java |   22 -
 ...g.apache.dubbo.registry.client.ServiceDiscovery |    1 -
 .../eureka/EurekaServiceDiscoveryTest.java         |   67 -
 dubbo-spi-registry/dubbo-registry-redis/pom.xml    |   52 -
 .../apache/dubbo/registry/redis/RedisRegistry.java |  661 ---
 .../dubbo/registry/redis/RedisRegistryFactory.java |   34 -
 .../org.apache.dubbo.registry.RegistryFactory      |    1 -
 .../dubbo/registry/redis/RedisRegistryTest.java    |  130 -
 dubbo-spi-registry/dubbo-registry-sofa/pom.xml     |  133 -
 .../apache/dubbo/registry/sofa/SofaRegistry.java   |  300 --
 .../dubbo/registry/sofa/SofaRegistryConstants.java |   43 -
 .../dubbo/registry/sofa/SofaRegistryFactory.java   |   41 -
 .../org.apache.dubbo.registry.RegistryFactory      |    1 -
 .../apache/dubbo/registry/sofa/HelloService.java   |   24 -
 .../dubbo/registry/sofa/HelloServiceImpl.java      |   44 -
 .../src/test/resources/log4j.properties            |    7 -
 dubbo-spi-registry/pom.xml                         |   39 -
 dubbo-spi-remoting/dubbo-remoting-etcd3/pom.xml    |  106 -
 .../dubbo/remoting/etcd/AbstractRetryPolicy.java   |   45 -
 .../apache/dubbo/remoting/etcd/ChildListener.java  |   25 -
 .../org/apache/dubbo/remoting/etcd/Constants.java  |   55 -
 .../org/apache/dubbo/remoting/etcd/EtcdClient.java |  191 -
 .../dubbo/remoting/etcd/EtcdTransporter.java       |   47 -
 .../apache/dubbo/remoting/etcd/RetryPolicy.java    |   31 -
 .../apache/dubbo/remoting/etcd/StateListener.java  |   27 -
 .../etcd/jetcd/ConnectionStateListener.java        |   31 -
 .../dubbo/remoting/etcd/jetcd/JEtcdClient.java     |  473 --
 .../remoting/etcd/jetcd/JEtcdClientWrapper.java    |  754 ---
 .../remoting/etcd/jetcd/JEtcdTransporter.java      |   30 -
 .../dubbo/remoting/etcd/jetcd/RetryLoops.java      |   99 -
 .../dubbo/remoting/etcd/jetcd/RetryNTimes.java     |   36 -
 .../dubbo/remoting/etcd/option/OptionUtil.java     |   78 -
 .../remoting/etcd/support/AbstractEtcdClient.java  |  194 -
 .../org.apache.dubbo.remoting.etcd.EtcdTransporter |    1 -
 .../dubbo/remoting/etcd/jetcd/JEtcdClientTest.java |  427 --
 .../etcd/jetcd/JEtcdClientWrapperTest.java         |  187 -
 .../dubbo/remoting/etcd/jetcd/LeaseTest.java       |  154 -
 dubbo-spi-remoting/dubbo-remoting-grizzly/pom.xml  |   42 -
 .../remoting/transport/grizzly/GrizzlyChannel.java |  198 -
 .../remoting/transport/grizzly/GrizzlyClient.java  |  112 -
 .../transport/grizzly/GrizzlyCodecAdapter.java     |  145 -
 .../remoting/transport/grizzly/GrizzlyHandler.java |  118 -
 .../remoting/transport/grizzly/GrizzlyServer.java  |  127 -
 .../transport/grizzly/GrizzlyTransporter.java      |   43 -
 .../internal/org.apache.dubbo.remoting.Transporter |    1 -
 .../transport/grizzly/GrizzlyTransporterTest.java  |   41 -
 dubbo-spi-remoting/dubbo-remoting-http/pom.xml     |   61 -
 .../org/apache/dubbo/remoting/http/HttpBinder.java |   39 -
 .../apache/dubbo/remoting/http/HttpHandler.java    |   39 -
 .../org/apache/dubbo/remoting/http/HttpServer.java |   72 -
 .../dubbo/remoting/http/jetty/JettyHttpBinder.java |   34 -
 .../dubbo/remoting/http/jetty/JettyHttpServer.java |  112 -
 .../remoting/http/servlet/BootstrapListener.java   |   37 -
 .../remoting/http/servlet/DispatcherServlet.java   |   65 -
 .../remoting/http/servlet/ServletHttpBinder.java   |   34 -
 .../remoting/http/servlet/ServletHttpServer.java   |   31 -
 .../remoting/http/servlet/ServletManager.java      |   50 -
 .../remoting/http/support/AbstractHttpServer.java  |  134 -
 .../remoting/http/tomcat/TomcatHttpBinder.java     |   31 -
 .../remoting/http/tomcat/TomcatHttpServer.java     |   93 -
 .../org.apache.dubbo.remoting.http.HttpBinder      |    3 -
 .../remoting/http/jetty/JettyHttpBinderTest.java   |   53 -
 .../remoting/http/tomcat/TomcatHttpBinderTest.java |   55 -
 dubbo-spi-remoting/dubbo-remoting-mina/pom.xml     |   52 -
 .../dubbo/remoting/transport/mina/MinaChannel.java |  191 -
 .../dubbo/remoting/transport/mina/MinaClient.java  |  174 -
 .../remoting/transport/mina/MinaCodecAdapter.java  |  167 -
 .../dubbo/remoting/transport/mina/MinaHandler.java |   95 -
 .../dubbo/remoting/transport/mina/MinaServer.java  |  112 -
 .../remoting/transport/mina/MinaTransporter.java   |   40 -
 .../internal/org.apache.dubbo.remoting.Transporter |    1 -
 .../transport/mina/ClientToServerTest.java         |   92 -
 .../remoting/transport/mina/ClientsTest.java       |   65 -
 .../org/apache/remoting/transport/mina/Hello.java  |   45 -
 .../transport/mina/MinaClientToServerTest.java     |   41 -
 .../org/apache/remoting/transport/mina/World.java  |   45 -
 .../remoting/transport/mina/WorldHandler.java      |   36 -
 dubbo-spi-remoting/dubbo-remoting-p2p/pom.xml      |   44 -
 .../com/alibaba/dubbo/remoting/p2p/Networker.java  |   22 -
 .../java/org/apache/dubbo/remoting/p2p/Group.java  |   57 -
 .../org/apache/dubbo/remoting/p2p/Networker.java   |   39 -
 .../org/apache/dubbo/remoting/p2p/Networkers.java  |   47 -
 .../java/org/apache/dubbo/remoting/p2p/Peer.java   |   36 -
 .../dubbo/remoting/p2p/exchange/ExchangeGroup.java |   36 -
 .../remoting/p2p/exchange/ExchangeNetworker.java   |   35 -
 .../remoting/p2p/exchange/ExchangeNetworkers.java  |   45 -
 .../dubbo/remoting/p2p/exchange/ExchangePeer.java  |   26 -
 .../exchange/support/AbstractExchangeGroup.java    |  128 -
 .../p2p/exchange/support/ExchangeServerPeer.java   |  137 -
 .../p2p/exchange/support/FileExchangeGroup.java    |  135 -
 .../exchange/support/FileExchangeNetworker.java    |   34 -
 .../exchange/support/MulticastExchangeGroup.java   |  108 -
 .../support/MulticastExchangeNetworker.java        |   34 -
 .../dubbo/remoting/p2p/support/AbstractGroup.java  |  119 -
 .../dubbo/remoting/p2p/support/FileGroup.java      |  133 -
 .../dubbo/remoting/p2p/support/FileNetworker.java  |   34 -
 .../dubbo/remoting/p2p/support/MulticastGroup.java |  108 -
 .../remoting/p2p/support/MulticastNetworker.java   |   34 -
 .../dubbo/remoting/p2p/support/ServerPeer.java     |  124 -
 .../org.apache.dubbo.remoting.p2p.Networker        |    2 -
 .../support/MulticastExchangeNetworkerTest.java    |   81 -
 .../remoting/p2p/support/FileNetworkerTest.java    |   83 -
 .../p2p/support/MulticastNetworkerTest.java        |   70 -
 dubbo-spi-remoting/pom.xml                         |   39 -
 dubbo-spi-rpc/dubbo-rpc-hessian/pom.xml            |   62 -
 .../dubbo/rpc/protocol/hessian/Constants.java      |   35 -
 .../hessian/DubboHessianURLConnectionFactory.java  |   41 -
 .../rpc/protocol/hessian/HessianProtocol.java      |  202 -
 .../rpc/protocol/hessian/HttpClientConnection.java |   99 -
 .../hessian/HttpClientConnectionFactory.java       |   58 -
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 -
 .../rpc/protocol/hessian/HessianProtocolTest.java  |  250 -
 .../dubbo/rpc/protocol/hessian/HessianService.java |   37 -
 .../rpc/protocol/hessian/HessianServiceImpl.java   |   75 -
 dubbo-spi-rpc/dubbo-rpc-http/pom.xml               |   61 -
 .../dubbo/rpc/protocol/http/HttpProtocol.java      |  191 -
 .../rpc/protocol/http/HttpProtocolErrorCode.java   |   29 -
 .../rpc/protocol/http/JsonRemoteInvocation.java    |   61 -
 .../rpc/protocol/http/JsonRpcProxyFactoryBean.java |   86 -
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 -
 .../dubbo/rpc/protocol/http/HttpProtocolTest.java  |   92 -
 .../dubbo/rpc/protocol/http/HttpService.java       |   27 -
 .../dubbo/rpc/protocol/http/HttpServiceImpl.java   |   58 -
 dubbo-spi-rpc/dubbo-rpc-memcached/pom.xml          |   42 -
 .../rpc/protocol/memcached/MemcachedProtocol.java  |  122 -
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 -
 .../protocol/memcached/MemcachedProtocolTest.java  |   21 -
 dubbo-spi-rpc/dubbo-rpc-native-thrift/pom.xml      |   49 -
 .../rpc/protocol/nativethrift/ThriftProtocol.java  |  189 -
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 -
 .../src/test/idls/DemoService.thrift               |   17 -
 .../src/test/idls/UserService.thrift               |    6 -
 .../rpc/protocol/nativethrift/DemoService.java     | 5141 --------------------
 .../rpc/protocol/nativethrift/DemoServiceImpl.java |   78 -
 .../protocol/nativethrift/ThriftProtocolTest.java  |   84 -
 .../rpc/protocol/nativethrift/UserService.java     |  952 ----
 .../rpc/protocol/nativethrift/UserServiceImpl.java |   24 -
 dubbo-spi-rpc/dubbo-rpc-redis/pom.xml              |   58 -
 .../dubbo/rpc/protocol/redis/RedisProtocol.java    |  187 -
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 -
 .../dubbo/rpc/protocol/redis/IDemoService.java     |   29 -
 .../rpc/protocol/redis/RedisProtocolTest.java      |  230 -
 ...org.apache.dubbo.common.serialize.Serialization |    1 -
 dubbo-spi-rpc/dubbo-rpc-rmi/pom.xml                |   42 -
 .../rpc/protocol/rmi/RmiRemoteInvocation.java      |   39 -
 .../apache/dubbo/rpc/protocol/rmi/RmiProtocol.java |  154 -
 .../rpc/protocol/rmi/RmiRemoteInvocation.java      |   64 -
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 -
 .../apache/dubbo/rpc/protocol/rmi/DemoService.java |   47 -
 .../dubbo/rpc/protocol/rmi/DemoServiceImpl.java    |   89 -
 .../dubbo/rpc/protocol/rmi/RemoteService.java      |   26 -
 .../dubbo/rpc/protocol/rmi/RemoteServiceImpl.java  |   32 -
 .../dubbo/rpc/protocol/rmi/RmiProtocolTest.java    |  227 -
 .../org/apache/dubbo/rpc/protocol/rmi/Type.java    |   21 -
 dubbo-spi-rpc/dubbo-rpc-thrift/pom.xml             |   73 -
 .../rpc/protocol/thrift/ClassNameGenerator.java    |   22 -
 .../rpc/protocol/thrift/ClassNameGenerator.java    |   31 -
 .../protocol/thrift/DubboClassNameGenerator.java   |   36 -
 .../protocol/thrift/ThriftClassNameGenerator.java  |   36 -
 .../dubbo/rpc/protocol/thrift/ThriftCodec.java     |  697 ---
 .../dubbo/rpc/protocol/thrift/ThriftConstants.java |   32 -
 .../dubbo/rpc/protocol/thrift/ThriftInvoker.java   |  171 -
 .../rpc/protocol/thrift/ThriftNativeCodec.java     |   96 -
 .../dubbo/rpc/protocol/thrift/ThriftProtocol.java  |  272 --
 .../dubbo/rpc/protocol/thrift/ThriftType.java      |   51 -
 .../dubbo/rpc/protocol/thrift/ThriftUtils.java     |  135 -
 .../protocol/thrift/ext/MultiServiceProcessor.java |  121 -
 .../rpc/protocol/thrift/io/InputStreamWrapper.java |   88 -
 .../io/RandomAccessByteArrayOutputStream.java      |  117 -
 .../internal/org.apache.dubbo.remoting.Codec2      |    1 -
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 -
 ...he.dubbo.rpc.protocol.thrift.ClassNameGenerator |    2 -
 .../src/test/java/$__ClassNameTestDubboStub.java   |  681 ---
 .../src/test/java/ClassNameTest.java               |   45 -
 .../src/test/java/ClassNameTestDubbo.java          |   29 -
 .../src/test/java/ClassNameTestThrift.java         |  767 ---
 .../apache/dubbo/rpc/gen/dubbo/$__DemoStub.java    | 4347 -----------------
 .../java/org/apache/dubbo/rpc/gen/dubbo/Demo.java  |   42 -
 .../java/org/apache/dubbo/rpc/gen/thrift/Demo.java | 4753 ------------------
 .../dubbo/rpc/protocol/thrift/AbstractTest.java    |  150 -
 .../apache/dubbo/rpc/protocol/thrift/DemoImpl.java |   56 -
 .../dubbo/rpc/protocol/thrift/DubboDemoImpl.java   |   23 -
 .../protocol/thrift/FramedTransportFactory.java    |   30 -
 .../dubbo/rpc/protocol/thrift/MockedChannel.java   |  116 -
 .../rpc/protocol/thrift/ServerExceptionTest.java   |  100 -
 .../protocol/thrift/ServiceMethodNotFoundTest.java |  146 -
 .../dubbo/rpc/protocol/thrift/ThriftCodecTest.java |  477 --
 .../dubbo/rpc/protocol/thrift/ThriftDemoImpl.java  |   22 -
 .../rpc/protocol/thrift/ThriftProtocolTest.java    |   87 -
 .../dubbo/rpc/protocol/thrift/ThriftUtilsTest.java |   88 -
 .../thrift/examples/DubboDemoConsumer.java         |   36 -
 .../thrift/examples/DubboDemoProvider.java         |   31 -
 .../src/test/resources/dubbo-demo-provider.xml     |   34 -
 .../src/test/thrift/ClassNameTestDubbo.thrift      |    3 -
 .../src/test/thrift/ClassNameTestThrift.thrift     |    3 -
 .../dubbo-rpc-thrift/src/test/thrift/Demo.thrift   |   16 -
 dubbo-spi-rpc/dubbo-rpc-webservice/pom.xml         |   76 -
 .../protocol/webservice/WebServiceProtocol.java    |  204 -
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 -
 .../dubbo/rpc/protocol/webservice/DemoService.java |   43 -
 .../rpc/protocol/webservice/DemoServiceImpl.java   |   80 -
 .../apache/dubbo/rpc/protocol/webservice/User.java |   38 -
 .../webservice/WebserviceProtocolTest.java         |   77 -
 dubbo-spi-rpc/dubbo-rpc-xml/README.md              |   88 -
 dubbo-spi-rpc/dubbo-rpc-xml/pom.xml                |   66 -
 .../xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java    |  196 -
 .../protocol/xmlrpc/XmlRpcProxyFactoryBean.java    |  142 -
 .../org.apache.dubbo.remoting.http.HttpBinder      |    1 -
 .../dubbo/internal/org.apache.dubbo.rpc.Protocol   |    1 -
 .../rpc/protocol/xmlrpc/XmlRpcProtocolTest.java    |   90 -
 .../xml/rpc/protocol/xmlrpc/XmlRpcService.java     |   25 -
 .../xml/rpc/protocol/xmlrpc/XmlRpcServiceImpl.java |   51 -
 dubbo-spi-rpc/pom.xml                              |   42 -
 .../common/serialize/avro/AvroObjectInput.java     |  118 -
 .../common/serialize/avro/AvroObjectOutput.java    |  106 -
 .../common/serialize/avro/AvroSerialization.java   |   52 -
 ...org.apache.dubbo.common.serialize.Serialization |    1 -
 .../dubbo-serialization-fastjson/pom.xml           |   43 -
 .../serialize/fastjson/FastJsonObjectInput.java    |  121 -
 .../serialize/fastjson/FastJsonObjectOutput.java   |  113 -
 .../serialize/fastjson/FastJsonSerialization.java  |   59 -
 ...org.apache.dubbo.common.serialize.Serialization |    1 -
 .../dubbo-serialization-fst/pom.xml                |   42 -
 .../dubbo/common/serialize/fst/FstFactory.java     |   53 -
 .../dubbo/common/serialize/fst/FstObjectInput.java |  117 -
 .../common/serialize/fst/FstObjectOutput.java      |  106 -
 .../common/serialize/fst/FstSerialization.java     |   58 -
 ...org.apache.dubbo.common.serialize.Serialization |    1 -
 .../dubbo-serialization-gson/pom.xml               |   42 -
 .../common/serialize/gson/GsonJsonObjectInput.java |  121 -
 .../serialize/gson/GsonJsonObjectOutput.java       |  108 -
 .../common/serialize/gson/GsonSerialization.java   |   53 -
 ...org.apache.dubbo.common.serialize.Serialization |    1 -
 .../serialize/gson/GsonJsonObjectOutputTest.java   |  143 -
 .../serialize/gson/GsonJsonSerializationTest.java  |   64 -
 .../apache/dubbo/common/serialize/gson/Image.java  |  120 -
 .../dubbo-serialization-kryo/pom.xml               |   47 -
 .../common/serialize/kryo/CompatibleKryo.java      |   54 -
 .../common/serialize/kryo/KryoObjectInput.java     |  162 -
 .../common/serialize/kryo/KryoObjectOutput.java    |  118 -
 .../common/serialize/kryo/KryoSerialization.java   |   58 -
 .../serialize/kryo/optimized/KryoObjectInput2.java |  168 -
 .../kryo/optimized/KryoObjectOutput2.java          |  122 -
 .../kryo/optimized/KryoSerialization2.java         |   57 -
 .../serialize/kryo/utils/AbstractKryoFactory.java  |  158 -
 .../common/serialize/kryo/utils/KryoUtils.java     |   44 -
 .../serialize/kryo/utils/PooledKryoFactory.java    |   40 -
 .../serialize/kryo/utils/PrototypeKryoFactory.java |   32 -
 .../serialize/kryo/utils/ReflectionUtils.java      |   33 -
 .../kryo/utils/ThreadLocalKryoFactory.java         |   39 -
 ...org.apache.dubbo.common.serialize.Serialization |    2 -
 .../dubbo-serialization-native-hession/pom.xml     |   42 -
 .../serialize/hessian/Hessian2ObjectInput.java     |   98 -
 .../serialize/hessian/Hessian2ObjectOutput.java    |   95 -
 .../serialize/hessian/Hessian2Serialization.java   |   53 -
 .../hessian/Hessian2SerializerFactory.java         |   42 -
 .../serialize/hessian/Java8SerializerFactory.java  |   88 -
 .../hessian/serializer/java8/DurationHandle.java   |   53 -
 .../hessian/serializer/java8/InstantHandle.java    |   54 -
 .../serializer/java8/Java8TimeSerializer.java      |   57 -
 .../hessian/serializer/java8/LocalDateHandle.java  |   55 -
 .../serializer/java8/LocalDateTimeHandle.java      |   55 -
 .../hessian/serializer/java8/LocalTimeHandle.java  |   57 -
 .../hessian/serializer/java8/MonthDayHandle.java   |   53 -
 .../serializer/java8/OffsetDateTimeHandle.java     |   55 -
 .../hessian/serializer/java8/OffsetTimeHandle.java |   55 -
 .../hessian/serializer/java8/PeriodHandle.java     |   56 -
 .../hessian/serializer/java8/YearHandle.java       |   52 -
 .../hessian/serializer/java8/YearMonthHandle.java  |   53 -
 .../hessian/serializer/java8/ZoneIdHandle.java     |   52 -
 .../hessian/serializer/java8/ZoneIdSerializer.java |   43 -
 .../hessian/serializer/java8/ZoneOffsetHandle.java |   51 -
 .../serializer/java8/ZonedDateTimeHandle.java      |   62 -
 ...org.apache.dubbo.common.serialize.Serialization |    1 -
 .../serialize/hessian/Java8TimeSerializerTest.java |  150 -
 .../protobuf/support/wrapper/MapValue.java         |  793 ---
 .../protobuf/support/wrapper/ThrowablePB.java      | 2662 ----------
 .../dubbo-serialization-protobuf/pom.xml           |   96 -
 .../support/GenericProtobufJsonObjectInput.java    |  164 -
 .../support/GenericProtobufJsonObjectOutput.java   |  161 -
 .../support/GenericProtobufJsonSerialization.java  |   54 -
 .../support/GenericProtobufObjectInput.java        |  146 -
 .../support/GenericProtobufObjectOutput.java       |  157 -
 .../support/GenericProtobufSerialization.java      |   63 -
 .../serialize/protobuf/support/ProtobufUtils.java  |  206 -
 .../protobuf/support/ProtobufWrappedException.java |   68 -
 .../src/main/proto/MapValue.proto                  |   27 -
 .../src/main/proto/ThrowablePB.proto               |   64 -
 ...org.apache.dubbo.common.serialize.Serialization |    2 -
 .../dubbo-serialization-protostuff/pom.xml         |   53 -
 .../protostuff/ProtostuffObjectInput.java          |  136 -
 .../protostuff/ProtostuffObjectOutput.java         |  130 -
 .../protostuff/ProtostuffSerialization.java        |   58 -
 .../dubbo/common/serialize/protostuff/Wrapper.java |   33 -
 .../protostuff/delegate/SqlDateDelegate.java       |   55 -
 .../protostuff/delegate/TimeDelegate.java          |   57 -
 .../protostuff/delegate/TimestampDelegate.java     |   57 -
 .../serialize/protostuff/utils/WrapperUtils.java   |  115 -
 ...org.apache.dubbo.common.serialize.Serialization |    1 -
 .../dubbo-serialization-test/pom.xml               |   86 -
 .../serialize/avro/AvroObjectInputOutputTest.java  |  196 -
 .../serialize/avro/AvroSerializationTest.java      |   64 -
 .../base/AbstractSerializationPersonFailTest.java  |  141 -
 .../base/AbstractSerializationPersonOkTest.java    |   92 -
 .../serialize/base/AbstractSerializationTest.java  | 1212 -----
 .../fastjson/FastJsonObjectInputTest.java          |  199 -
 .../fastjson/FastJsonObjectOutputTest.java         |  142 -
 .../fastjson/FastJsonSerializationTest.java        |   62 -
 .../dubbo/common/serialize/fst/FstFactoryTest.java |   32 -
 .../common/serialize/fst/FstObjectInputTest.java   |   51 -
 .../common/serialize/fst/FstObjectOutputTest.java  |  186 -
 .../common/serialize/fst/FstSerializationTest.java |   63 -
 .../serialize/hessian2/Hessian2PersonOkTest.java   |  212 -
 .../hessian2/Hessian2SerializationTest.java        |  210 -
 .../jdk/CompactedJavaSerializationTest.java        |   27 -
 .../serialize/jdk/JavaSerializationTest.java       |   27 -
 .../common/serialize/jdk/JdkPersonOkTest.java      |   30 -
 .../serialize/jdk/NativeJavaSerializationTest.java |   26 -
 .../common/serialize/kryo/KryoPersonOkTest.java    |   29 -
 .../serialize/kryo/KyroSerializationTest.java      |   26 -
 .../common/serialize/kryo/ReflectionUtilsTest.java |   46 -
 .../dubbo/common/serialize/model/AnimalEnum.java   |   21 -
 .../dubbo/common/serialize/model/BizException.java |   29 -
 .../model/BizExceptionNoDefaultConstructor.java    |   26 -
 .../dubbo/common/serialize/model/Organization.java |   30 -
 .../dubbo/common/serialize/model/Person.java       |   95 -
 .../common/serialize/model/SerializablePerson.java |   97 -
 .../dubbo/common/serialize/model/media/Image.java  |  120 -
 .../dubbo/common/serialize/model/media/Media.java  |  205 -
 .../common/serialize/model/media/MediaContent.java |   78 -
 .../common/serialize/model/person/BigPerson.java   |  151 -
 .../common/serialize/model/person/FullAddress.java |  202 -
 .../common/serialize/model/person/PersonInfo.java  |  206 -
 .../serialize/model/person/PersonStatus.java       |   22 -
 .../dubbo/common/serialize/model/person/Phone.java |  139 -
 .../support/AbstractProtobufSerializationTest.java |  372 --
 .../GenericProtobufJsonObjectOutputTest.java       |  206 -
 .../GenericProtobufJsonSerializationTest.java      |   23 -
 .../support/GenericProtobufSerializationTest.java  |   23 -
 .../serialize/protobuf/support/model/GooglePB.java | 3431 -------------
 .../protobuf/support/model/ServiceInterface.java   |   21 -
 .../protostuff/ProtostuffObjectOutputTest.java     |  242 -
 .../protostuff/ProtostuffSerializationTest.java    |   27 -
 .../support/SerializableClassRegistryTest.java     |   38 -
 .../src/test/proto/GooglePB.proto                  |   51 -
 .../SimpleDO.fc                                    |    2 -
 dubbo-spi-serialization/pom.xml                    |   42 -
 dubbo-test/pom.xml                                 |  247 -
 .../apache/dubbo/config/AbstractConfigTest.java    |  927 ----
 .../dubbo/config/AbstractInterfaceConfigTest.java  |  354 --
 .../dubbo/config/AbstractMethodConfigTest.java     |  126 -
 .../dubbo/config/AbstractReferenceConfigTest.java  |  212 -
 .../dubbo/config/AbstractServiceConfigTest.java    |  184 -
 .../apache/dubbo/config/ApplicationConfigTest.java |  217 -
 .../apache/dubbo/config/ArgumentConfigTest.java    |   63 -
 .../dubbo/config/ConfigCenterConfigTest.java       |   44 -
 .../apache/dubbo/config/ConsumerConfigTest.java    |   81 -
 .../org/apache/dubbo/config/MethodConfigTest.java  |  240 -
 .../org/apache/dubbo/config/ModuleConfigTest.java  |  104 -
 .../org/apache/dubbo/config/MonitorConfigTest.java |  107 -
 .../apache/dubbo/config/ProtocolConfigTest.java    |  204 -
 .../apache/dubbo/config/ProviderConfigTest.java    |  219 -
 .../apache/dubbo/config/ReferenceConfigTest.java   |  159 -
 .../apache/dubbo/config/RegistryConfigTest.java    |  190 -
 .../org/apache/dubbo/config/ServiceConfigTest.java |  264 -
 .../test/java/org/apache/dubbo/config/api/Box.java |   23 -
 .../org/apache/dubbo/config/api/DemoException.java |   42 -
 .../org/apache/dubbo/config/api/DemoService.java   |   37 -
 .../java/org/apache/dubbo/config/api/Greeting.java |   24 -
 .../java/org/apache/dubbo/config/api/User.java     |   65 -
 .../ConsulDubboServiceConsumerBootstrap.java       |   52 -
 .../ConsulDubboServiceProviderBootstrap.java       |   42 -
 .../dubbo/config/bootstrap/DubboBootstrapTest.java |  154 -
 .../bootstrap/DubboServiceConsumerBootstrap.java   |   58 -
 .../bootstrap/DubboServiceProviderBootstrap.java   |   95 -
 .../DubboServiceProviderMinimumBootstrap.java      |   38 -
 .../apache/dubbo/config/bootstrap/EchoService.java |   31 -
 .../dubbo/config/bootstrap/EchoServiceImpl.java    |   36 -
 .../EtcdDubboServiceConsumerBootstrap.java         |   51 -
 .../EtcdDubboServiceProviderBootstrap.java         |   94 -
 .../NacosDubboServiceConsumerBootstrap.java        |   56 -
 .../NacosDubboServiceProviderBootstrap.java        |   51 -
 .../ZookeeperDubboServiceConsumerBootstrap.java    |   55 -
 .../ZookeeperDubboServiceProviderBootstrap.java    |   43 -
 .../bootstrap/builders/AbstractBuilderTest.java    |  126 -
 .../builders/AbstractInterfaceBuilderTest.java     |  311 --
 .../builders/AbstractMethodBuilderTest.java        |  196 -
 .../builders/AbstractReferenceBuilderTest.java     |  151 -
 .../builders/AbstractServiceBuilderTest.java       |  245 -
 .../bootstrap/builders/ApplicationBuilderTest.java |  255 -
 .../bootstrap/builders/ArgumentBuilderTest.java    |   63 -
 .../builders/ConfigCenterBuilderTest.java          |  169 -
 .../bootstrap/builders/ConsumerBuilderTest.java    |   95 -
 .../builders/MetadataReportBuilderTest.java        |  151 -
 .../bootstrap/builders/MethodBuilderTest.java      |  189 -
 .../bootstrap/builders/ModuleBuilderTest.java      |  112 -
 .../bootstrap/builders/MonitorBuilderTest.java     |  135 -
 .../bootstrap/builders/ProtocolBuilderTest.java    |  338 --
 .../bootstrap/builders/ProviderBuilderTest.java    |  227 -
 .../bootstrap/builders/ReferenceBuilderTest.java   |  125 -
 .../bootstrap/builders/RegistryBuilderTest.java    |  256 -
 .../bootstrap/builders/ServiceBuilderTest.java     |  131 -
 .../DubboInterfaceConsumerBootstrap.java           |   57 -
 .../apache/dubbo/config/bootstrap/rest/User.java   |   77 -
 .../dubbo/config/bootstrap/rest/UserService.java   |   45 -
 .../config/bootstrap/rest/UserServiceImpl.java     |   32 -
 .../apache/dubbo/config/cache/CacheService.java    |   26 -
 .../dubbo/config/cache/CacheServiceImpl.java       |   32 -
 .../org/apache/dubbo/config/cache/CacheTest.java   |  140 -
 .../config/consumer/DemoActionByAnnotation.java    |   35 -
 .../dubbo/config/consumer/DemoActionBySetter.java  |   36 -
 .../dubbo/config/consumer/DemoInterceptor.java     |   31 -
 .../PublishingServiceDefinitionListenerTest.java   |   94 -
 .../DelegateProviderMetaDataInvokerTest.java       |   60 -
 .../apache/dubbo/config/mock/GreetingLocal1.java   |   21 -
 .../apache/dubbo/config/mock/GreetingLocal2.java   |   26 -
 .../apache/dubbo/config/mock/GreetingLocal3.java   |   32 -
 .../apache/dubbo/config/mock/GreetingMock1.java    |   20 -
 .../apache/dubbo/config/mock/GreetingMock2.java    |   29 -
 .../org/apache/dubbo/config/mock/MockCodec.java    |   37 -
 .../apache/dubbo/config/mock/MockDispatcher.java   |   29 -
 .../apache/dubbo/config/mock/MockExchanger.java    |   37 -
 .../dubbo/config/mock/MockExporterListener.java    |   34 -
 .../org/apache/dubbo/config/mock/MockFilter.java   |   30 -
 .../dubbo/config/mock/MockInvokerListener.java     |   33 -
 .../apache/dubbo/config/mock/MockLoadBalance.java  |   32 -
 .../org/apache/dubbo/config/mock/MockProtocol.java |   89 -
 .../apache/dubbo/config/mock/MockProtocol2.java    |   48 -
 .../apache/dubbo/config/mock/MockProxyFactory.java |   39 -
 .../org/apache/dubbo/config/mock/MockRegistry.java |  110 -
 .../dubbo/config/mock/MockRegistryFactory.java     |   37 -
 .../dubbo/config/mock/MockRegistryFactory2.java    |   31 -
 .../dubbo/config/mock/MockStatusChecker.java       |   28 -
 .../dubbo/config/mock/MockTelnetHandler.java       |   29 -
 .../apache/dubbo/config/mock/MockThreadPool.java   |   30 -
 .../apache/dubbo/config/mock/MockTransporter.java  |   42 -
 .../apache/dubbo/config/mock/TestProxyFactory.java |   33 -
 .../config/provider/impl/DemoServiceImpl.java      |   51 -
 .../config/url/ExporterSideConfigUrlTest.java      |  102 -
 .../dubbo/config/url/InvokerSideConfigUrlTest.java |  217 -
 .../dubbo/config/url/RpcConfigGetSetProxy.java     |  166 -
 .../org/apache/dubbo/config/url/UrlTestBase.java   |  202 -
 .../dubbo/config/utils/MockReferenceConfig.java    |   59 -
 .../config/utils/ReferenceConfigCacheTest.java     |  151 -
 .../dubbo/config/utils/XxxMockReferenceConfig.java |   59 -
 .../dubbo/config/utils/service/FooService.java     |   23 -
 .../dubbo/config/utils/service/FooServiceImpl.java |   23 -
 .../dubbo/config/utils/service/XxxService.java     |   23 -
 .../dubbo/config/utils/service/XxxServiceImpl.java |   23 -
 .../metadata/MetadataServiceExporterTest.java      |   42 -
 .../org.apache.dubbo.common.status.StatusChecker   |   18 -
 .../org.apache.dubbo.common.threadpool.ThreadPool  |   18 -
 .../org.apache.dubbo.registry.RegistryFactory      |    2 -
 .../services/org.apache.dubbo.remoting.Dispatcher  |   18 -
 .../services/org.apache.dubbo.remoting.Transporter |   18 -
 .../org.apache.dubbo.remoting.exchange.Exchanger   |   18 -
 .../services/org.apache.dubbo.rpc.ExporterListener |   18 -
 .../META-INF/services/org.apache.dubbo.rpc.Filter  |    1 -
 .../services/org.apache.dubbo.rpc.InvokerListener  |    1 -
 .../services/org.apache.dubbo.rpc.Protocol         |    2 -
 .../services/org.apache.dubbo.rpc.ProxyFactory     |    2 -
 .../services/org.apache.dubbo.rpc.cluster.Cluster  |    1 -
 .../org.apache.dubbo.rpc.cluster.LoadBalance       |    1 -
 dubbo-test/src/test/resources/dubbo.properties     |    2 -
 pom.xml                                            |  541 +-
 568 files changed, 1478 insertions(+), 73207 deletions(-)

diff --git a/.asf.yaml b/.asf.yaml
index 6aa91c1..69e38d5 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -1,3 +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.
+#
+#
+
 notifications:
     commits:      commits@dubbo.apache.org
     issues:       notifications@dubbo.apache.org
@@ -6,4 +25,4 @@ notifications:
 github:
   features:
     # Enable issue management
-    issues: true
\ No newline at end of file
+    issues: true
diff --git a/dubbo-test/src/test/resources/META-INF/services/org.apache.dubbo.remoting.Codec b/.editorconfig
similarity index 73%
rename from dubbo-test/src/test/resources/META-INF/services/org.apache.dubbo.remoting.Codec
rename to .editorconfig
index 94f7668..eefafba 100644
--- a/dubbo-test/src/test/resources/META-INF/services/org.apache.dubbo.remoting.Codec
+++ b/.editorconfig
@@ -1,4 +1,3 @@
-#
 # 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.
@@ -15,4 +14,18 @@
 # limitations under the License.
 #
 
-mockcodec=org.apache.dubbo.config.mock.MockCodec
\ No newline at end of file
+# EditorConfig is awesome: https://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+
+# 4 space indentation
+[*.{java,xml}]
+indent_style = space
+indent_size = 4
diff --git a/dubbo-test/src/test/resources/META-INF/services/org.apache.dubbo.remoting.telnet.TelnetHandler b/.gitattributes
similarity index 89%
rename from dubbo-test/src/test/resources/META-INF/services/org.apache.dubbo.remoting.telnet.TelnetHandler
rename to .gitattributes
index 76dfd94..c8c7a66 100644
--- a/dubbo-test/src/test/resources/META-INF/services/org.apache.dubbo.remoting.telnet.TelnetHandler
+++ b/.gitattributes
@@ -1,4 +1,3 @@
-#
 # 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.
@@ -14,5 +13,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-mocktelnethandler=org.apache.dubbo.config.mock.MockTelnetHandler
 
+# Auto detect text files and perform LF normalization
+*        text=auto
+
+*.java   text eol=lf
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7c91f5b..9c97150 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -4,20 +4,65 @@ on: [push, pull_request]
 
 jobs:
   build:
-    runs-on: ubuntu-latest
+    runs-on: ${{ matrix.os }}
     strategy:
+      fail-fast: false
       matrix:
-        java: [ 8, 11 ]
-    timeout-minutes: 20
+        os: [ ubuntu-18.04, windows-2019 ]
+        jdk: [ 8, 11 ]
     steps:
       - uses: actions/checkout@v2
-      - name: Set up JDK ${{ matrix.java }}
+        with:
+          path: dubbo-spi-extensions
+      - uses: actions/checkout@v2
+        with:
+          repository: 'apache/dubbo'
+          ref: '3.0'
+          path: dubbo
+      - name: "Set up JDK ${{ matrix.jdk }}"
         uses: actions/setup-java@v1
         with:
-          java-version: ${{ matrix.java }}
-      - name: Build with Maven
+          java-version: ${{ matrix.jdk }}
+      - uses: actions/cache@v2
+        name: "Cache local Maven repository"
+        with:
+          path: ~/.m2/repository
+          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+          restore-keys: |
+            ${{ runner.os }}-maven-
+      - name: "Build tools"
         run: |
-          cd ./dubbo-api-docs
-          mvn clean install -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true
-      - name: Upload coverage to codecov
-        uses: codecov/codecov-action@v1
\ No newline at end of file
+          cd ./dubbo
+          ./mvnw --batch-mode -U -e --no-transfer-progress install -pl dubbo-build-tools -am -DskipTests=true
+      - name: "Test with Maven"
+        timeout-minutes: 40
+        if: ${{ startsWith( matrix.os, 'ubuntu') }}
+        run: |
+          cd ./dubbo-spi-extensions
+          ./mvnw --batch-mode -U -e --no-transfer-progress clean test verify -Pjacoco -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true
+      - name: "Test with Maven"
+        timeout-minutes: 50
+        if: ${{ startsWith( matrix.os, 'windows') }}
+        run: |
+          cd ./dubbo-spi-extensions
+          ./mvnw --batch-mode -U -e --no-transfer-progress clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"checkstyle_unix.skip=true" -D"rat.skip=false" -D"maven.javadoc.skip=true"
+      - name: "Pack rat file if failure"
+        if: failure()
+        run: 7z a ${{ github.workspace }}/rat.zip *rat.txt -r
+      - name: "Upload rat file if failure"
+        if: failure()
+        uses: actions/upload-artifact@v2
+        with:
+          name: "rat-file"
+          path: ${{ github.workspace }}/rat.zip
+      - name: "Pack checkstyle file if failure"
+        if: failure()
+        run: 7z a ${{ github.workspace }}/checkstyle.zip *checkstyle* -r
+      - name: "Upload checkstyle file if failure"
+        if: failure()
+        uses: actions/upload-artifact@v2
+        with:
+          name: "checkstyle-file"
+          path: ${{ github.workspace }}/checkstyle.zip
+      - name: "Upload coverage to Codecov"
+        uses: codecov/codecov-action@v1
diff --git a/LICENSE b/LICENSE
index 7a4a3ea..d645695 100644
--- a/LICENSE
+++ b/LICENSE
@@ -199,4 +199,4 @@
    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.
\ No newline at end of file
+   limitations under the License.
diff --git a/codestyle/checkstyle-suppressions.xml b/codestyle/checkstyle-suppressions.xml
index 1817cf7..2e3e4de 100644
--- a/codestyle/checkstyle-suppressions.xml
+++ b/codestyle/checkstyle-suppressions.xml
@@ -3,6 +3,6 @@
         "-//Puppy Crawl//DTD Suppressions 1.1//EN"
         "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
 <suppressions>
-    <suppress files="[\\/]src[\\/]main[\\/]java[\\/]com[\\/]alibaba[\\/]com[\\/]caucho[\\/]hessian" checks=".*"/>
+    <suppress files="[\\/]build[\\/]generated[\\/]source[\\/]proto" checks=".*"/>
     <suppress files="Yylex\.java" checks="AvoidEscapedUnicodeCharacters"/>
-</suppressions>
\ No newline at end of file
+</suppressions>
diff --git a/codestyle/checkstyle.xml b/codestyle/checkstyle.xml
index 050fbed..413cc72 100644
--- a/codestyle/checkstyle.xml
+++ b/codestyle/checkstyle.xml
@@ -12,6 +12,10 @@
         <property name="fileExtensions" value="java"/>
     </module>
 
+    <module name="FileTabCharacter">
+        <property name="fileExtensions" value="java,xml"/>
+    </module>
+
     <!-- TreeWalker Checks -->
     <module name="TreeWalker">
         <module name="SuppressWarningsHolder"/>
diff --git a/codestyle/checkstyle_unix.xml b/codestyle/checkstyle_unix.xml
new file mode 100644
index 0000000..589c7d7
--- /dev/null
+++ b/codestyle/checkstyle_unix.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+        "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+        "http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
+
+<module name="Checker">
+    <module name="NewlineAtEndOfFile">
+        <property name="lineSeparator" value="lf" />
+    </module>
+</module>
diff --git a/codestyle/dubbo_codestyle_for_idea.xml b/codestyle/dubbo_codestyle_for_idea.xml
index 1f87caa..27fc652 100644
--- a/codestyle/dubbo_codestyle_for_idea.xml
+++ b/codestyle/dubbo_codestyle_for_idea.xml
@@ -13,4 +13,4 @@
             <package name="" withSubpackages="true" static="true"/>
         </value>
     </option>
-</code_scheme>
\ No newline at end of file
+</code_scheme>
diff --git a/dubbo-all/pom.xml b/dubbo-all/pom.xml
deleted file mode 100644
index 93898ca..0000000
--- a/dubbo-all/pom.xml
+++ /dev/null
@@ -1,1057 +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.
-  -->
-<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/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-parent</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
-    </parent>
-    <artifactId>dubbo-all</artifactId>
-    <packaging>jar</packaging>
-    <name>dubbo-all</name>
-    <description>The all in one project of dubbo</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-config-api</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-config-spring</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-cluster</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-common</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-filter-cache</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-filter-validation</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-api</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-netty</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-netty4</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-etcd3</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-mina</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-grizzly</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-p2p</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-http</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-api</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-dubbo</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-injvm</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-http</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-rmi</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-hessian</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-webservice</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-thrift</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-native-thrift</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-memcached</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-redis</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-rest</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-xml</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-grpc</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-api</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-default</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-multicast</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-zookeeper</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-redis</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-consul</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-etcd3</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-            <exclusions>
-                <exclusion>
-                    <groupId>io.grpc</groupId>
-                    <artifactId>grpc-core</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>io.grpc</groupId>
-                    <artifactId>grpc-netty</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-eureka</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-nacos</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-sofa</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-multiple</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-monitor-api</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-monitor-default</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-container-spring</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-container-log4j</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-container-logback</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-qos</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-api</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-fastjson</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-fst</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-hessian2</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-native-hession</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-jdk</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-kryo</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-avro</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-protostuff</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-gson</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-protobuf</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-configcenter-zookeeper</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-configcenter-apollo</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-configcenter-nacos</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-configcenter-consul</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-configcenter-etcd</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-            <exclusions>
-                <exclusion>
-                    <groupId>io.grpc</groupId>
-                    <artifactId>grpc-core</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>io.grpc</groupId>
-                    <artifactId>grpc-netty</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-compatible</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>com.alibaba</groupId>
-            <artifactId>hessian-lite</artifactId>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <!-- metadata -->
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-metadata-api</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-metadata-report-zookeeper</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-metadata-report-redis</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-metadata-report-consul</artifactId>
-            <version>${project.version}</version>
-            <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>
-            <exclusions>
-                <exclusion>
-                    <groupId>io.grpc</groupId>
-                    <artifactId>grpc-core</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>io.grpc</groupId>
-                    <artifactId>grpc-netty</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-metadata-report-nacos</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-auth</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-            <optional>true</optional>
-        </dependency>
-
-        <!-- Transitive dependencies -->
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-context</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.alibaba.spring</groupId>
-            <artifactId>spring-context-support</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.javassist</groupId>
-            <artifactId>javassist</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.netty</groupId>
-            <artifactId>netty-all</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.google.code.gson</groupId>
-            <artifactId>gson</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.yaml</groupId>
-            <artifactId>snakeyaml</artifactId>
-        </dependency>
-
-        <!-- Temporarily add this part to exclude transitive dependency -->
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-engine</artifactId>
-            <version>${junit_jupiter_version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-params</artifactId>
-            <version>${junit_jupiter_version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>cglib</groupId>
-            <artifactId>cglib-nodep</artifactId>
-            <version>${cglib_version}</version>
-            <scope>test</scope>
-            <optional>true</optional>
-        </dependency>
-    </dependencies>
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-shade-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>shade</goal>
-                        </goals>
-                        <configuration>
-                            <createSourcesJar>true</createSourcesJar>
-                            <promoteTransitiveDependencies>false</promoteTransitiveDependencies>
-                            <artifactSet>
-                                <includes>
-                                    <include>com.alibaba:hessian-lite</include>
-                                    <include>org.apache.dubbo:dubbo-config-api</include>
-                                    <include>org.apache.dubbo:dubbo-config-spring</include>
-                                    <include>org.apache.dubbo:dubbo-compatible</include>
-                                    <include>org.apache.dubbo:dubbo-common</include>
-                                    <include>org.apache.dubbo:dubbo-remoting-api</include>
-                                    <include>org.apache.dubbo:dubbo-remoting-netty</include>
-                                    <include>org.apache.dubbo:dubbo-remoting-netty4</include>
-                                    <include>org.apache.dubbo:dubbo-remoting-etcd3</include>
-                                    <include>org.apache.dubbo:dubbo-remoting-mina</include>
-                                    <include>org.apache.dubbo:dubbo-remoting-grizzly</include>
-                                    <include>org.apache.dubbo:dubbo-remoting-p2p</include>
-                                    <include>org.apache.dubbo:dubbo-remoting-http</include>
-                                    <include>org.apache.dubbo:dubbo-remoting-zookeeper</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-api</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-dubbo</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-injvm</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-http</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-rmi</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-hessian</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-webservice</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-thrift</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-native-thrift</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-memcached</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-redis</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-rest</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-xml</include>
-                                    <include>org.apache.dubbo:dubbo-rpc-grpc</include>
-                                    <include>org.apache.dubbo:dubbo-filter-validation</include>
-                                    <include>org.apache.dubbo:dubbo-filter-cache</include>
-                                    <include>org.apache.dubbo:dubbo-cluster</include>
-                                    <include>org.apache.dubbo:dubbo-registry-api</include>
-                                    <include>org.apache.dubbo:dubbo-registry-default</include>
-                                    <include>org.apache.dubbo:dubbo-registry-multicast</include>
-                                    <include>org.apache.dubbo:dubbo-registry-zookeeper</include>
-                                    <include>org.apache.dubbo:dubbo-registry-redis</include>
-                                    <include>org.apache.dubbo:dubbo-registry-consul</include>
-                                    <include>org.apache.dubbo:dubbo-registry-etcd3</include>
-                                    <include>org.apache.dubbo:dubbo-registry-eureka</include>
-                                    <include>org.apache.dubbo:dubbo-registry-nacos</include>
-                                    <include>org.apache.dubbo:dubbo-registry-sofa</include>
-                                    <include>org.apache.dubbo:dubbo-registry-multiple</include>
-                                    <include>org.apache.dubbo:dubbo-monitor-api</include>
-                                    <include>org.apache.dubbo:dubbo-monitor-default</include>
-                                    <include>org.apache.dubbo:dubbo-container-api</include>
-                                    <include>org.apache.dubbo:dubbo-container-spring</include>
-                                    <include>org.apache.dubbo:dubbo-container-log4j</include>
-                                    <include>org.apache.dubbo:dubbo-container-logback</include>
-                                    <include>org.apache.dubbo:dubbo-qos</include>
-                                    <include>org.apache.dubbo:dubbo-serialization-api</include>
-                                    <include>org.apache.dubbo:dubbo-serialization-fastjson</include>
-                                    <include>org.apache.dubbo:dubbo-serialization-hessian2</include>
-                                    <include>org.apache.dubbo:dubbo-serialization-fst</include>
-                                    <include>org.apache.dubbo:dubbo-serialization-kryo</include>
-                                    <include>org.apache.dubbo:dubbo-serialization-avro</include>
-                                    <include>org.apache.dubbo:dubbo-serialization-jdk</include>
-                                    <include>org.apache.dubbo:dubbo-serialization-protostuff</include>
-                                    <include>org.apache.dubbo:dubbo-serialization-gson</include>
-                                    <include>org.apache.dubbo:dubbo-serialization-protobuf</include>
-                                    <include>org.apache.dubbo:dubbo-configcenter-api</include>
-                                    <include>org.apache.dubbo:dubbo-configcenter-definition</include>
-                                    <include>org.apache.dubbo:dubbo-configcenter-apollo</include>
-                                    <include>org.apache.dubbo:dubbo-configcenter-zookeeper</include>
-                                    <include>org.apache.dubbo:dubbo-configcenter-consul</include>
-                                    <include>org.apache.dubbo:dubbo-configcenter-etcd</include>
-                                    <include>org.apache.dubbo:dubbo-configcenter-nacos</include>
-                                    <include>org.apache.dubbo:dubbo-metadata-api</include>
-                                    <include>org.apache.dubbo:dubbo-metadata-report-redis</include>
-                                    <include>org.apache.dubbo:dubbo-metadata-report-zookeeper</include>
-                                    <include>org.apache.dubbo:dubbo-metadata-report-consul</include>
-                                    <include>org.apache.dubbo:dubbo-metadata-report-etcd</include>
-                                    <include>org.apache.dubbo:dubbo-metadata-report-nacos</include>
-                                    <include>org.apache.dubbo:dubbo-serialization-native-hession</include>
-                                    <include>org.apache.dubbo:dubbo-auth</include>
-                                </includes>
-                            </artifactSet>
-                            <transformers>
-                                <!-- dubbo-common beginning -->
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.common.compiler.Compiler
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionFactory
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.common.infra.InfraAdapter
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.common.logger.LoggerAdapter
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.common.status.StatusChecker
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.common.store.DataStore
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool
-                                    </resource>
-                                </transformer>
-                                <!-- dubbo-common end -->
-
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.Dispatcher</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.Codec2</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.Transporter</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.exchange.Exchanger
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http.HttpBinder
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.p2p.Networker
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.telnet.TelnetHandler
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.InvokerListener</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.ExporterListener</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.ProxyFactory</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Cluster</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.LoadBalance
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Merger</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.RouterFactory
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.ConfiguratorFactory
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.container.Container</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.monitor.MonitorFactory
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.validation.Validation</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.cache.CacheFactory</resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
-                                    </resource>
-                                </transformer>
-                                <!-- @since 2.7.5 -->
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.event.EventDispatcher
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.MetadataServiceExporter
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.ServiceNameMapping
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscovery
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>META-INF/dubbo/internal/org.apache.dubbo.event.EventListener
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceInstanceCustomizer
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.registry.client.metadata.MetadataServiceURLBuilder
-                                    </resource>
-                                </transformer>
-
-                                <!-- @since 2.7.6 -->
-
-                                <!-- 'dubbo-common' module -->
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.common.convert.Converter
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.common.convert.multiple.MultiValueConverter
-                                    </resource>
-                                </transformer>
-
-                                <!-- 'dubbo-metadata-api' module -->
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.ServiceRestMetadataResolver
-                                    </resource>
-                                </transformer>
-
-                                <!-- 'dubbo-metadata-processor' module -->
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.builder.TypeDefinitionBuilder
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.rest.ServiceRestMetadataResolver
-                                    </resource>
-                                </transformer>
-
-                                <!-- @since 2.7.7 -->
-
-                                <!-- 'dubbo-common' module -->
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/services/org.apache.dubbo.common.extension.LoadingStrategy
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.auth.spi.AccessKeyStorage
-                                    </resource>
-                                </transformer>
-                                <transformer
-                                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
-                                    <resource>
-                                        META-INF/dubbo/internal/org.apache.dubbo.auth.spi.Authenticator
-                                    </resource>
-                                </transformer>
-
-                            </transformers>
-                            <filters>
-                                <filter>
-                                    <artifact>org.apache.dubbo:dubbo</artifact>
-                                    <excludes>
-                                        <!-- These following two line is optional, it can remove some warn log -->
-                                        <exclude>com/**</exclude>
-                                        <exclude>org/**</exclude>
-                                        <!-- This one is required -->
-                                        <exclude>META-INF/dubbo/**</exclude>
-                                    </excludes>
-                                </filter>
-                            </filters>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-
-    <profiles>
-        <profile>
-            <id>release</id>
-            <build>
-                <plugins>
-                    <plugin>
-                        <artifactId>maven-javadoc-plugin</artifactId>
-                        <version>${maven_javadoc_version}</version>
-                        <executions>
-                            <execution>
-                                <id>attach-javadoc</id>
-                                <goals>
-                                    <goal>jar</goal>
-                                </goals>
-                                <configuration>
-                                    <doclint>none</doclint>
-                                </configuration>
-                            </execution>
-                        </executions>
-                        <configuration>
-                            <includeDependencySources>true</includeDependencySources>
-                            <dependencySourceIncludes>
-                                <dependencySourceInclude>org.apache.dubbo:dubbo-*</dependencySourceInclude>
-                                <dependencySourceExclude>com.alibaba:hessian-*</dependencySourceExclude>
-                            </dependencySourceIncludes>
-                            <show>public</show>
-                            <charset>UTF-8</charset>
-                            <encoding>UTF-8</encoding>
-                            <docencoding>UTF-8</docencoding>
-                            <links>
-                                <link>http://docs.oracle.com/javase/7/docs/api</link>
-                            </links>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-</project>
diff --git a/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml b/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml
index 77251b0..7abfe58 100644
--- a/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-annotations/pom.xml
@@ -19,7 +19,7 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>org.apache.dubbo</groupId>
+        <groupId>org.apache.dubbo.extensions</groupId>
         <artifactId>dubbo-api-docs</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
diff --git a/dubbo-api-docs/dubbo-api-docs-core/pom.xml b/dubbo-api-docs/dubbo-api-docs-core/pom.xml
index ff4fcde..7e08d77 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-core/pom.xml
@@ -20,7 +20,7 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>org.apache.dubbo</groupId>
+        <groupId>org.apache.dubbo.extensions</groupId>
         <artifactId>dubbo-api-docs</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -31,7 +31,7 @@
     <dependencies>
 
         <dependency>
-            <groupId>org.apache.dubbo</groupId>
+            <groupId>org.apache.dubbo.extensions</groupId>
             <artifactId>dubbo-api-docs-annotations</artifactId>
         </dependency>
 
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
index eadab90..7e25b61 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/core/DubboApiDocsAnnotationScanner.java
@@ -16,8 +16,6 @@
  */
 package org.apache.dubbo.apidocs.core;
 
-import com.alibaba.fastjson.JSON;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.dubbo.apidocs.annotations.ApiDoc;
 import org.apache.dubbo.apidocs.annotations.ApiModule;
 import org.apache.dubbo.apidocs.annotations.RequestParam;
@@ -39,19 +37,22 @@ import org.apache.dubbo.config.RegistryConfig;
 import org.apache.dubbo.config.ServiceConfig;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.apache.dubbo.config.annotation.Service;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.aop.support.AopUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.event.ApplicationReadyEvent;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.annotation.Import;
-import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
+import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
 import java.math.BigDecimal;
@@ -120,8 +121,8 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
             ApiModule moduleAnn = apiModuleClass.getAnnotation(ApiModule.class);
             if (!apiModuleClass.isAnnotationPresent(Service.class) && !apiModuleClass.isAnnotationPresent(DubboService.class)) {
                 LOG.warn("【Warning】" + apiModuleClass.getName() + " @ApiModule annotation is used, " +
-                        "but it is not a dubbo provider (without " + Service.class.getName() + " or " +
-                        DubboService.class.getName() + " annotation)");
+                    "but it is not a dubbo provider (without " + Service.class.getName() + " or " +
+                    DubboService.class.getName() + " annotation)");
                 return;
             }
             boolean async;
@@ -238,7 +239,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
             Class<?> argClass = argsClass[i];
             Type parameterType = parametersTypes[i];
             methodParamInfoSb.append(METHOD_PARAM_INDEX_BOUNDARY_LEFT).append(i)
-                    .append(METHOD_PARAM_INDEX_BOUNDARY_RIGHT).append(argClass.getCanonicalName());
+                .append(METHOD_PARAM_INDEX_BOUNDARY_RIGHT).append(argClass.getCanonicalName());
             if (i + 1 < argsClass.length) {
                 methodParamInfoSb.append(METHOD_PARAMETER_SEPARATOR);
             }
@@ -291,6 +292,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
     /**
      * get method parameter types describe string
      * return empty string if describe string is no args and no return vals ()V
+     *
      * @param method method
      * @return method parameter types describe string
      */
@@ -308,16 +310,21 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
      */
     private List<ParamBean> processField(Class<?> argClass, Type parameterType, Parameter parameter) {
         Map<String, String> genericTypeAndNamesMap;
-        if (parameterType instanceof ParameterizedTypeImpl) {
-            ParameterizedTypeImpl parameterTypeImpl = (ParameterizedTypeImpl) parameterType;
-            TypeVariable<? extends Class<?>>[] typeVariables = parameterTypeImpl.getRawType().getTypeParameters();
-            Type[] actualTypeArguments = parameterTypeImpl.getActualTypeArguments();
-            genericTypeAndNamesMap = new HashMap<>(typeVariables.length);
-            for (int i = 0; i < typeVariables.length; i++) {
-                genericTypeAndNamesMap.put(typeVariables[i].getTypeName(), actualTypeArguments[i].getTypeName());
+        if (parameterType instanceof ParameterizedType) {
+            ParameterizedType parameterTypeImpl = (ParameterizedType) parameterType;
+            Type rawType = parameterTypeImpl.getRawType();
+            if (rawType instanceof Class<?>) {
+                TypeVariable<? extends Class<?>>[] typeVariables = ((Class<?>) rawType).getTypeParameters();
+                Type[] actualTypeArguments = parameterTypeImpl.getActualTypeArguments();
+                genericTypeAndNamesMap = new HashMap<>(typeVariables.length);
+                for (int i = 0; i < typeVariables.length; i++) {
+                    genericTypeAndNamesMap.put(typeVariables[i].getTypeName(), actualTypeArguments[i].getTypeName());
+                }
+            } else {
+                genericTypeAndNamesMap = Collections.emptyMap();
             }
         } else {
-            genericTypeAndNamesMap = Collections.EMPTY_MAP;
+            genericTypeAndNamesMap = Collections.emptyMap();
         }
 
         List<ParamBean> apiParamsList = new ArrayList<>(16);
@@ -352,16 +359,16 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 }
 
                 ParamBean tempParamBean = this.processHtmlType(null == genericType ?
-                        field.getType() : genericType, requestParam, paramBean);
+                    field.getType() : genericType, requestParam, paramBean);
                 if (tempParamBean == null || HtmlTypeEnum.TEXT_AREA.equals(tempParamBean.getHtmlType())) {
                     Object objResult;
                     if (null == genericType) {
                         objResult = ClassTypeUtil.initClassTypeWithDefaultValue(
-                                field.getGenericType(), field.getType(), 0, genericTypeAndNamesMap);
+                            field.getGenericType(), field.getType(), 0, genericTypeAndNamesMap);
                     } else {
                         objResult = ClassTypeUtil.initClassTypeWithDefaultValue(
-                                ClassTypeUtil.makeParameterizedType(genericTypeName), genericType, 0,
-                                true, genericTypeAndNamesMap);
+                            ClassTypeUtil.makeParameterizedType(genericTypeName), genericType, 0,
+                            true, genericTypeAndNamesMap);
                     }
                     if (!ClassTypeUtil.isBaseType(objResult)) {
                         paramBean.setHtmlType(HtmlTypeEnum.TEXT_AREA);
@@ -388,7 +395,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
             }
 
             Object objResult = ClassTypeUtil.initClassTypeWithDefaultValue(
-                    parameterType, argClass, 0, genericTypeAndNamesMap);
+                parameterType, argClass, 0, genericTypeAndNamesMap);
             if (!ClassTypeUtil.isBaseType(objResult)) {
                 paramBean.setHtmlType(HtmlTypeEnum.TEXT_AREA);
                 paramBean.setSubParamsJson(JSON.toJSONString(objResult, ClassTypeUtil.FAST_JSON_FEATURES));
@@ -424,7 +431,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
             param.setHtmlType(HtmlTypeEnum.TEXT_BYTE);
             processed = true;
         } else if (Long.class.isAssignableFrom(classType) || long.class.isAssignableFrom(classType) ||
-                BigDecimal.class.isAssignableFrom(classType) || BigInteger.class.isAssignableFrom(classType)) {
+            BigDecimal.class.isAssignableFrom(classType) || BigInteger.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.NUMBER_INTEGER);
             processed = true;
         } else if (Double.class.isAssignableFrom(classType) || double.class.isAssignableFrom(classType)) {
@@ -449,7 +456,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
             param.setHtmlType(HtmlTypeEnum.DATE_SELECTOR);
             processed = true;
         } else if (classType.isArray() || Collection.class.isAssignableFrom(classType) ||
-                Map.class.isAssignableFrom(classType)) {
+            Map.class.isAssignableFrom(classType)) {
             param.setHtmlType(HtmlTypeEnum.TEXT_AREA);
             processed = true;
         }
@@ -501,7 +508,7 @@ public class DubboApiDocsAnnotationScanner implements ApplicationListener<Applic
                 }
                 if (!checkSuccess) {
                     LOG.error("The allowed value in the @RequestParam annotation does not match the " +
-                            "annotated enumeration " + classType.getCanonicalName() + ", please check!");
+                        "annotated enumeration " + classType.getCanonicalName() + ", please check!");
                 }
             }
             processed = true;
diff --git a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
index fe94569..8dda30a 100644
--- a/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
+++ b/dubbo-api-docs/dubbo-api-docs-core/src/main/java/org/apache/dubbo/apidocs/utils/ClassTypeUtil.java
@@ -16,10 +16,15 @@
  */
 package org.apache.dubbo.apidocs.utils;
 
+import org.apache.dubbo.apidocs.annotations.RequestParam;
+import org.apache.dubbo.apidocs.annotations.ResponseProperty;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.alibaba.fastjson.util.ParameterizedTypeImpl;
 import org.apache.commons.lang3.StringUtils;
-import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.GenericArrayType;
@@ -42,20 +47,15 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 
-import org.apache.dubbo.apidocs.annotations.RequestParam;
-import org.apache.dubbo.apidocs.annotations.ResponseProperty;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-
+import static org.apache.dubbo.apidocs.core.Constants.CLASS_FIELD_NAME;
+import static org.apache.dubbo.apidocs.core.Constants.EMPTY_OBJECT_INSTANCE;
+import static org.apache.dubbo.apidocs.core.Constants.ENUM_VALUES_SEPARATOR;
+import static org.apache.dubbo.apidocs.core.Constants.METHOD_NAME_NAME;
+import static org.apache.dubbo.apidocs.core.Constants.RESPONSE_STR_EXAMPLE;
 import static org.apache.dubbo.apidocs.core.Constants.SKIP_FIELD_SERIALVERSIONUID;
 import static org.apache.dubbo.apidocs.core.Constants.SKIP_FIELD_THIS$0;
-import static org.apache.dubbo.apidocs.core.Constants.CLASS_FIELD_NAME;
 import static org.apache.dubbo.apidocs.core.Constants.SQUARE_BRACKET_LEFT;
 import static org.apache.dubbo.apidocs.core.Constants.SQUARE_BRACKET_RIGHT;
-import static org.apache.dubbo.apidocs.core.Constants.RESPONSE_STR_EXAMPLE;
-import static org.apache.dubbo.apidocs.core.Constants.ENUM_VALUES_SEPARATOR;
-import static org.apache.dubbo.apidocs.core.Constants.METHOD_NAME_NAME;
-import static org.apache.dubbo.apidocs.core.Constants.EMPTY_OBJECT_INSTANCE;
 import static org.apache.dubbo.apidocs.core.Constants.STRING_EMPTY;
 import static org.apache.dubbo.apidocs.core.Constants.STRING_KEY;
 
@@ -70,21 +70,21 @@ public class ClassTypeUtil {
      * fastjson features
      */
     public static SerializerFeature[] FAST_JSON_FEATURES = {
-            //Whether to output the field with null value. The default value is false.
-            SerializerFeature.WriteMapNullValue,
-            //If the list field is null, the output is [], not null
-            SerializerFeature.WriteNullListAsEmpty,
-            //If the character type field is null, the output is' ', not null
-            SerializerFeature.WriteNullStringAsEmpty,
-            //If the Boolean field is null, the output is false instead of null
-            SerializerFeature.WriteNullBooleanAsFalse,
-            // Null number output 0
-            SerializerFeature.WriteNullNumberAsZero,
-            //Eliminate the problem of circular reference to the same object.
-            // The default value is false (it may enter a dead cycle if not configured)
-            SerializerFeature.DisableCircularReferenceDetect,
-            // Use. Name() to handle enumeration
-            SerializerFeature.WriteEnumUsingName
+        //Whether to output the field with null value. The default value is false.
+        SerializerFeature.WriteMapNullValue,
+        //If the list field is null, the output is [], not null
+        SerializerFeature.WriteNullListAsEmpty,
+        //If the character type field is null, the output is' ', not null
+        SerializerFeature.WriteNullStringAsEmpty,
+        //If the Boolean field is null, the output is false instead of null
+        SerializerFeature.WriteNullBooleanAsFalse,
+        // Null number output 0
+        SerializerFeature.WriteNullNumberAsZero,
+        //Eliminate the problem of circular reference to the same object.
+        // The default value is false (it may enter a dead cycle if not configured)
+        SerializerFeature.DisableCircularReferenceDetect,
+        // Use. Name() to handle enumeration
+        SerializerFeature.WriteEnumUsingName
     };
 
     private static final int PROCESS_COUNT_MAX = 10;
@@ -93,13 +93,18 @@ public class ClassTypeUtil {
 
     public static String calss2Json(Type genericType, Class<?> classType) {
         Map<String, String> genericTypeAndNamesMap;
-        if (genericType instanceof ParameterizedTypeImpl) {
-            ParameterizedTypeImpl parameterTypeImpl = (ParameterizedTypeImpl) genericType;
-            TypeVariable<? extends Class<?>>[] typeVariables = parameterTypeImpl.getRawType().getTypeParameters();
-            Type[] actualTypeArguments = parameterTypeImpl.getActualTypeArguments();
-            genericTypeAndNamesMap = new HashMap<>(typeVariables.length);
-            for (int i = 0; i < typeVariables.length; i++) {
-                genericTypeAndNamesMap.put(typeVariables[i].getTypeName(), actualTypeArguments[i].getTypeName());
+        if (genericType instanceof ParameterizedType) {
+            ParameterizedType parameterTypeImpl = (ParameterizedType) genericType;
+            Type rawType = parameterTypeImpl.getRawType();
+            if (rawType instanceof Class<?>) {
+                TypeVariable<? extends Class<?>>[] typeVariables = ((Class<?>) rawType).getTypeParameters();
+                Type[] actualTypeArguments = parameterTypeImpl.getActualTypeArguments();
+                genericTypeAndNamesMap = new HashMap<>(typeVariables.length);
+                for (int i = 0; i < typeVariables.length; i++) {
+                    genericTypeAndNamesMap.put(typeVariables[i].getTypeName(), actualTypeArguments[i].getTypeName());
+                }
+            } else {
+                genericTypeAndNamesMap = Collections.emptyMap();
             }
         } else {
             genericTypeAndNamesMap = Collections.EMPTY_MAP;
@@ -120,7 +125,7 @@ public class ClassTypeUtil {
     public static Object initClassTypeWithDefaultValue(Type genericType, Class<?> classType, int processCount,
                                                        Map<String, String> methodPrarmGenericTypeAndNamesMap) {
         return initClassTypeWithDefaultValue(genericType, classType, processCount, false,
-                methodPrarmGenericTypeAndNamesMap);
+            methodPrarmGenericTypeAndNamesMap);
     }
 
     /**
@@ -137,28 +142,33 @@ public class ClassTypeUtil {
                                                        Map<String, String> methodPrarmGenericTypeAndNamesMap) {
         if (processCount >= PROCESS_COUNT_MAX) {
             LOG.warn("The depth of bean has exceeded 10 layers, the deeper layer will be ignored! " +
-                    "Please modify the parameter structure or check whether there is circular reference in bean!");
+                "Please modify the parameter structure or check whether there is circular reference in bean!");
             return null;
         }
         processCount++;
 
         Object initResult = initClassTypeWithDefaultValueNoProceeField(genericType, classType, processCount,
-                methodPrarmGenericTypeAndNamesMap);
+            methodPrarmGenericTypeAndNamesMap);
         if (null != initResult) {
             return initResult;
         }
 
         Map<String, String> genericTypeAndNamesMap;
-        if (genericType instanceof ParameterizedTypeImpl) {
-            ParameterizedTypeImpl parameterTypeImpl = (ParameterizedTypeImpl) genericType;
-            TypeVariable<? extends Class<?>>[] typeVariables = parameterTypeImpl.getRawType().getTypeParameters();
-            Type[] actualTypeArguments = parameterTypeImpl.getActualTypeArguments();
-            genericTypeAndNamesMap = new HashMap<>(typeVariables.length);
-            for (int i = 0; i < typeVariables.length; i++) {
-                genericTypeAndNamesMap.put(typeVariables[i].getTypeName(), actualTypeArguments[i].getTypeName());
+        if (genericType instanceof ParameterizedType) {
+            ParameterizedType parameterTypeImpl = (ParameterizedType) genericType;
+            Type rawType = parameterTypeImpl.getRawType();
+            if (rawType instanceof Class<?>) {
+                TypeVariable<? extends Class<?>>[] typeVariables = ((Class<?>) rawType).getTypeParameters();
+                Type[] actualTypeArguments = parameterTypeImpl.getActualTypeArguments();
+                genericTypeAndNamesMap = new HashMap<>(typeVariables.length);
+                for (int i = 0; i < typeVariables.length; i++) {
+                    genericTypeAndNamesMap.put(typeVariables[i].getTypeName(), actualTypeArguments[i].getTypeName());
+                }
+            } else {
+                genericTypeAndNamesMap = Collections.emptyMap();
             }
         } else {
-            genericTypeAndNamesMap = Collections.EMPTY_MAP;
+            genericTypeAndNamesMap = Collections.emptyMap();
         }
 
         Map<String, Object> result = new HashMap<>(16);
@@ -180,13 +190,13 @@ public class ClassTypeUtil {
                     StringBuilder strValue = new StringBuilder(responseProperty.value());
                     if (StringUtils.isNotBlank(responseProperty.example())) {
                         strValue.append(SQUARE_BRACKET_LEFT).append(RESPONSE_STR_EXAMPLE)
-                                .append(responseProperty.example()).append(SQUARE_BRACKET_RIGHT);
+                            .append(responseProperty.example()).append(SQUARE_BRACKET_RIGHT);
                     }
                     result.put(field2.getName(), strValue.toString());
                 } else {
                     // It's string, but there's no annotation
                     result.put(field2.getName(), initClassTypeWithDefaultValue(field2.getGenericType(), field2.getType(),
-                            processCount, methodPrarmGenericTypeAndNamesMap));
+                        processCount, methodPrarmGenericTypeAndNamesMap));
                 }
             } else {
                 // Check if the type of the property is generic
@@ -195,12 +205,12 @@ public class ClassTypeUtil {
                     // The type of the attribute is generic. Find the generic from the definition of
                     // the class in which the attribute is located
                     result.put(field2.getName(), initClassTypeWithDefaultValue(makeParameterizedType(genericTypeName),
-                            makeClass(genericTypeName),
-                            processCount, true, methodPrarmGenericTypeAndNamesMap));
+                        makeClass(genericTypeName),
+                        processCount, true, methodPrarmGenericTypeAndNamesMap));
                 } else {
                     // Not generic
                     result.put(field2.getName(), initClassTypeWithDefaultValue(field2.getGenericType(), field2.getType(),
-                            processCount, methodPrarmGenericTypeAndNamesMap));
+                        processCount, methodPrarmGenericTypeAndNamesMap));
                 }
             }
         }
@@ -208,8 +218,8 @@ public class ClassTypeUtil {
     }
 
     public static Object initClassTypeWithDefaultValueNoProceeField(
-            Type genericType, Class<?> classType, int processCount,
-            Map<String, String> methodPrarmGenericTypeAndNamesMap) {
+        Type genericType, Class<?> classType, int processCount,
+        Map<String, String> methodPrarmGenericTypeAndNamesMap) {
         if (null == classType) {
             return EMPTY_OBJECT_INSTANCE;
         }
@@ -265,7 +275,7 @@ public class ClassTypeUtil {
                 }
 
                 obj = initClassTypeWithDefaultValue(makeParameterizedType(subTypeName), makeClass(subTypeName),
-                        processCount, isBuildClassAttribute, methodPrarmGenericTypeAndNamesMap);
+                    processCount, isBuildClassAttribute, methodPrarmGenericTypeAndNamesMap);
             } else {
                 Class<?> arrType = classType.getComponentType();
                 obj = initClassTypeWithDefaultValue(null, arrType, processCount, methodPrarmGenericTypeAndNamesMap);
@@ -292,7 +302,7 @@ public class ClassTypeUtil {
                 }
 
                 obj = initClassTypeWithDefaultValue(makeParameterizedType(subTypeName), makeClass(subTypeName),
-                        processCount, isBuildClassAttribute, methodPrarmGenericTypeAndNamesMap);
+                    processCount, isBuildClassAttribute, methodPrarmGenericTypeAndNamesMap);
                 list.add(obj);
             }
             return list;
@@ -319,7 +329,7 @@ public class ClassTypeUtil {
                 }
 
                 Object objValue = initClassTypeWithDefaultValue(makeParameterizedType(subTypeName), makeClass(subTypeName),
-                        processCount, isBuildClassAttribute, methodPrarmGenericTypeAndNamesMap);
+                    processCount, isBuildClassAttribute, methodPrarmGenericTypeAndNamesMap);
                 map.put(STRING_KEY, objValue);
             }
             return map;
@@ -331,7 +341,7 @@ public class ClassTypeUtil {
             ParameterizedType pt = (ParameterizedType) genericType;
             String typeName = pt.getActualTypeArguments()[0].getTypeName();
             return initClassTypeWithDefaultValue(makeParameterizedType(typeName), makeClass(typeName),
-                    processCount, methodPrarmGenericTypeAndNamesMap);
+                processCount, methodPrarmGenericTypeAndNamesMap);
         } else if (BigDecimal.class.isAssignableFrom(classType)) {
             return 0;
         } else if (BigInteger.class.isAssignableFrom(classType)) {
@@ -348,16 +358,16 @@ public class ClassTypeUtil {
      */
     public static boolean isBaseType(Object o) {
         if (o instanceof Integer ||
-                o instanceof Byte ||
-                o instanceof Long ||
-                o instanceof Double ||
-                o instanceof Float ||
-                o instanceof Character ||
-                o instanceof Short ||
-                o instanceof Boolean ||
-                o instanceof String ||
-                o instanceof BigDecimal ||
-                o instanceof BigInteger) {
+            o instanceof Byte ||
+            o instanceof Long ||
+            o instanceof Double ||
+            o instanceof Float ||
+            o instanceof Character ||
+            o instanceof Short ||
+            o instanceof Boolean ||
+            o instanceof String ||
+            o instanceof BigDecimal ||
+            o instanceof BigInteger) {
             return true;
         }
         return false;
@@ -392,7 +402,7 @@ public class ClassTypeUtil {
             String subTypeNames = typeName.substring((typeName.indexOf("<") + 1), (typeName.length() - 1));
             String[] subTypeNamesArray = subTypeNames.split(",");
             Type[] subTypes = makeSubClass(subTypeNamesArray);
-            return ParameterizedTypeImpl.make(typeClass, subTypes, null);
+            return new ParameterizedTypeImpl(subTypes, null, typeClass);
         } catch (ClassNotFoundException e) {
             LOG.warn("Exception getting generics in completabilefuture", e);
             return null;
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml
index ccd5cff..3e70a2a 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-api/pom.xml
@@ -19,7 +19,7 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>org.apache.dubbo.examples.apidocs</groupId>
+        <groupId>org.apache.dubbo.extensions.examples.apidocs</groupId>
         <artifactId>dubbo-api-docs-examples</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -33,7 +33,7 @@
 
     <dependencies>
         <dependency>
-            <groupId>org.apache.dubbo</groupId>
+            <groupId>org.apache.dubbo.extensions</groupId>
             <artifactId>dubbo-api-docs-annotations</artifactId>
         </dependency>
     </dependencies>
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
index de8500c..7cf765b 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/pom.xml
@@ -19,7 +19,7 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>org.apache.dubbo.examples.apidocs</groupId>
+        <groupId>org.apache.dubbo.extensions.examples.apidocs</groupId>
         <artifactId>dubbo-api-docs-examples</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -33,12 +33,13 @@
 
     <dependencies>
         <dependency>
-            <groupId>org.apache.dubbo</groupId>
+            <groupId>org.apache.dubbo.extensions</groupId>
             <artifactId>dubbo-api-docs-core</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.dubbo.examples.apidocs</groupId>
+            <groupId>org.apache.dubbo.extensions.examples.apidocs</groupId>
             <artifactId>examples-api</artifactId>
+            <version>${revision}</version>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/dubbo.properties b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/dubbo.properties
index ca71826..ad602ba 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/dubbo.properties
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider-sca/src/main/resources/dubbo.properties
@@ -1 +1 @@
-dubbo.application.qos.port=22222
\ No newline at end of file
+dubbo.application.qos.port=22222
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
index 71521a1..402433f 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/examples-provider/pom.xml
@@ -19,7 +19,7 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>org.apache.dubbo.examples.apidocs</groupId>
+        <groupId>org.apache.dubbo.extensions.examples.apidocs</groupId>
         <artifactId>dubbo-api-docs-examples</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
@@ -33,12 +33,13 @@
 
     <dependencies>
         <dependency>
-            <groupId>org.apache.dubbo</groupId>
+            <groupId>org.apache.dubbo.extensions</groupId>
             <artifactId>dubbo-api-docs-core</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.dubbo.examples.apidocs</groupId>
+            <groupId>org.apache.dubbo.extensions.examples.apidocs</groupId>
             <artifactId>examples-api</artifactId>
+            <version>${revision}</version>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
@@ -47,6 +48,11 @@
 
         <dependency>
             <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-registry-nacos</artifactId>
             <exclusions>
                 <exclusion>
diff --git a/dubbo-api-docs/dubbo-api-docs-examples/pom.xml b/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
index ddadcc8..a97e334 100644
--- a/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
+++ b/dubbo-api-docs/dubbo-api-docs-examples/pom.xml
@@ -19,13 +19,13 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>org.apache.dubbo</groupId>
+        <groupId>org.apache.dubbo.extensions</groupId>
         <artifactId>dubbo-api-docs</artifactId>
         <version>${revision}</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
-    <groupId>org.apache.dubbo.examples.apidocs</groupId>
+    <groupId>org.apache.dubbo.extensions.examples.apidocs</groupId>
     <artifactId>dubbo-api-docs-examples</artifactId>
 
     <packaging>pom</packaging>
diff --git a/dubbo-api-docs/pom.xml b/dubbo-api-docs/pom.xml
index b66ac3c..fea0da8 100644
--- a/dubbo-api-docs/pom.xml
+++ b/dubbo-api-docs/pom.xml
@@ -18,74 +18,21 @@
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
-        <groupId>org.apache</groupId>
-        <artifactId>apache</artifactId>
-        <version>19</version>
-        <relativePath/>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>extensions-parent</artifactId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
     </parent>
-    <groupId>org.apache.dubbo</groupId>
+
     <artifactId>dubbo-api-docs</artifactId>
     <version>${revision}</version>
     <packaging>pom</packaging>
+
     <name>${project.artifactId}</name>
     <description>Dubbo interface documentation, testing tools</description>
-    <url>https://github.com/apache/dubbo</url>
     <inceptionYear>2020</inceptionYear>
-    <licenses>
-        <license>
-            <name>Apache License, Version 2.0</name>
-            <url>http://www.apache.org/licenses/LICENSE-2.0</url>
-            <distribution>repo</distribution>
-        </license>
-    </licenses>
-
-    <scm>
-        <url>https://github.com/apache/dubbo</url>
-        <connection>scm:git:https://github.com/apache/dubbo-spi-extensions.git</connection>
-        <developerConnection>scm:git:https://github.com/apache/dubbo-spi-extensions.git</developerConnection>
-        <tag>HEAD</tag>
-    </scm>
-    <mailingLists>
-        <mailingList>
-            <name>Development List</name>
-            <subscribe>dev-subscribe@dubbo.apache.org</subscribe>
-            <unsubscribe>dev-unsubscribe@dubbo.apache.org</unsubscribe>
-            <post>dev@dubbo.apache.org</post>
-        </mailingList>
-        <mailingList>
-            <name>Commits List</name>
-            <subscribe>commits-subscribe@dubbo.apache.org</subscribe>
-            <unsubscribe>commits-unsubscribe@dubbo.apache.org</unsubscribe>
-            <post>commits@dubbo.apache.org</post>
-        </mailingList>
-        <mailingList>
-            <name>Issues List</name>
-            <subscribe>issues-subscribe@dubbo.apache.org</subscribe>
-            <unsubscribe>issues-unsubscribe@dubbo.apache.org</unsubscribe>
-            <post>issues@dubbo.apache.org</post>
-        </mailingList>
-    </mailingLists>
-    <developers>
-        <developer>
-            <id>dubbo.io</id>
-            <name>The Dubbo Project Contributors</name>
-            <email>dev-subscribe@dubbo.apache.org</email>
-            <url>http://dubbo.apache.org/</url>
-        </developer>
-    </developers>
-
-    <organization>
-        <name>The Apache Software Foundation</name>
-        <url>http://www.apache.org/</url>
-    </organization>
-
-    <issueManagement>
-        <system>Github Issues</system>
-        <url>https://github.com/apache/dubbo-spi-extensions/issues</url>
-    </issueManagement>
 
     <properties>
-        <revision>2.7.8.3</revision>
         <project.build.jdkVersion>1.8</project.build.jdkVersion>
         <argLine>-Dfile.encoding=UTF-8</argLine>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -96,6 +43,7 @@
 
         <spring-boot.version>2.3.4.RELEASE</spring-boot.version>
         <dubbo.version>2.7.8</dubbo.version>
+        <dubbo_version>2.7.8</dubbo_version>
         <commons-beanutils.version>1.9.4</commons-beanutils.version>
         <commons-collections.version>4.2</commons-collections.version>
         <disruptor.version>3.4.2</disruptor.version>
@@ -125,12 +73,12 @@
 
             <!-- Internal libs -->
             <dependency>
-                <groupId>org.apache.dubbo</groupId>
+                <groupId>org.apache.dubbo.extensions</groupId>
                 <artifactId>dubbo-api-docs-annotations</artifactId>
                 <version>${revision}</version>
             </dependency>
             <dependency>
-                <groupId>org.apache.dubbo</groupId>
+                <groupId>org.apache.dubbo.extensions</groupId>
                 <artifactId>dubbo-api-docs-core</artifactId>
                 <version>${revision}</version>
             </dependency>
@@ -243,57 +191,6 @@
                 </executions>
             </plugin>
             <plugin>
-                <groupId>org.apache.rat</groupId>
-                <artifactId>apache-rat-plugin</artifactId>
-                <version>0.12</version>
-                <executions>
-                    <execution>
-                        <id>verify.rat</id>
-                        <phase>verify</phase>
-                        <goals>
-                            <goal>check</goal>
-                        </goals>
-                        <configuration>
-                            <excludes>
-                                <exclude>**/.idea/</exclude>
-                                <exclude>**/*.iml</exclude>
-                                <exclude>**/*.txt</exclude>
-                                <exclude>**/*.sh</exclude>
-                                <exclude>**/*.bat</exclude>
-                                <exclude>**/*.md</exclude>
-                                <exclude>.git/</exclude>
-                                <exclude>**/*.git*</exclude>
-                                <exclude>.gitignore</exclude>
-                                <exclude>**/.settings/*</exclude>
-                                <exclude>**/.classpath</exclude>
-                                <exclude>**/*.properties</exclude>
-                                <exclude>**/.project</exclude>
-                                <exclude>**/target/**</exclude>
-                                <exclude>**/*.log</exclude>
-                                <exclude>.codecov.yml</exclude>
-                                <exclude>.travis.yml</exclude>
-                                <exclude>**/codestyle/*</exclude>
-                                <exclude>**/node_modules/**</exclude>
-                                <exclude>**/.babelrc</exclude>
-                                <exclude>**/.editorconfig</exclude>
-                                <exclude>**/package-lock.json</exclude>
-                                <exclude>**/package.json</exclude>
-                                <exclude>**/OpenSans.css</exclude>
-                                <exclude>**/.eslintignore</exclude>
-                                <exclude>**/.browserslistrc</exclude>
-                                <exclude>**/resources/META-INF/**</exclude>
-                                <exclude>**/src/main/resources/public/**</exclude>
-                                <exclude>**/src/licenses/**</exclude>
-                                <exclude>.github/**</exclude>
-                                <exclude>**/assets/**</exclude>
-                                <exclude>**/yarn.lock</exclude>
-                                <exclude>**/node/**</exclude>
-                            </excludes>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>flatten-maven-plugin</artifactId>
                 <version>${maven-flatten-version}</version>
@@ -322,17 +219,6 @@
                 </executions>
             </plugin>
             <plugin>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>${project.build.jdkVersion}</source>
-                    <target>${project.build.jdkVersion}</target>
-                    <encoding>${project.build.sourceEncoding}</encoding>
-                    <compilerArguments>
-                        <verbose/>
-                    </compilerArguments>
-                </configuration>
-            </plugin>
-            <plugin>
                 <artifactId>maven-resources-plugin</artifactId>
                 <configuration>
                     <!-- We are not suppose to setup the customer resources here -->
@@ -349,43 +235,6 @@
                 </configuration>
             </plugin>
 
-            <plugin>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                </configuration>
-            </plugin>
-            <plugin>
-                <artifactId>maven-source-plugin</artifactId>
-                <version>2.2.1</version>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>jar-no-fork</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
-                <artifactId>maven-javadoc-plugin</artifactId>
-                <version>2.9.1</version>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>jar</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <configuration>
-                    <show>private</show>
-                    <nohelp>true</nohelp>
-                    <charset>UTF-8</charset>
-                    <encoding>UTF-8</encoding>
-                    <docencoding>UTF-8</docencoding>
-                    <additionalparam>-Xdoclint:none</additionalparam>
-                </configuration>
-            </plugin>
         </plugins>
     </build>
 
diff --git a/dubbo-spi-container/dubbo-container-log4j/pom.xml b/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/pom.xml
similarity index 56%
rename from dubbo-spi-container/dubbo-container-log4j/pom.xml
rename to dubbo-cluster-extensions/dubbo-cluster-broadcast-1/pom.xml
index 1b5b3d2..9761a2c 100644
--- a/dubbo-spi-container/dubbo-container-log4j/pom.xml
+++ b/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/pom.xml
@@ -1,3 +1,4 @@
+<?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
@@ -14,25 +15,24 @@
   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/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+<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>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-container</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
+        <artifactId>dubbo-cluster-extensions</artifactId>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
     </parent>
-    <artifactId>dubbo-container-log4j</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The log4j container module of dubbo project</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-    </properties>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-cluster-broadcast-1</artifactId>
+
     <dependencies>
         <dependency>
             <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-container-api</artifactId>
-            <version>${project.parent.version}</version>
+            <artifactId>dubbo-cluster</artifactId>
         </dependency>
     </dependencies>
-</project>
\ No newline at end of file
+
+</project>
diff --git a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockCluster.java b/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastCluster1.java
similarity index 68%
rename from dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockCluster.java
rename to dubbo-cluster-extensions/dubbo-cluster-broadcast-1/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastCluster1.java
index 39bf974..239913a 100644
--- a/dubbo-test/src/test/java/org/apache/dubbo/config/mock/MockCluster.java
+++ b/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastCluster1.java
@@ -6,7 +6,7 @@
  * (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
+ *     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,
@@ -14,16 +14,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.config.mock;
+package org.apache.dubbo.rpc.cluster.support;
 
-import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.cluster.Cluster;
 import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster;
+
+/**
+ * BroadcastCluster
+ *
+ */
+public class BroadcastCluster1 extends AbstractCluster {
 
-public class MockCluster implements Cluster {
     @Override
-    public <T> Invoker<T> join(Directory<T> directory) throws RpcException {
-        return null;
+    public <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException {
+        return new BroadcastCluster1Invoker<>(directory);
     }
+
 }
diff --git a/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastCluster1Invoker.java b/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastCluster1Invoker.java
new file mode 100644
index 0000000..45f11a3
--- /dev/null
+++ b/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastCluster1Invoker.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.rpc.cluster.support;
+
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.threadlocal.NamedInternalThreadFactory;
+import org.apache.dubbo.rpc.AppResponse;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcContext;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.cluster.LoadBalance;
+
+import com.google.gson.Gson;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.function.BiConsumer;
+import java.util.stream.Collectors;
+
+/**
+ * BroadcastCluster2Invoker
+ * <p>
+ * sed for collecting all service provider results when in broadcast2 mode
+ */
+public class BroadcastCluster1Invoker<T> extends AbstractClusterInvoker<T> {
+
+    private static final Logger logger = LoggerFactory.getLogger(BroadcastCluster1Invoker.class);
+
+    private static final String BROADCAST_RESULTS_KEY = "broadcast.results";
+
+    private final ExecutorService executor = Executors.newCachedThreadPool(
+            new NamedInternalThreadFactory("broadcast_cluster1", true));
+
+    public BroadcastCluster1Invoker(Directory<T> directory) {
+        super(directory);
+    }
+
+    @Override
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public Result doInvoke(final Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
+        checkInvokers(invokers, invocation);
+        RpcContext.getContext().setInvokers((List) invokers);
+        InvokeResult res = invoke(invokers, invocation);
+        if (hasException(res.exception)) {
+            return createResult(invocation, res.exception, res.resultList);
+        }
+        Object value = res.resultList.stream().map(it->it.getData()).findFirst().orElse(null);
+        return createResult(invocation, value, res.resultList);
+    }
+
+
+    private InvokeResult invoke(List<Invoker<T>> invokers, final Invocation invocation) {
+        List<BroadcastResult> resultList = new ArrayList<>(invokers.size());
+        List<Callable<BroadcastResult>> tasks = getCallables(invokers, invocation);
+
+        try {
+            List<Future<BroadcastResult>> futures = executor.invokeAll(tasks);
+            resultList = futures.stream().map(it -> {
+                try {
+                    return it.get();
+                } catch (Throwable e) {
+                    BroadcastResult br = new BroadcastResult();
+                    br.setException(getRpcException(e));
+                    br.setExceptionMsg(br.getException().getMessage());
+                    return br;
+                }
+            }).collect(Collectors.toList());
+        } catch (InterruptedException e) {
+            BroadcastResult br = new BroadcastResult();
+            br.setException(getRpcException(e));
+            br.setExceptionMsg(br.getException().getMessage());
+            resultList.add(br);
+        }
+
+        return new InvokeResult(resultList.stream().map(BroadcastResult::getException)
+                .filter(it -> null != it).findFirst().orElse(null), resultList);
+
+    }
+
+    private List<Callable<BroadcastResult>> getCallables(List<Invoker<T>> invokers, Invocation invocation) {
+        List<Callable<BroadcastResult>> tasks = invokers.stream().map(it -> (Callable<BroadcastResult>) () -> {
+            BroadcastResult br = new BroadcastResult(it.getUrl().getIp(), it.getUrl().getPort());
+            Result result = null;
+            try {
+                result = it.invoke(invocation);
+                if (null != result && result.hasException()) {
+                    Throwable resultException = result.getException();
+                    if (null != resultException) {
+                        RpcException exception = getRpcException(result.getException());
+                        br.setExceptionMsg(exception.getMessage());
+                        br.setException(exception);
+                        logger.warn(exception.getMessage(), exception);
+                    }
+                } else if (null != result) {
+                    br.setData(result.getValue());
+                    br.setResult(result);
+                }
+            } catch (Throwable ex) {
+                RpcException exception = getRpcException(result.getException());
+                br.setExceptionMsg(exception.getMessage());
+                br.setException(exception);
+                logger.warn(exception.getMessage(), exception);
+            }
+            return br;
+        }).collect(Collectors.toList());
+        return tasks;
+    }
+
+
+    private class InvokeResult {
+        public RpcException exception;
+        public List<BroadcastResult> resultList;
+
+        public InvokeResult(RpcException ex, List<BroadcastResult> resultList) {
+            this.exception = ex;
+            this.resultList = resultList;
+        }
+    }
+
+
+    private boolean hasException(RpcException exception) {
+        return null != exception;
+    }
+
+    private Result createResult(Invocation invocation, RpcException exception, List<BroadcastResult> resultList) {
+        AppResponse result = new AppResponse(invocation) {
+            @Override
+            public Result whenCompleteWithContext(BiConsumer<Result, Throwable> fn) {
+                RpcContext.getServerContext().setAttachment(BROADCAST_RESULTS_KEY, new Gson().toJson(resultList));
+                return new AppResponse();
+            }
+        };
+        result.setException(exception);
+        return result;
+    }
+
+    private Result createResult(Invocation invocation, Object value, List<BroadcastResult> resultList) {
+        return new AppResponse(invocation) {
+            @Override
+            public Result whenCompleteWithContext(BiConsumer<Result, Throwable> fn) {
+                RpcContext.getServerContext().setAttachment(BROADCAST_RESULTS_KEY, new Gson().toJson(resultList));
+                AppResponse res = new AppResponse();
+                res.setValue(value);
+                return res;
+            }
+        };
+    }
+
+    private RpcException getRpcException(Throwable throwable) {
+        RpcException rpcException = null;
+        if (throwable instanceof RpcException) {
+            rpcException = (RpcException) throwable;
+        } else {
+            rpcException = new RpcException(throwable.getMessage(), throwable);
+        }
+        return rpcException;
+    }
+}
diff --git a/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastResult.java b/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastResult.java
new file mode 100644
index 0000000..87da0d9
--- /dev/null
+++ b/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/src/main/java/org/apache/dubbo/rpc/cluster/support/BroadcastResult.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dubbo.rpc.cluster.support;
+
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+
+import java.io.Serializable;
+
+/**
+ * BroadcastResult
+ */
+public class BroadcastResult implements Serializable {
+
+
+    private String ip;
+
+    private int port;
+
+    private Object data;
+
+    private String exceptionMsg;
+
+    private transient Result result;
+
+    private transient RpcException exception;
+
+
+    public BroadcastResult() {
+    }
+
+    public BroadcastResult(String ip, int port) {
+        this.ip = ip;
+        this.port = port;
+    }
+
+    public String getIp() {
+        return ip;
+    }
+
+    public void setIp(String ip) {
+        this.ip = ip;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+    public String getExceptionMsg() {
+        return exceptionMsg;
+    }
+
+    public void setExceptionMsg(String exceptionMsg) {
+        this.exceptionMsg = exceptionMsg;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public Result getResult() {
+        return result;
+    }
+
+    public void setResult(Result result) {
+        this.result = result;
+    }
+
+    public RpcException getException() {
+        return exception;
+    }
+
+    public void setException(RpcException exception) {
+        this.exception = exception;
+    }
+}
diff --git a/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Cluster b/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Cluster
new file mode 100644
index 0000000..a4fd509
--- /dev/null
+++ b/dubbo-cluster-extensions/dubbo-cluster-broadcast-1/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.Cluster
@@ -0,0 +1 @@
+broadcast1=org.apache.dubbo.rpc.cluster.support.BroadcastCluster1
diff --git a/dubbo-spi-metadata/pom.xml b/dubbo-cluster-extensions/pom.xml
similarity index 77%
copy from dubbo-spi-metadata/pom.xml
copy to dubbo-cluster-extensions/pom.xml
index d35ed4b..f3a3b20 100644
--- a/dubbo-spi-metadata/pom.xml
+++ b/dubbo-cluster-extensions/pom.xml
@@ -1,3 +1,4 @@
+<?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
@@ -18,22 +19,18 @@
          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>
-        <groupId>org.apache.dubbo.spi</groupId>
-        <artifactId>dubbo-spi-extensions</artifactId>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>extensions-parent</artifactId>
         <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <artifactId>dubbo-spi-metadata</artifactId>
+    <artifactId>dubbo-cluster-extensions</artifactId>
     <packaging>pom</packaging>
-
-    <properties>
-        <skip_maven_deploy>true</skip_maven_deploy>
-    </properties>
-
     <modules>
-        <module>dubbo-metadata-report-consul</module>
-        <module>dubbo-metadata-report-etcd</module>
+        <module>dubbo-cluster-broadcast-1</module>
     </modules>
 
+
 </project>
diff --git a/dubbo-spi-serialization/dubbo-serialization-test/src/test/resources/log4j.xml b/dubbo-common-extensions/pom.xml
similarity index 59%
rename from dubbo-spi-serialization/dubbo-serialization-test/src/test/resources/log4j.xml
rename to dubbo-common-extensions/pom.xml
index 3c5e376..ec737d2 100644
--- a/dubbo-spi-serialization/dubbo-serialization-test/src/test/resources/log4j.xml
+++ b/dubbo-common-extensions/pom.xml
@@ -15,17 +15,17 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
-    <appender name="dubbo" class="org.apache.dubbo.common.utils.DubboAppender">
-        <param name="File" value="../../dubbo.log"/>
-        <param name="encoding" value="GBK"/>
-        <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="%d %p [%c:%M] - %m%n"/>
-        </layout>
-    </appender>
-    <root>
-        <level value="INFO"/>
-        <appender-ref ref="dubbo"/>
-    </root>
-</log4j:configuration>
\ No newline at end of file
+<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>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>extensions-parent</artifactId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-common-extensions</artifactId>
+
+</project>
diff --git a/dubbo-spi-container/pom.xml b/dubbo-configcenter-extensions/pom.xml
similarity index 58%
rename from dubbo-spi-container/pom.xml
rename to dubbo-configcenter-extensions/pom.xml
index e5f81c0..28e3faf 100644
--- a/dubbo-spi-container/pom.xml
+++ b/dubbo-configcenter-extensions/pom.xml
@@ -1,3 +1,4 @@
+<?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
@@ -14,22 +15,22 @@
   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/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+<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>
-        <groupId>org.apache.dubbo.spi</groupId>
-        <artifactId>dubbo-spi-extensions</artifactId>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>extensions-parent</artifactId>
         <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
     </parent>
-    <artifactId>dubbo-spi-container</artifactId>
-    <packaging>pom</packaging>
-    <name>${project.artifactId}</name>
-    <description>The container module of dubbo project</description>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-configcenter-extensions</artifactId>
+
     <properties>
-        <skip_maven_deploy>true</skip_maven_deploy>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
     </properties>
-    <modules>
-        <module>dubbo-container-log4j</module>
-        <module>dubbo-container-logback</module>
-    </modules>
+
 </project>
diff --git a/dubbo-extensions-distribution/dubbo-apache-release/pom.xml b/dubbo-extensions-distribution/dubbo-apache-release/pom.xml
new file mode 100644
index 0000000..bd367cc
--- /dev/null
+++ b/dubbo-extensions-distribution/dubbo-apache-release/pom.xml
@@ -0,0 +1,87 @@
+<!--
+  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/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>dubbo-extensions-distribution</artifactId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <artifactId>dubbo-extensions-apache-release</artifactId>
+    <packaging>pom</packaging>
+    <name>dubbo-extensions-apache-release</name>
+    <description>The apache source extensions release</description>
+    <properties>
+        <skip_maven_deploy>true</skip_maven_deploy>
+    </properties>
+
+    <profiles>
+        <profile>
+            <id>release</id>
+            <build>
+                <finalName>apache-dubbo-extensions-${project.version}</finalName>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <version>3.1.0</version>
+                        <executions>
+                            <execution>
+                                <id>bin</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <configuration>
+                                    <descriptors>
+                                        <descriptor>src/assembly/bin-release.xml</descriptor>
+                                    </descriptors>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>src</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <configuration>
+                                    <descriptors>
+                                        <descriptor>src/assembly/source-release.xml</descriptor>
+                                    </descriptors>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-gpg-plugin</artifactId>
+                        <version>1.6</version>
+                        <executions>
+                            <execution>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>sign</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/dubbo-spi-rpc/dubbo-rpc-thrift/src/test/resources/dubbo-demo-consumer.xml b/dubbo-extensions-distribution/dubbo-apache-release/src/assembly/bin-release.xml
similarity index 52%
rename from dubbo-spi-rpc/dubbo-rpc-thrift/src/test/resources/dubbo-demo-consumer.xml
rename to dubbo-extensions-distribution/dubbo-apache-release/src/assembly/bin-release.xml
index 3dccf35..36c7bb4 100644
--- a/dubbo-spi-rpc/dubbo-rpc-thrift/src/test/resources/dubbo-demo-consumer.xml
+++ b/dubbo-extensions-distribution/dubbo-apache-release/src/assembly/bin-release.xml
@@ -1,4 +1,3 @@
-<?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
@@ -15,18 +14,22 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
-       xmlns="http://www.springframework.org/schema/beans"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
-    http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
-
-    <dubbo:application name="dubbo-demo-consumer"/>
-
-    <dubbo:registry address="multicast://224.5.6.7:1234"/>
-
-    <dubbo:protocol name="thrift"/>
-
-    <dubbo:reference id="demoService" interface="org.apache.dubbo.rpc.gen.thrift.Demo$Iface" timeout="1000000"/>
-
-</beans>
\ No newline at end of file
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
+    <id>bin</id>
+    <formats>
+        <format>zip</format>
+    </formats>
+    <includeBaseDirectory>true</includeBaseDirectory>
+    <baseDirectory>${project.build.finalName}-bin</baseDirectory>
+    <fileSets>
+        <fileSet>
+            <directory>../../</directory>
+            <includes>
+                <include>DISCLAIMER</include>
+                <include>NOTICE</include>
+                <include>LICENSE</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/dubbo-extensions-distribution/dubbo-apache-release/src/assembly/source-release.xml b/dubbo-extensions-distribution/dubbo-apache-release/src/assembly/source-release.xml
new file mode 100644
index 0000000..68bab41
--- /dev/null
+++ b/dubbo-extensions-distribution/dubbo-apache-release/src/assembly/source-release.xml
@@ -0,0 +1,57 @@
+<!--
+  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.
+  -->
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
+    <id>src</id>
+    <formats>
+        <format>zip</format>
+    </formats>
+    <includeBaseDirectory>true</includeBaseDirectory>
+    <baseDirectory>${project.build.finalName}-src</baseDirectory>
+
+    <fileSets>
+        <fileSet>
+            <directory>../../</directory>
+            <useDefaultExcludes>true</useDefaultExcludes>
+            <includes>
+                <include>**/*</include>
+            </includes>
+            <excludes>
+                <exclude>**/target/**</exclude>
+                <exclude>**/build/**</exclude>
+                <exclude>**/eclipse-classes/**</exclude>
+                <exclude>*.enc</exclude>
+                <exclude>*.gpg</exclude>
+                <exclude>**/surefire*</exclude>
+                <exclude>**/svn-commit*</exclude>
+                <exclude>**/.idea/**</exclude>
+                <exclude>**/*.iml</exclude>
+                <exclude>**/*.ipr</exclude>
+                <exclude>**/*.iws</exclude>
+                <exclude>**/cobertura.ser</exclude>
+                <exclude>**/*.log</exclude>
+                <exclude>release.properties</exclude>
+                <exclude>**/*.xml.*</exclude>
+                <exclude>**/*.patch</exclude>
+                <exclude>**/.mvn/**</exclude>
+                <exclude>**/*.jar</exclude>
+                <exclude>**/mvnw*</exclude>
+                <exclude>**/.flattened-pom.xml</exclude>
+            </excludes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/dubbo-extensions-distribution/dubbo-bom/pom.xml b/dubbo-extensions-distribution/dubbo-bom/pom.xml
new file mode 100644
index 0000000..a7ede71
--- /dev/null
+++ b/dubbo-extensions-distribution/dubbo-bom/pom.xml
@@ -0,0 +1,146 @@
+<?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">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>extensions-parent</artifactId>
+        <version>${revision}</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>dubbo-extensions-bom</artifactId>
+    <packaging>pom</packaging>
+
+    <name>dubbo-extensions-bom</name>
+
+    <dependencyManagement>
+        <dependencies>
+            <!-- Dubbo Api Docs -->
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-api-docs</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-api-docs-annotations</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-api-docs-core</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <!-- Dubbo Cluster Extensions -->
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-cluster-extensions</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-cluster-broadcast-1</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <!-- Dubbo Common Extensions -->
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-common-extensions</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <!-- Dubbo Config Center Extensions -->
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-configcenter-extensions</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <!-- Dubbo Filter Extensions -->
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-filter-extensions</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <!-- Dubbo Metadata Report Extensions -->
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-metadata-report-extensions</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <!-- Dubbo Registry Extensions -->
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-registry-extensions</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <!-- Dubbo Remoting Extensions -->
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-remoting-extensions</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <!-- Dubbo RPC Extensions -->
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-rpc-extensions</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <!-- Dubbo Serialization Extensions -->
+            <dependency>
+                <groupId>org.apache.dubbo.extensions</groupId>
+                <artifactId>dubbo-serialization-extensions</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+        </dependencies>
+    </dependencyManagement>
+
+    <profiles>
+        <profile>
+            <id>release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-gpg-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>sign</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
diff --git a/dubbo-spi-serialization/dubbo-serialization-avro/pom.xml b/dubbo-extensions-distribution/pom.xml
similarity index 54%
rename from dubbo-spi-serialization/dubbo-serialization-avro/pom.xml
rename to dubbo-extensions-distribution/pom.xml
index 91ee1bc..f317454 100644
--- a/dubbo-spi-serialization/dubbo-serialization-avro/pom.xml
+++ b/dubbo-extensions-distribution/pom.xml
@@ -14,31 +14,36 @@
   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/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-serialization</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>extensions-parent</artifactId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
     </parent>
-    <artifactId>dubbo-serialization-avro</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The avro serialization module of dubbo project</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-    </properties>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-extensions-distribution</artifactId>
+    <packaging>pom</packaging>
 
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.avro</groupId>
-            <artifactId>avro</artifactId>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file
+    <profiles>
+        <profile>
+            <id>install</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <modules>
+                <module>dubbo-bom</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>release</id>
+            <modules>
+                <module>dubbo-apache-release</module>
+                <module>dubbo-bom</module>
+            </modules>
+        </profile>
+    </profiles>
+</project>
diff --git a/dubbo-spi-metadata/pom.xml b/dubbo-filter-extensions/pom.xml
similarity index 73%
copy from dubbo-spi-metadata/pom.xml
copy to dubbo-filter-extensions/pom.xml
index d35ed4b..5080dc4 100644
--- a/dubbo-spi-metadata/pom.xml
+++ b/dubbo-filter-extensions/pom.xml
@@ -1,3 +1,4 @@
+<?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
@@ -18,22 +19,13 @@
          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>
-        <groupId>org.apache.dubbo.spi</groupId>
-        <artifactId>dubbo-spi-extensions</artifactId>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>extensions-parent</artifactId>
         <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <artifactId>dubbo-spi-metadata</artifactId>
-    <packaging>pom</packaging>
-
-    <properties>
-        <skip_maven_deploy>true</skip_maven_deploy>
-    </properties>
-
-    <modules>
-        <module>dubbo-metadata-report-consul</module>
-        <module>dubbo-metadata-report-etcd</module>
-    </modules>
+    <artifactId>dubbo-filter-extensions</artifactId>
 
 </project>
diff --git a/dubbo-spi-metadata/pom.xml b/dubbo-metadata-report-extensions/pom.xml
similarity index 73%
copy from dubbo-spi-metadata/pom.xml
copy to dubbo-metadata-report-extensions/pom.xml
index d35ed4b..de4a2c7 100644
--- a/dubbo-spi-metadata/pom.xml
+++ b/dubbo-metadata-report-extensions/pom.xml
@@ -1,3 +1,4 @@
+<?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
@@ -18,22 +19,13 @@
          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>
-        <groupId>org.apache.dubbo.spi</groupId>
-        <artifactId>dubbo-spi-extensions</artifactId>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>extensions-parent</artifactId>
         <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <artifactId>dubbo-spi-metadata</artifactId>
-    <packaging>pom</packaging>
-
-    <properties>
-        <skip_maven_deploy>true</skip_maven_deploy>
-    </properties>
-
-    <modules>
-        <module>dubbo-metadata-report-consul</module>
-        <module>dubbo-metadata-report-etcd</module>
-    </modules>
+    <artifactId>dubbo-metadata-report-extensions</artifactId>
 
 </project>
diff --git a/dubbo-spi-metadata/pom.xml b/dubbo-registry-extensions/pom.xml
similarity index 73%
copy from dubbo-spi-metadata/pom.xml
copy to dubbo-registry-extensions/pom.xml
index d35ed4b..04cdd4b 100644
--- a/dubbo-spi-metadata/pom.xml
+++ b/dubbo-registry-extensions/pom.xml
@@ -1,3 +1,4 @@
+<?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
@@ -18,22 +19,13 @@
          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>
-        <groupId>org.apache.dubbo.spi</groupId>
-        <artifactId>dubbo-spi-extensions</artifactId>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>extensions-parent</artifactId>
         <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <artifactId>dubbo-spi-metadata</artifactId>
-    <packaging>pom</packaging>
-
-    <properties>
-        <skip_maven_deploy>true</skip_maven_deploy>
-    </properties>
-
-    <modules>
-        <module>dubbo-metadata-report-consul</module>
-        <module>dubbo-metadata-report-etcd</module>
-    </modules>
+    <artifactId>dubbo-registry-extensions</artifactId>
 
 </project>
diff --git a/dubbo-spi-metadata/pom.xml b/dubbo-remoting-extensions/pom.xml
similarity index 73%
copy from dubbo-spi-metadata/pom.xml
copy to dubbo-remoting-extensions/pom.xml
index d35ed4b..805d66d 100644
--- a/dubbo-spi-metadata/pom.xml
+++ b/dubbo-remoting-extensions/pom.xml
@@ -1,3 +1,4 @@
+<?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
@@ -18,22 +19,14 @@
          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>
-        <groupId>org.apache.dubbo.spi</groupId>
-        <artifactId>dubbo-spi-extensions</artifactId>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>extensions-parent</artifactId>
         <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <artifactId>dubbo-spi-metadata</artifactId>
-    <packaging>pom</packaging>
+    <artifactId>dubbo-remoting-extensions</artifactId>
 
-    <properties>
-        <skip_maven_deploy>true</skip_maven_deploy>
-    </properties>
-
-    <modules>
-        <module>dubbo-metadata-report-consul</module>
-        <module>dubbo-metadata-report-etcd</module>
-    </modules>
 
 </project>
diff --git a/dubbo-test/src/test/resources/log4j.xml b/dubbo-rpc-extensions/pom.xml
similarity index 57%
rename from dubbo-test/src/test/resources/log4j.xml
rename to dubbo-rpc-extensions/pom.xml
index bfc37a8..09fd505 100644
--- a/dubbo-test/src/test/resources/log4j.xml
+++ b/dubbo-rpc-extensions/pom.xml
@@ -1,3 +1,4 @@
+<?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
@@ -14,15 +15,17 @@
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
-<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
-    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
-        <layout class="org.apache.log4j.PatternLayout">
-            <param name="ConversionPattern" value="[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n"/>
-        </layout>
-    </appender>
-    <root>
-        <level value="INFO"/>
-        <appender-ref ref="CONSOLE"/>
-    </root>
-</log4j:configuration>
\ No newline at end of file
+<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>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>extensions-parent</artifactId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-rpc-extensions</artifactId>
+
+</project>
diff --git a/dubbo-spi-metadata/pom.xml b/dubbo-serialization-extensions/pom.xml
similarity index 73%
rename from dubbo-spi-metadata/pom.xml
rename to dubbo-serialization-extensions/pom.xml
index d35ed4b..0b44ebe 100644
--- a/dubbo-spi-metadata/pom.xml
+++ b/dubbo-serialization-extensions/pom.xml
@@ -1,3 +1,4 @@
+<?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
@@ -18,22 +19,14 @@
          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>
-        <groupId>org.apache.dubbo.spi</groupId>
-        <artifactId>dubbo-spi-extensions</artifactId>
+        <groupId>org.apache.dubbo.extensions</groupId>
+        <artifactId>extensions-parent</artifactId>
         <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <artifactId>dubbo-spi-metadata</artifactId>
-    <packaging>pom</packaging>
+    <artifactId>dubbo-serialization-extensions</artifactId>
 
-    <properties>
-        <skip_maven_deploy>true</skip_maven_deploy>
-    </properties>
-
-    <modules>
-        <module>dubbo-metadata-report-consul</module>
-        <module>dubbo-metadata-report-etcd</module>
-    </modules>
 
 </project>
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml b/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml
deleted file mode 100644
index 3349bff..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-consul/pom.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?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">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-configcenter</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>dubbo-configcenter-consul</artifactId>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.orbitz.consul</groupId>
-            <artifactId>consul-client</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.pszymczyk.consul</groupId>
-            <artifactId>embedded-consul</artifactId>
-        </dependency>
-    </dependencies>
-
-
-</project>
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java b/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
deleted file mode 100644
index 282bdef..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
+++ /dev/null
@@ -1,218 +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.configcenter.consul;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
-import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
-import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
-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.common.utils.StringUtils;
-
-import com.google.common.base.Charsets;
-import com.google.common.net.HostAndPort;
-import com.orbitz.consul.Consul;
-import com.orbitz.consul.KeyValueClient;
-import com.orbitz.consul.cache.KVCache;
-import com.orbitz.consul.model.kv.Value;
-
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import static org.apache.dubbo.common.config.configcenter.Constants.CONFIG_NAMESPACE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
-import static org.apache.dubbo.common.utils.StringUtils.EMPTY_STRING;
-
-/**
- * config center implementation for consul
- */
-public class ConsulDynamicConfiguration implements DynamicConfiguration {
-    private static final Logger logger = LoggerFactory.getLogger(ConsulDynamicConfiguration.class);
-
-    private static final int DEFAULT_PORT = 8500;
-    private static final int DEFAULT_WATCH_TIMEOUT = 60 * 1000;
-    private static final String WATCH_TIMEOUT = "consul-watch-timeout";
-
-    private URL url;
-    private String rootPath;
-    private Consul client;
-    private KeyValueClient kvClient;
-    private ConcurrentMap<String, ConsulListener> watchers = new ConcurrentHashMap<>();
-
-    public ConsulDynamicConfiguration(URL url) {
-        this.url = url;
-        this.rootPath = PATH_SEPARATOR + url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP) + PATH_SEPARATOR + "config";
-        String host = url.getHost();
-        int port = url.getPort() != 0 ? url.getPort() : DEFAULT_PORT;
-        client = Consul.builder().withHostAndPort(HostAndPort.fromParts(host, port)).build();
-        this.kvClient = client.keyValueClient();
-    }
-
-    @Override
-    public void addListener(String key, String group, ConfigurationListener listener) {
-        logger.info("register listener " + listener.getClass() + " for config with key: " + key + ", group: " + group);
-        String normalizedKey = convertKey(group, key);
-        ConsulListener watcher = watchers.computeIfAbsent(normalizedKey, k -> new ConsulListener(key, group));
-        watcher.addListener(listener);
-    }
-
-    @Override
-    public void removeListener(String key, String group, ConfigurationListener listener) {
-        logger.info("unregister listener " + listener.getClass() + " for config with key: " + key + ", group: " + group);
-        ConsulListener watcher = watchers.get(convertKey(group, key));
-        if (watcher != null) {
-            watcher.removeListener(listener);
-        }
-    }
-
-    @Override
-    public String getConfig(String key, String group, long timeout) throws IllegalStateException {
-        return (String) getInternalProperty(convertKey(group, key));
-    }
-
-    @Override
-    public SortedSet<String> getConfigKeys(String group) throws UnsupportedOperationException {
-        SortedSet<String> configKeys = new TreeSet<>();
-        String normalizedKey = convertKey(group, EMPTY_STRING);
-        List<String> keys = kvClient.getKeys(normalizedKey);
-        if (CollectionUtils.isNotEmpty(keys)) {
-            keys.stream()
-                    .filter(k -> !k.equals(normalizedKey))
-                    .map(k -> k.substring(k.lastIndexOf(PATH_SEPARATOR) + 1))
-                    .forEach(configKeys::add);
-        }
-        return configKeys;
-//        SortedSet<String> configKeys = new TreeSet<>();
-//        String normalizedKey = convertKey(group, key);
-//        kvClient.getValueAsString(normalizedKey).ifPresent(v -> {
-//            Collections.addAll(configKeys, v.split(","));
-//        });
-//        return configKeys;
-    }
-
-    /**
-     * @param key     the key to represent a configuration
-     * @param group   the group where the key belongs to
-     * @param content the content of configuration
-     * @return
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    public boolean publishConfig(String key, String group, String content) throws UnsupportedOperationException {
-//        String normalizedKey = convertKey(group, key);
-//        Value value = kvClient.getValue(normalizedKey).orElseThrow(() -> new IllegalArgumentException(normalizedKey + " does not exit."));
-//        Optional<String> old = value.getValueAsString();
-//        if (old.isPresent()) {
-//            content = old.get() + "," + content;
-//        }
-//
-//        while (!kvClient.putValue(key, content, value.getModifyIndex())) {
-//            value = kvClient.getValue(normalizedKey).orElseThrow(() -> new IllegalArgumentException(normalizedKey + " does not exit."));
-//            old = value.getValueAsString();
-//            if (old.isPresent()) {
-//                content = old.get() + "," + content;
-//            }
-//            try {
-//                Thread.sleep(10);
-//            } catch (InterruptedException e) {
-//                e.printStackTrace();
-//            }
-//        }
-//        return true;
-        String normalizedKey = convertKey(group, key);
-        return kvClient.putValue(normalizedKey + PATH_SEPARATOR + content);
-    }
-
-    @Override
-    public Object getInternalProperty(String key) {
-        logger.info("getting config from: " + key);
-        return kvClient.getValueAsString(key, Charsets.UTF_8).orElse(null);
-    }
-
-    @Override
-    public void close() throws Exception {
-        client.destroy();
-    }
-
-    private String buildPath(String group) {
-        String actualGroup = StringUtils.isEmpty(group) ? DEFAULT_GROUP : group;
-        return rootPath + PATH_SEPARATOR + actualGroup;
-    }
-
-    private String convertKey(String group, String key) {
-        return buildPath(group) + PATH_SEPARATOR + key;
-    }
-
-    private class ConsulListener implements KVCache.Listener<String, Value> {
-
-        private KVCache kvCache;
-        private Set<ConfigurationListener> listeners = new LinkedHashSet<>();
-        private String key;
-        private String group;
-        private String normalizedKey;
-
-        public ConsulListener(String key, String group) {
-            this.key = key;
-            this.group = group;
-            this.normalizedKey = convertKey(group, key);
-            initKVCache();
-        }
-
-        private void initKVCache() {
-            this.kvCache = KVCache.newCache(kvClient, normalizedKey);
-            kvCache.addListener(this);
-            kvCache.start();
-        }
-
-        @Override
-        public void notify(Map<String, Value> newValues) {
-            // Cache notifies all paths with "foo" the root path
-            // If you want to watch only "foo" value, you must filter other paths
-            Optional<Value> newValue = newValues.values().stream()
-                    .filter(value -> value.getKey().equals(normalizedKey))
-                    .findAny();
-
-            newValue.ifPresent(value -> {
-                // Values are encoded in key/value store, decode it if needed
-                Optional<String> decodedValue = newValue.get().getValueAsString();
-                decodedValue.ifPresent(v -> listeners.forEach(l -> {
-                    ConfigChangedEvent event = new ConfigChangedEvent(key, group, v, ConfigChangeType.MODIFIED);
-                    l.process(event);
-                }));
-            });
-        }
-
-        private void addListener(ConfigurationListener listener) {
-            this.listeners.add(listener);
-        }
-
-        private void removeListener(ConfigurationListener listener) {
-            this.listeners.remove(listener);
-        }
-    }
-}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationFactory.java b/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationFactory.java
deleted file mode 100644
index 980a156..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationFactory.java
+++ /dev/null
@@ -1,32 +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.configcenter.consul;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.AbstractDynamicConfigurationFactory;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
-
-/**
- * Config center factory for consul
- */
-public class ConsulDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
-    @Override
-    protected DynamicConfiguration createDynamicConfiguration(URL url) {
-        return new ConsulDynamicConfiguration(url);
-    }
-}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory b/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
deleted file mode 100644
index b7a5091..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
+++ /dev/null
@@ -1 +0,0 @@
-consul=org.apache.dubbo.configcenter.consul.ConsulDynamicConfigurationFactory
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-consul/src/test/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationTest.java b/dubbo-spi-configcenter/dubbo-configcenter-consul/src/test/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationTest.java
deleted file mode 100644
index 8ada5fb..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-consul/src/test/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfigurationTest.java
+++ /dev/null
@@ -1,109 +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.configcenter.consul;
-
-import org.apache.dubbo.common.URL;
-
-import com.google.common.net.HostAndPort;
-import com.orbitz.consul.Consul;
-import com.orbitz.consul.KeyValueClient;
-import com.orbitz.consul.cache.KVCache;
-import com.orbitz.consul.model.kv.Value;
-import com.pszymczyk.consul.ConsulProcess;
-import com.pszymczyk.consul.ConsulStarterBuilder;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import java.util.Optional;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-/**
- *
- */
-public class ConsulDynamicConfigurationTest {
-
-    private static ConsulProcess consul;
-    private static URL configCenterUrl;
-    private static ConsulDynamicConfiguration configuration;
-
-    private static Consul client;
-    private static KeyValueClient kvClient;
-
-    @BeforeAll
-    public static void setUp() throws Exception {
-        consul = ConsulStarterBuilder.consulStarter()
-                .build()
-                .start();
-        configCenterUrl = URL.valueOf("consul://localhost:" + consul.getHttpPort());
-
-        configuration = new ConsulDynamicConfiguration(configCenterUrl);
-        client = Consul.builder().withHostAndPort(HostAndPort.fromParts("localhost", consul.getHttpPort())).build();
-        kvClient = client.keyValueClient();
-    }
-
-    @AfterAll
-    public static void tearDown() throws Exception {
-        consul.close();
-        configuration.close();
-    }
-
-    @Test
-    public void testGetConfig() {
-        kvClient.putValue("/dubbo/config/dubbo/foo", "bar");
-        // test equals
-        assertEquals("bar", configuration.getConfig("foo", "dubbo"));
-        // test does not block
-        assertEquals("bar", configuration.getConfig("foo", "dubbo"));
-        Assertions.assertNull(configuration.getConfig("not-exist", "dubbo"));
-    }
-
-    @Test
-    public void testAddListener() {
-        KVCache cache = KVCache.newCache(kvClient, "/dubbo/config/dubbo/foo");
-        cache.addListener(newValues -> {
-            // Cache notifies all paths with "foo" the root path
-            // If you want to watch only "foo" value, you must filter other paths
-            Optional<Value> newValue = newValues.values().stream()
-                    .filter(value -> value.getKey().equals("foo"))
-                    .findAny();
-
-            newValue.ifPresent(value -> {
-                // Values are encoded in key/value store, decode it if needed
-                Optional<String> decodedValue = newValue.get().getValueAsString();
-                decodedValue.ifPresent(v -> System.out.println(String.format("Value is: %s", v))); //prints "bar"
-            });
-        });
-        cache.start();
-
-        kvClient.putValue("/dubbo/config/dubbo/foo", "new-value");
-        kvClient.putValue("/dubbo/config/dubbo/foo/sub", "sub-value");
-        kvClient.putValue("/dubbo/config/dubbo/foo/sub2", "sub-value2");
-        kvClient.putValue("/dubbo/config/foo", "parent-value");
-
-        System.out.println(kvClient.getKeys("/dubbo/config/dubbo/foo"));
-        System.out.println(kvClient.getKeys("/dubbo/config"));
-        System.out.println(kvClient.getValues("/dubbo/config/dubbo/foo"));
-    }
-
-    @Test
-    public void testGetConfigKeys() {
-
-    }
-}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml b/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml
deleted file mode 100644
index 9fcc2fe..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-etcd/pom.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?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">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-configcenter</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>dubbo-configcenter-etcd</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The etcd implementation of the config-center api</description>
-
-    <properties>
-        <skipIntegrationTests>true</skipIntegrationTests>
-    </properties>
-
-    <dependencies>
-        <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>
-
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-common</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-etcd3</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <skipTests>${skipIntegrationTests}</skipTests>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-</project>
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java b/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java
deleted file mode 100644
index f686e86..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java
+++ /dev/null
@@ -1,197 +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.configcenter.support.etcd;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
-import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
-import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.remoting.etcd.StateListener;
-import org.apache.dubbo.remoting.etcd.jetcd.JEtcdClient;
-
-import com.google.protobuf.ByteString;
-import io.etcd.jetcd.api.Event;
-import io.etcd.jetcd.api.WatchCancelRequest;
-import io.etcd.jetcd.api.WatchCreateRequest;
-import io.etcd.jetcd.api.WatchGrpc;
-import io.etcd.jetcd.api.WatchRequest;
-import io.etcd.jetcd.api.WatchResponse;
-import io.grpc.ManagedChannel;
-import io.grpc.stub.StreamObserver;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.dubbo.common.config.configcenter.Constants.CONFIG_NAMESPACE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
-
-/**
- * The etcd implementation of {@link DynamicConfiguration}
- */
-public class EtcdDynamicConfiguration implements DynamicConfiguration {
-
-    /**
-     * The final root path would be: /$NAME_SPACE/config
-     */
-    private String rootPath;
-
-    /**
-     * The etcd client
-     */
-    private final JEtcdClient etcdClient;
-
-    /**
-     * The map store the key to {@link EtcdConfigWatcher} mapping
-     */
-    private final ConcurrentMap<ConfigurationListener, EtcdConfigWatcher> watchListenerMap;
-
-    EtcdDynamicConfiguration(URL url) {
-        rootPath = PATH_SEPARATOR + url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP) + "/config";
-        etcdClient = new JEtcdClient(url);
-        etcdClient.addStateListener(state -> {
-            if (state == StateListener.CONNECTED) {
-                try {
-                    recover();
-                } catch (Exception e) {
-                    // ignore
-                }
-            }
-        });
-        watchListenerMap = new ConcurrentHashMap<>();
-    }
-
-    @Override
-    public void addListener(String key, String group, ConfigurationListener listener) {
-        if (watchListenerMap.get(listener) == null) {
-            EtcdConfigWatcher watcher = new EtcdConfigWatcher(key, group, listener);
-            watchListenerMap.put(listener, watcher);
-            watcher.watch();
-        }
-    }
-
-    @Override
-    public void removeListener(String key, String group, ConfigurationListener listener) {
-        EtcdConfigWatcher watcher = watchListenerMap.get(listener);
-        watcher.cancelWatch();
-    }
-
-    @Override
-    public String getConfig(String key, String group, long timeout) throws IllegalStateException {
-        return (String) getInternalProperty(convertKey(group, key));
-    }
-
-//    @Override
-//    public String getConfigs(String key, String group, long timeout) throws IllegalStateException {
-//        if (StringUtils.isEmpty(group)) {
-//            group = DEFAULT_GROUP;
-//        }
-//        return (String) getInternalProperty(convertKey(group, key));
-//    }
-
-    @Override
-    public Object getInternalProperty(String key) {
-        return etcdClient.getKVValue(key);
-    }
-
-    private String buildPath(String group) {
-        String actualGroup = StringUtils.isEmpty(group) ? DEFAULT_GROUP : group;
-        return rootPath + PATH_SEPARATOR + actualGroup;
-    }
-
-    private String convertKey(String group, String key) {
-        return buildPath(group) + PATH_SEPARATOR + key;
-    }
-
-    private void recover() {
-        for (EtcdConfigWatcher watcher : watchListenerMap.values()) {
-            watcher.watch();
-        }
-    }
-
-    public class EtcdConfigWatcher implements StreamObserver<WatchResponse> {
-
-        private ConfigurationListener listener;
-        protected WatchGrpc.WatchStub watchStub;
-        private StreamObserver<WatchRequest> observer;
-        protected long watchId;
-        private ManagedChannel channel;
-
-        private final String key;
-
-        private final String group;
-
-        private String normalizedKey;
-
-        public EtcdConfigWatcher(String key, String group, ConfigurationListener listener) {
-            this.key = key;
-            this.group = group;
-            this.normalizedKey = convertKey(group, key);
-            this.listener = listener;
-            this.channel = etcdClient.getChannel();
-        }
-
-        @Override
-        public void onNext(WatchResponse watchResponse) {
-            this.watchId = watchResponse.getWatchId();
-            for (Event etcdEvent : watchResponse.getEventsList()) {
-                ConfigChangeType type = ConfigChangeType.MODIFIED;
-                if (etcdEvent.getType() == Event.EventType.DELETE) {
-                    type = ConfigChangeType.DELETED;
-                }
-                ConfigChangedEvent event = new ConfigChangedEvent(key, group,
-                        etcdEvent.getKv().getValue().toString(UTF_8), type);
-                listener.process(event);
-            }
-        }
-
-        @Override
-        public void onError(Throwable throwable) {
-            // ignore
-        }
-
-        @Override
-        public void onCompleted() {
-            // ignore
-        }
-
-        public long getWatchId() {
-            return watchId;
-        }
-
-        private void watch() {
-            watchStub = WatchGrpc.newStub(channel);
-            observer = watchStub.watch(this);
-            WatchCreateRequest.Builder builder = WatchCreateRequest.newBuilder()
-                    .setKey(ByteString.copyFromUtf8(normalizedKey))
-                    .setProgressNotify(true);
-            WatchRequest req = WatchRequest.newBuilder().setCreateRequest(builder).build();
-            observer.onNext(req);
-        }
-
-        private void cancelWatch() {
-            WatchCancelRequest watchCancelRequest =
-                    WatchCancelRequest.newBuilder().setWatchId(watchId).build();
-            WatchRequest cancelRequest = WatchRequest.newBuilder()
-                    .setCancelRequest(watchCancelRequest).build();
-            observer.onNext(cancelRequest);
-        }
-    }
-}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationFactory.java b/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationFactory.java
deleted file mode 100644
index 269cee6..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationFactory.java
+++ /dev/null
@@ -1,33 +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.configcenter.support.etcd;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.AbstractDynamicConfigurationFactory;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
-
-/**
- * The etcd implementation of {@link AbstractDynamicConfigurationFactory}
- */
-public class EtcdDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
-
-    @Override
-    protected DynamicConfiguration createDynamicConfiguration(URL url) {
-        return new EtcdDynamicConfiguration(url);
-    }
-}
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory b/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
deleted file mode 100644
index d84b1ae..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
+++ /dev/null
@@ -1 +0,0 @@
-etcd=org.apache.dubbo.configcenter.support.etcd.EtcdDynamicConfigurationFactory
\ No newline at end of file
diff --git a/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/test/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationTest.java b/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/test/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationTest.java
deleted file mode 100644
index 86dd306..0000000
--- a/dubbo-spi-configcenter/dubbo-configcenter-etcd/src/test/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfigurationTest.java
+++ /dev/null
@@ -1,154 +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.configcenter.support.etcd;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
-import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
-import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
-
-import io.etcd.jetcd.ByteSequence;
-import io.etcd.jetcd.Client;
-import io.etcd.jetcd.launcher.EtcdCluster;
-import io.etcd.jetcd.launcher.EtcdClusterFactory;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.net.URI;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.dubbo.remoting.etcd.Constants.SESSION_TIMEOUT_KEY;
-
-/**
- * Unit test for etcd config center support
- * Integrate with https://github.com/etcd-io/jetcd#launcher
- */
-public class EtcdDynamicConfigurationTest {
-
-    private static EtcdDynamicConfiguration config;
-
-    public EtcdCluster etcdCluster = EtcdClusterFactory.buildCluster(getClass().getSimpleName(), 3, false, false);
-
-    private static Client client;
-
-    @Test
-    public void testGetConfig() {
-
-        put("/dubbo/config/org.apache.dubbo.etcd.testService/configurators", "hello");
-        put("/dubbo/config/test/dubbo.properties", "aaa=bbb");
-        Assert.assertEquals("hello", config.getConfig("org.apache.dubbo.etcd.testService.configurators", DynamicConfiguration.DEFAULT_GROUP));
-        Assert.assertEquals("aaa=bbb", config.getConfig("dubbo.properties", "test"));
-    }
-
-    @Test
-    public void testAddListener() throws Exception {
-        CountDownLatch latch = new CountDownLatch(4);
-        TestListener listener1 = new TestListener(latch);
-        TestListener listener2 = new TestListener(latch);
-        TestListener listener3 = new TestListener(latch);
-        TestListener listener4 = new TestListener(latch);
-        config.addListener("AService.configurators", listener1);
-        config.addListener("AService.configurators", listener2);
-        config.addListener("testapp.tagrouters", listener3);
-        config.addListener("testapp.tagrouters", listener4);
-
-        put("/dubbo/config/AService/configurators", "new value1");
-        Thread.sleep(200);
-        put("/dubbo/config/testapp/tagrouters", "new value2");
-        Thread.sleep(200);
-        put("/dubbo/config/testapp", "new value3");
-
-        Thread.sleep(1000);
-
-        Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
-        Assert.assertEquals(1, listener1.getCount("/dubbo/config/AService/configurators"));
-        Assert.assertEquals(1, listener2.getCount("/dubbo/config/AService/configurators"));
-        Assert.assertEquals(1, listener3.getCount("/dubbo/config/testapp/tagrouters"));
-        Assert.assertEquals(1, listener4.getCount("/dubbo/config/testapp/tagrouters"));
-
-        Assert.assertEquals("new value1", listener1.getValue());
-        Assert.assertEquals("new value1", listener2.getValue());
-        Assert.assertEquals("new value2", listener3.getValue());
-        Assert.assertEquals("new value2", listener4.getValue());
-    }
-
-    private class TestListener implements ConfigurationListener {
-        private CountDownLatch latch;
-        private String value;
-        private Map<String, Integer> countMap = new HashMap<>();
-
-        public TestListener(CountDownLatch latch) {
-            this.latch = latch;
-        }
-
-        @Override
-        public void process(ConfigChangedEvent event) {
-            Integer count = countMap.computeIfAbsent(event.getKey(), k -> 0);
-            countMap.put(event.getKey(), ++count);
-            value = event.getContent();
-            latch.countDown();
-        }
-
-        public int getCount(String key) {
-            return countMap.get(key);
-        }
-
-        public String getValue() {
-            return value;
-        }
-    }
-
-    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.");
-        }
-    }
-
-    @Before
-    public void setUp() {
-
-        etcdCluster.start();
-
-        client = Client.builder().endpoints(etcdCluster.getClientEndpoints()).build();
-
-        List<URI> clientEndPoints = etcdCluster.getClientEndpoints();
-
-        String ipAddress = clientEndPoints.get(0).getHost() + ":" + clientEndPoints.get(0).getPort();
-        String urlForDubbo = "etcd3://" + ipAddress + "/org.apache.dubbo.etcd.testService";
-
-        // timeout in 15 seconds.
-        URL url = URL.valueOf(urlForDubbo)
-                .addParameter(SESSION_TIMEOUT_KEY, 15000);
-        config = new EtcdDynamicConfiguration(url);
-    }
-
-    @After
-    public void tearDown() {
-        etcdCluster.close();
-    }
-
-}
diff --git a/dubbo-spi-configcenter/pom.xml b/dubbo-spi-configcenter/pom.xml
deleted file mode 100644
index 458b80b..0000000
--- a/dubbo-spi-configcenter/pom.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<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/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.dubbo.spi</groupId>
-        <artifactId>dubbo-spi-extensions</artifactId>
-        <version>${revision}</version>
-    </parent>
-    <artifactId>dubbo-spi-configcenter</artifactId>
-    <packaging>pom</packaging>
-    <name>${project.artifactId}</name>
-    <description>The service config-center module of the Dubbo project</description>
-    <properties>
-        <skip_maven_deploy>true</skip_maven_deploy>
-    </properties>
-
-    <modules>
-        <module>dubbo-configcenter-consul</module>
-        <module>dubbo-configcenter-etcd</module>
-    </modules>
-</project>
diff --git a/dubbo-spi-container/dubbo-container-log4j/src/main/java/org/apache/dubbo/container/log4j/Log4jContainer.java b/dubbo-spi-container/dubbo-container-log4j/src/main/java/org/apache/dubbo/container/log4j/Log4jContainer.java
deleted file mode 100644
index 4ba9c1c..0000000
--- a/dubbo-spi-container/dubbo-container-log4j/src/main/java/org/apache/dubbo/container/log4j/Log4jContainer.java
+++ /dev/null
@@ -1,103 +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.container.log4j;
-
-import org.apache.dubbo.common.config.ConfigurationUtils;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.container.Container;
-
-import org.apache.log4j.Appender;
-import org.apache.log4j.FileAppender;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.PropertyConfigurator;
-
-import java.util.Enumeration;
-import java.util.Properties;
-
-/**
- * Log4jContainer. (SPI, Singleton, ThreadSafe)
- *
- * The container class implementation for Log4j
- */
-public class Log4jContainer implements Container {
-
-    public static final String LOG4J_FILE = "dubbo.log4j.file";
-
-    public static final String LOG4J_LEVEL = "dubbo.log4j.level";
-
-    public static final String LOG4J_SUBDIRECTORY = "dubbo.log4j.subdirectory";
-
-    public static final String DEFAULT_LOG4J_LEVEL = "ERROR";
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public void start() {
-        String file = ConfigurationUtils.getProperty(LOG4J_FILE);
-        if (file != null && file.length() > 0) {
-            String level = ConfigurationUtils.getProperty(LOG4J_LEVEL);
-            if (StringUtils.isEmpty(level)) {
-                level = DEFAULT_LOG4J_LEVEL;
-            }
-            Properties properties = new Properties();
-            properties.setProperty("log4j.rootLogger", level + ",application");
-            properties.setProperty("log4j.appender.application", "org.apache.log4j.DailyRollingFileAppender");
-            properties.setProperty("log4j.appender.application.File", file);
-            properties.setProperty("log4j.appender.application.Append", "true");
-            properties.setProperty("log4j.appender.application.DatePattern", "'.'yyyy-MM-dd");
-            properties.setProperty("log4j.appender.application.layout", "org.apache.log4j.PatternLayout");
-            properties.setProperty("log4j.appender.application.layout.ConversionPattern", "%d [%t] %-5p %C{6} (%F:%L) - %m%n");
-            PropertyConfigurator.configure(properties);
-        }
-        String subdirectory = ConfigurationUtils.getProperty(LOG4J_SUBDIRECTORY);
-        if (subdirectory != null && subdirectory.length() > 0) {
-            Enumeration<org.apache.log4j.Logger> ls = LogManager.getCurrentLoggers();
-            while (ls.hasMoreElements()) {
-                org.apache.log4j.Logger l = ls.nextElement();
-                if (l != null) {
-                    Enumeration<Appender> as = l.getAllAppenders();
-                    while (as.hasMoreElements()) {
-                        Appender a = as.nextElement();
-                        if (a instanceof FileAppender) {
-                            FileAppender fa = (FileAppender) a;
-                            String f = fa.getFile();
-                            if (f != null && f.length() > 0) {
-                                int i = f.replace('\\', '/').lastIndexOf('/');
-                                String path;
-                                if (i == -1) {
-                                    path = subdirectory;
-                                } else {
-                                    path = f.substring(0, i);
-                                    if (!path.endsWith(subdirectory)) {
-                                        path = path + "/" + subdirectory;
-                                    }
-                                    f = f.substring(i + 1);
-                                }
-                                fa.setFile(path + "/" + f);
-                                fa.activateOptions();
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public void stop() {
-    }
-
-}
diff --git a/dubbo-spi-container/dubbo-container-log4j/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.container.Container b/dubbo-spi-container/dubbo-container-log4j/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.container.Container
deleted file mode 100644
index 0b4c162..0000000
--- a/dubbo-spi-container/dubbo-container-log4j/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.container.Container
+++ /dev/null
@@ -1 +0,0 @@
-log4j=org.apache.dubbo.container.log4j.Log4jContainer
\ No newline at end of file
diff --git a/dubbo-spi-container/dubbo-container-log4j/src/test/java/org/apache/dubbo/container/log4j/Log4jContainerTest.java b/dubbo-spi-container/dubbo-container-log4j/src/test/java/org/apache/dubbo/container/log4j/Log4jContainerTest.java
deleted file mode 100644
index b75b305..0000000
--- a/dubbo-spi-container/dubbo-container-log4j/src/test/java/org/apache/dubbo/container/log4j/Log4jContainerTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.container.log4j;
-
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.container.Container;
-
-import org.junit.jupiter.api.Test;
-
-/**
- * StandaloneContainerTest
- */
-public class Log4jContainerTest {
-
-    @Test
-    public void testContainer() {
-        Log4jContainer container = (Log4jContainer) ExtensionLoader.getExtensionLoader(Container.class).getExtension("log4j");
-        container.start();
-        container.stop();
-    }
-
-}
\ No newline at end of file
diff --git a/dubbo-spi-container/dubbo-container-logback/pom.xml b/dubbo-spi-container/dubbo-container-logback/pom.xml
deleted file mode 100644
index d4437eb..0000000
--- a/dubbo-spi-container/dubbo-container-logback/pom.xml
+++ /dev/null
@@ -1,42 +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.
-  -->
-<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/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-container</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
-    </parent>
-    <artifactId>dubbo-container-logback</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The logback container module of dubbo project</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-container-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>ch.qos.logback</groupId>
-            <artifactId>logback-classic</artifactId>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/dubbo-spi-container/dubbo-container-logback/src/main/java/org/apache/dubbo/container/logback/LogbackContainer.java b/dubbo-spi-container/dubbo-container-logback/src/main/java/org/apache/dubbo/container/logback/LogbackContainer.java
deleted file mode 100644
index 430e2e2..0000000
--- a/dubbo-spi-container/dubbo-container-logback/src/main/java/org/apache/dubbo/container/logback/LogbackContainer.java
+++ /dev/null
@@ -1,108 +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.container.logback;
-
-import org.apache.dubbo.common.utils.ConfigUtils;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.container.Container;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.rolling.RollingFileAppender;
-import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
-import org.slf4j.LoggerFactory;
-
-/**
- * LogbackContainer. (SPI, Singleton, ThreadSafe)
- *
- * The container class implementation for Logback
- */
-public class LogbackContainer implements Container {
-
-    public static final String LOGBACK_FILE = "dubbo.logback.file";
-
-    public static final String LOGBACK_LEVEL = "dubbo.logback.level";
-
-    public static final String LOGBACK_MAX_HISTORY = "dubbo.logback.maxhistory";
-
-    public static final String DEFAULT_LOGBACK_LEVEL = "ERROR";
-
-    @Override
-    public void start() {
-        String file = ConfigUtils.getProperty(LOGBACK_FILE);
-        if (file != null && file.length() > 0) {
-            String level = ConfigUtils.getProperty(LOGBACK_LEVEL);
-            if (StringUtils.isEmpty(level)) {
-                level = DEFAULT_LOGBACK_LEVEL;
-            }
-            // maxHistory=0 Infinite history
-            int maxHistory = StringUtils.parseInteger(ConfigUtils.getProperty(LOGBACK_MAX_HISTORY));
-
-            doInitializer(file, level, maxHistory);
-        }
-    }
-
-    @Override
-    public void stop() {
-    }
-
-    /**
-     * Initializer logback
-     *
-     * @param file
-     * @param level
-     * @param maxHistory
-     */
-    private void doInitializer(String file, String level, int maxHistory) {
-        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
-        Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
-        rootLogger.detachAndStopAllAppenders();
-
-        // appender
-        RollingFileAppender<ILoggingEvent> fileAppender = new RollingFileAppender<ILoggingEvent>();
-        fileAppender.setContext(loggerContext);
-        fileAppender.setName("application");
-        fileAppender.setFile(file);
-        fileAppender.setAppend(true);
-
-        // policy
-        TimeBasedRollingPolicy<ILoggingEvent> policy = new TimeBasedRollingPolicy<ILoggingEvent>();
-        policy.setContext(loggerContext);
-        policy.setMaxHistory(maxHistory);
-        policy.setFileNamePattern(file + ".%d{yyyy-MM-dd}");
-        policy.setParent(fileAppender);
-        policy.start();
-        fileAppender.setRollingPolicy(policy);
-
-        // encoder
-        PatternLayoutEncoder encoder = new PatternLayoutEncoder();
-        encoder.setContext(loggerContext);
-        encoder.setPattern("%date [%thread] %-5level %logger (%file:%line\\) - %msg%n");
-        encoder.start();
-        fileAppender.setEncoder(encoder);
-
-        fileAppender.start();
-
-        rootLogger.addAppender(fileAppender);
-        rootLogger.setLevel(Level.toLevel(level));
-        rootLogger.setAdditive(false);
-    }
-
-}
diff --git a/dubbo-spi-container/dubbo-container-logback/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.container.Container b/dubbo-spi-container/dubbo-container-logback/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.container.Container
deleted file mode 100644
index 04c4eaa..0000000
--- a/dubbo-spi-container/dubbo-container-logback/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.container.Container
+++ /dev/null
@@ -1 +0,0 @@
-logback=org.apache.dubbo.container.logback.LogbackContainer
\ No newline at end of file
diff --git a/dubbo-spi-container/dubbo-container-logback/src/test/java/org/apache/dubbo/container/logback/LogbackContainerTest.java b/dubbo-spi-container/dubbo-container-logback/src/test/java/org/apache/dubbo/container/logback/LogbackContainerTest.java
deleted file mode 100644
index d82e8a4..0000000
--- a/dubbo-spi-container/dubbo-container-logback/src/test/java/org/apache/dubbo/container/logback/LogbackContainerTest.java
+++ /dev/null
@@ -1,47 +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.container.logback;
-
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.container.Container;
-
-import org.junit.jupiter.api.Test;
-
-/**
- * StandaloneContainerTest
- */
-public class LogbackContainerTest {
-
-    private static final Logger logger = LoggerFactory.getLogger(LogbackContainerTest.class);
-
-    @Test
-    public void testContainer() {
-        LogbackContainer container = (LogbackContainer) ExtensionLoader.getExtensionLoader(Container.class)
-                .getExtension("logback");
-        container.start();
-
-        logger.debug("Test debug:" + this.getClass().getName());
-        logger.warn("Test warn:" + this.getClass().getName());
-        logger.info("Test info:" + this.getClass().getName());
-        logger.error("Test error:" + this.getClass().getName());
-
-        container.stop();
-    }
-
-}
\ No newline at end of file
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml b/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml
deleted file mode 100644
index 4c3cc36..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-consul/pom.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?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>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-metadata</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>dubbo-metadata-report-consul</artifactId>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-metadata-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.ecwid.consul</groupId>
-            <artifactId>consul-api</artifactId>
-        </dependency>
-    </dependencies>
-
-</project>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java b/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java
deleted file mode 100644
index c1e0a30..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java
+++ /dev/null
@@ -1,135 +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.metadata.store.consul;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.metadata.report.identifier.BaseMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
-import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
-import org.apache.dubbo.metadata.report.support.AbstractMetadataReport;
-import org.apache.dubbo.rpc.RpcException;
-
-import com.ecwid.consul.v1.ConsulClient;
-import com.ecwid.consul.v1.Response;
-import com.ecwid.consul.v1.kv.model.GetValue;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * metadata report impl for consul
- */
-public class ConsulMetadataReport extends AbstractMetadataReport {
-    private static final Logger logger = LoggerFactory.getLogger(ConsulMetadataReport.class);
-    private static final int DEFAULT_PORT = 8500;
-
-    private ConsulClient client;
-
-    public ConsulMetadataReport(URL url) {
-        super(url);
-
-        String host = url.getHost();
-        int port = url.getPort() != 0 ? url.getPort() : DEFAULT_PORT;
-        client = new ConsulClient(host, port);
-    }
-
-    @Override
-    protected void doStoreProviderMetadata(MetadataIdentifier providerMetadataIdentifier, String serviceDefinitions) {
-        this.storeMetadata(providerMetadataIdentifier, serviceDefinitions);
-    }
-
-    @Override
-    protected void doStoreConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, String value) {
-        this.storeMetadata(consumerMetadataIdentifier, value);
-    }
-
-    @Override
-    protected void doSaveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier, URL url) {
-        this.storeMetadata(serviceMetadataIdentifier, URL.encode(url.toFullString()));
-    }
-
-    @Override
-    protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier) {
-        this.deleteMetadata(serviceMetadataIdentifier);
-    }
-
-    @Override
-    protected List<String> doGetExportedURLs(ServiceMetadataIdentifier metadataIdentifier) {
-        //todo encode and decode
-        String content = getMetadata(metadataIdentifier);
-        if (StringUtils.isEmpty(content)) {
-            return Collections.emptyList();
-        }
-        return new ArrayList<String>(Arrays.asList(URL.decode(content)));
-    }
-
-    @Override
-    protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr) {
-        this.storeMetadata(subscriberMetadataIdentifier, urlListStr);
-    }
-
-    @Override
-    protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) {
-        return getMetadata(subscriberMetadataIdentifier);
-    }
-
-    private void storeMetadata(BaseMetadataIdentifier identifier, String v) {
-        try {
-            client.setKVValue(identifier.getUniqueKey(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);
-        }
-    }
-
-    private void deleteMetadata(BaseMetadataIdentifier identifier) {
-        try {
-            client.deleteKVValue(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
-        } catch (Throwable t) {
-            logger.error("Failed to delete " + identifier + " from consul , cause: " + t.getMessage(), t);
-            throw new RpcException("Failed to delete " + identifier + " from consul , cause: " + t.getMessage(), t);
-        }
-    }
-
-    private String getMetadata(BaseMetadataIdentifier identifier) {
-        try {
-            Response<GetValue> value = client.getKVValue(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
-            //FIXME CHECK
-            if (value != null && value.getValue() != null) {
-                //todo check decode value and value diff
-                return value.getValue().getValue();
-            }
-            return null;
-        } catch (Throwable t) {
-            logger.error("Failed to get " + identifier + " from consul , cause: " + t.getMessage(), t);
-            throw new RpcException("Failed to get " + identifier + " from consul , cause: " + t.getMessage(), t);
-        }
-    }
-
-    @Override
-    public String getServiceDefinition(MetadataIdentifier metadataIdentifier) {
-        return getMetadata(metadataIdentifier);
-    }
-}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReportFactory.java b/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReportFactory.java
deleted file mode 100644
index 1d1f5bb..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReportFactory.java
+++ /dev/null
@@ -1,32 +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.metadata.store.consul;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.metadata.report.MetadataReport;
-import org.apache.dubbo.metadata.report.support.AbstractMetadataReportFactory;
-
-/**
- * metadata report factory impl for consul
- */
-public class ConsulMetadataReportFactory extends AbstractMetadataReportFactory {
-    @Override
-    protected MetadataReport createMetadataReport(URL url) {
-        return new ConsulMetadataReport(url);
-    }
-}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory b/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
deleted file mode 100644
index 1f27535..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
+++ /dev/null
@@ -1 +0,0 @@
-consul=org.apache.dubbo.metadata.store.consul.ConsulMetadataReportFactory
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml b/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml
deleted file mode 100644
index 675257f..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-etcd/pom.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?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>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-metadata</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>dubbo-metadata-report-etcd</artifactId>
-
-    <properties>
-        <skipIntegrationTests>true</skipIntegrationTests>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-metadata-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>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <skipTests>${skipIntegrationTests}</skipTests>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-</project>
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java
deleted file mode 100644
index a80c6e8..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java
+++ /dev/null
@@ -1,150 +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.
- */
-
-/*
- * 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.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.metadata.report.identifier.BaseMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
-import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
-import org.apache.dubbo.metadata.report.support.AbstractMetadataReport;
-import org.apache.dubbo.remoting.etcd.jetcd.JEtcdClient;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
-
-/**
- * Report Metadata to Etcd
- */
-public class EtcdMetadataReport extends AbstractMetadataReport {
-
-    private final static Logger logger = LoggerFactory.getLogger(EtcdMetadataReport.class);
-
-    private final String root;
-
-    /**
-     * The etcd client
-     */
-    private final JEtcdClient etcdClient;
-
-    public EtcdMetadataReport(URL url) {
-        super(url);
-        if (url.isAnyHost()) {
-            throw new IllegalStateException("registry address == null");
-        }
-        String group = url.getParameter(GROUP_KEY, DEFAULT_ROOT);
-        if (!group.startsWith(PATH_SEPARATOR)) {
-            group = PATH_SEPARATOR + group;
-        }
-        this.root = group;
-        etcdClient = new JEtcdClient(url);
-    }
-
-    @Override
-    protected void doStoreProviderMetadata(MetadataIdentifier providerMetadataIdentifier, String serviceDefinitions) {
-        storeMetadata(providerMetadataIdentifier, serviceDefinitions);
-    }
-
-    @Override
-    protected void doStoreConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, String value) {
-        storeMetadata(consumerMetadataIdentifier, value);
-    }
-
-    @Override
-    protected void doSaveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier, URL url) {
-        String key = getNodeKey(serviceMetadataIdentifier);
-        if (!etcdClient.put(key, URL.encode(url.toFullString()))) {
-            logger.error("Failed to put " + serviceMetadataIdentifier + " to etcd, value: " + url);
-        }
-    }
-
-    @Override
-    protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier) {
-        etcdClient.delete(getNodeKey(serviceMetadataIdentifier));
-    }
-
-    @Override
-    protected List<String> doGetExportedURLs(ServiceMetadataIdentifier metadataIdentifier) {
-        String content = etcdClient.getKVValue(getNodeKey(metadataIdentifier));
-        if (StringUtils.isEmpty(content)) {
-            return Collections.emptyList();
-        }
-        return new ArrayList<String>(Arrays.asList(URL.decode(content)));
-    }
-
-    @Override
-    protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr) {
-        String key = getNodeKey(subscriberMetadataIdentifier);
-        if (!etcdClient.put(key, urlListStr)) {
-            logger.error("Failed to put " + subscriberMetadataIdentifier + " to etcd, value: " + urlListStr);
-        }
-    }
-
-    @Override
-    protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) {
-        return etcdClient.getKVValue(getNodeKey(subscriberMetadataIdentifier));
-    }
-
-    @Override
-    public String getServiceDefinition(MetadataIdentifier metadataIdentifier) {
-        return etcdClient.getKVValue(getNodeKey(metadataIdentifier));
-    }
-
-    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 getNodeKey(BaseMetadataIdentifier identifier) {
-        return toRootDir() + identifier.getUniqueKey(KeyTypeEnum.PATH);
-    }
-
-    String toRootDir() {
-        if (root.equals(PATH_SEPARATOR)) {
-            return root;
-        }
-        return root + PATH_SEPARATOR;
-    }
-}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportFactory.java b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportFactory.java
deleted file mode 100644
index 3bb9e92..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportFactory.java
+++ /dev/null
@@ -1,50 +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.
- */
-
-/*
- * 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.report.MetadataReport;
-import org.apache.dubbo.metadata.report.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-spi-metadata/dubbo-metadata-report-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
deleted file mode 100644
index 9a3c98c..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
+++ /dev/null
@@ -1 +0,0 @@
-etcd=org.apache.dubbo.metadata.store.etcd.EtcdMetadataReportFactory
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadata4TstService.java b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadata4TstService.java
deleted file mode 100644
index 1de21ce..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadata4TstService.java
+++ /dev/null
@@ -1,28 +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.metadata.store.etcd;
-
-/**
- * Test interface for Etcd metadata report
- */
-public interface EtcdMetadata4TstService {
-
-    int getCounter();
-
-    void printResult(String var);
-}
diff --git a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportTest.java b/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportTest.java
deleted file mode 100644
index 2d2efd5..0000000
--- a/dubbo-spi-metadata/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportTest.java
+++ /dev/null
@@ -1,259 +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.metadata.store.etcd;
-
-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.report.identifier.MetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
-import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
-
-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.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.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
-import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
-
-/**
- * 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";
-
-        String r = etcdMetadataReport.getServiceDefinition(new MetadataIdentifier(TEST_SERVICE, version, group, "provider", application));
-        Assertions.assertNull(r);
-        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");
-
-        r = etcdMetadataReport.getServiceDefinition(new MetadataIdentifier(TEST_SERVICE, version, group, "provider", application));
-        Assertions.assertNotNull(r);
-    }
-
-    @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\"}");
-    }
-
-    @Test
-    public void testDoSaveMetadata() throws ExecutionException, InterruptedException {
-        String version = "1.0.0";
-        String group = null;
-        String application = "etc-metadata-report-consumer-test";
-        String revision = "90980";
-        String protocol = "xxx";
-        URL url = generateURL(TEST_SERVICE, version, group, application);
-        ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, version,
-                group, "provider", revision, protocol);
-        etcdMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
-
-        CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
-                etcdMetadataReport.getNodeKey(serviceMetadataIdentifier), StandardCharsets.UTF_8));
-        String fileContent = response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
-        Assertions.assertNotNull(fileContent);
-
-        Assertions.assertEquals(fileContent, URL.encode(url.toFullString()));
-    }
-
-    @Test
-    public void testDoRemoveMetadata() throws ExecutionException, InterruptedException {
-        String version = "1.0.0";
-        String group = null;
-        String application = "etc-metadata-report-consumer-test";
-        String revision = "90980";
-        String protocol = "xxx";
-        URL url = generateURL(TEST_SERVICE, version, group, application);
-        ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, version,
-                group, "provider", revision, protocol);
-        etcdMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
-        CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
-                etcdMetadataReport.getNodeKey(serviceMetadataIdentifier), StandardCharsets.UTF_8));
-        String fileContent = response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
-        Assertions.assertNotNull(fileContent);
-
-
-        etcdMetadataReport.doRemoveMetadata(serviceMetadataIdentifier);
-
-        response = etcdClientForTest.getKVClient().get(ByteSequence.from(
-                etcdMetadataReport.getNodeKey(serviceMetadataIdentifier), StandardCharsets.UTF_8));
-        Assertions.assertTrue(response.get().getKvs().isEmpty());
-    }
-
-    @Test
-    public void testDoGetExportedURLs() throws ExecutionException, InterruptedException {
-        String version = "1.0.0";
-        String group = null;
-        String application = "etc-metadata-report-consumer-test";
-        String revision = "90980";
-        String protocol = "xxx";
-        URL url = generateURL(TEST_SERVICE, version, group, application);
-        ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, version,
-                group, "provider", revision, protocol);
-        etcdMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
-
-        List<String> r = etcdMetadataReport.doGetExportedURLs(serviceMetadataIdentifier);
-        Assertions.assertTrue(r.size() == 1);
-
-        String fileContent = r.get(0);
-        Assertions.assertNotNull(fileContent);
-
-        Assertions.assertEquals(fileContent, url.toFullString());
-    }
-
-    @Test
-    public void testDoSaveSubscriberData() throws ExecutionException, InterruptedException {
-        String version = "1.0.0";
-        String group = null;
-        String application = "etc-metadata-report-consumer-test";
-        String revision = "90980";
-        String protocol = "xxx";
-        URL url = generateURL(TEST_SERVICE, version, group, application);
-        SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
-        Gson gson = new Gson();
-        String r = gson.toJson(Arrays.asList(url));
-        etcdMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
-
-        CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
-                etcdMetadataReport.getNodeKey(subscriberMetadataIdentifier), StandardCharsets.UTF_8));
-        String fileContent = response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
-        Assertions.assertNotNull(fileContent);
-
-        Assertions.assertEquals(fileContent, r);
-    }
-
-    @Test
-    public void testDoGetSubscribedURLs() throws ExecutionException, InterruptedException {
-        String version = "1.0.0";
-        String group = null;
-        String application = "etc-metadata-report-consumer-test";
-        String revision = "90980";
-        String protocol = "xxx";
-        URL url = generateURL(TEST_SERVICE, version, group, application);
-        SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
-        Gson gson = new Gson();
-        String r = gson.toJson(Arrays.asList(url));
-        etcdMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
-
-        CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
-                etcdMetadataReport.getNodeKey(subscriberMetadataIdentifier), StandardCharsets.UTF_8));
-        String fileContent = etcdMetadataReport.doGetSubscribedURLs(subscriberMetadataIdentifier);
-        Assertions.assertNotNull(fileContent);
-
-        Assertions.assertEquals(fileContent, r);
-    }
-
-    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, 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 URL generateURL(String interfaceName, String version, String group, String application) {
-        URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":8989/" + interfaceName +
-                "?paramTest=etcdTest&version=" + version + "&application="
-                + application + (group == null ? "" : "&group=" + group));
-        return url;
-    }
-
-    private MetadataIdentifier storeConsumer(EtcdMetadataReport etcdMetadataReport, String interfaceName,
-                                             String version, String group, String application) throws InterruptedException {
-
-        MetadataIdentifier consumerIdentifier = new MetadataIdentifier(interfaceName, version, group, 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-spi-registry/dubbo-registry-consul/pom.xml b/dubbo-spi-registry/dubbo-registry-consul/pom.xml
deleted file mode 100644
index 43b3180..0000000
--- a/dubbo-spi-registry/dubbo-registry-consul/pom.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?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-registry</artifactId>
-        <groupId>org.apache.dubbo</groupId>
-        <version>3.0.0-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>dubbo-registry-consul</artifactId>
-
-    <properties>
-        <skipIntegrationTests>true</skipIntegrationTests>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.ecwid.consul</groupId>
-            <artifactId>consul-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.pszymczyk.consul</groupId>
-            <artifactId>embedded-consul</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <skipTests>${skipIntegrationTests}</skipTests>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>
diff --git a/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/AbstractConsulRegistry.java b/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/AbstractConsulRegistry.java
deleted file mode 100644
index 8a5e6d7..0000000
--- a/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/AbstractConsulRegistry.java
+++ /dev/null
@@ -1,39 +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.registry.consul;
-
-/**
- * @author cvictory ON 2019-08-02
- */
-public class AbstractConsulRegistry {
-
-    static final String SERVICE_TAG = "dubbo";
-    static final String URL_META_KEY = "url";
-    static final String WATCH_TIMEOUT = "consul-watch-timeout";
-    static final String CHECK_PASS_INTERVAL = "consul-check-pass-interval";
-    static final String DEREGISTER_AFTER = "consul-deregister-critical-service-after";
-
-    static final int DEFAULT_PORT = 8500;
-    // default watch timeout in millisecond
-    static final int DEFAULT_WATCH_TIMEOUT = 60 * 1000;
-    // default time-to-live in millisecond
-    static final long DEFAULT_CHECK_PASS_INTERVAL = 16000L;
-    // default deregister critical server after
-    static final String DEFAULT_DEREGISTER_TIME = "20s";
-
-
-}
diff --git a/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulRegistry.java b/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulRegistry.java
deleted file mode 100644
index d649076..0000000
--- a/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulRegistry.java
+++ /dev/null
@@ -1,360 +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.registry.consul;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.URLBuilder;
-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.common.utils.NamedThreadFactory;
-import org.apache.dubbo.common.utils.UrlUtils;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.support.FailbackRegistry;
-import org.apache.dubbo.rpc.RpcException;
-
-import com.ecwid.consul.v1.ConsulClient;
-import com.ecwid.consul.v1.QueryParams;
-import com.ecwid.consul.v1.Response;
-import com.ecwid.consul.v1.agent.model.NewService;
-import com.ecwid.consul.v1.catalog.CatalogServicesRequest;
-import com.ecwid.consul.v1.health.HealthServicesRequest;
-import com.ecwid.consul.v1.health.model.HealthService;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import static java.util.concurrent.Executors.newCachedThreadPool;
-import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
-import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
-import static org.apache.dubbo.registry.Constants.CONSUMER_PROTOCOL;
-import static org.apache.dubbo.registry.Constants.PROVIDER_PROTOCOL;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.CHECK_PASS_INTERVAL;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEFAULT_CHECK_PASS_INTERVAL;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEFAULT_DEREGISTER_TIME;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEFAULT_PORT;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEFAULT_WATCH_TIMEOUT;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEREGISTER_AFTER;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.SERVICE_TAG;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.URL_META_KEY;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.WATCH_TIMEOUT;
-
-/**
- * registry center implementation for consul
- */
-public class ConsulRegistry extends FailbackRegistry {
-    private static final Logger logger = LoggerFactory.getLogger(ConsulRegistry.class);
-
-    private ConsulClient client;
-    private long checkPassInterval;
-    private ExecutorService notifierExecutor = newCachedThreadPool(
-            new NamedThreadFactory("dubbo-consul-notifier", true));
-    private ConcurrentMap<URL, ConsulNotifier> notifiers = new ConcurrentHashMap<>();
-    private ScheduledExecutorService ttlConsulCheckExecutor;
-
-
-    public ConsulRegistry(URL url) {
-        super(url);
-        String host = url.getHost();
-        int port = url.getPort() != 0 ? url.getPort() : DEFAULT_PORT;
-        client = new ConsulClient(host, port);
-        checkPassInterval = url.getParameter(CHECK_PASS_INTERVAL, DEFAULT_CHECK_PASS_INTERVAL);
-        ttlConsulCheckExecutor = Executors.newSingleThreadScheduledExecutor();
-        ttlConsulCheckExecutor.scheduleAtFixedRate(this::checkPass, checkPassInterval / 8,
-                checkPassInterval / 8, TimeUnit.MILLISECONDS);
-    }
-
-    @Override
-    public void register(URL url) {
-        if (isConsumerSide(url)) {
-            return;
-        }
-
-        super.register(url);
-    }
-
-    @Override
-    public void doRegister(URL url) {
-        client.agentServiceRegister(buildService(url));
-    }
-
-    @Override
-    public void unregister(URL url) {
-        if (isConsumerSide(url)) {
-            return;
-        }
-
-        super.unregister(url);
-    }
-
-    @Override
-    public void doUnregister(URL url) {
-        client.agentServiceDeregister(buildId(url));
-    }
-
-    @Override
-    public void subscribe(URL url, NotifyListener listener) {
-        if (isProviderSide(url)) {
-            return;
-        }
-
-        super.subscribe(url, listener);
-    }
-
-    @Override
-    public void doSubscribe(URL url, NotifyListener listener) {
-        Long index;
-        List<URL> urls;
-        if (ANY_VALUE.equals(url.getServiceInterface())) {
-            Response<Map<String, List<String>>> response = getAllServices(-1, buildWatchTimeout(url));
-            index = response.getConsulIndex();
-            List<HealthService> services = getHealthServices(response.getValue());
-            urls = convert(services, url);
-        } else {
-            String service = url.getServiceInterface();
-            Response<List<HealthService>> response = getHealthServices(service, -1, buildWatchTimeout(url));
-            index = response.getConsulIndex();
-            urls = convert(response.getValue(), url);
-        }
-
-        notify(url, listener, urls);
-        ConsulNotifier notifier = notifiers.computeIfAbsent(url, k -> new ConsulNotifier(url, index));
-        notifierExecutor.submit(notifier);
-    }
-
-    @Override
-    public void unsubscribe(URL url, NotifyListener listener) {
-        if (isProviderSide(url)) {
-            return;
-        }
-
-        super.unsubscribe(url, listener);
-    }
-
-    @Override
-    public void doUnsubscribe(URL url, NotifyListener listener) {
-        ConsulNotifier notifier = notifiers.remove(url);
-        notifier.stop();
-    }
-
-    @Override
-    public List<URL> lookup(URL url) {
-        if (url == null) {
-            throw new IllegalArgumentException("lookup url == null");
-        }
-        try {
-            String service = url.getServiceKey();
-            Response<List<HealthService>> result = getHealthServices(service, -1, buildWatchTimeout(url));
-            if (result == null || result.getValue() == null || result.getValue().isEmpty()) {
-                return new ArrayList<>();
-            } else {
-                return convert(result.getValue(), url);
-            }
-        } catch (Throwable e) {
-            throw new RpcException("Failed to lookup " + url + " from consul " + getUrl() + ", cause: " + e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return client.getAgentSelf() != null;
-    }
-
-    @Override
-    public void destroy() {
-        super.destroy();
-        notifierExecutor.shutdown();
-        ttlConsulCheckExecutor.shutdown();
-    }
-
-    private void checkPass() {
-        for (URL url : getRegistered()) {
-            String checkId = buildId(url);
-            try {
-                client.agentCheckPass("service:" + checkId);
-                if (logger.isDebugEnabled()) {
-                    logger.debug("check pass for url: " + url + " with check id: " + checkId);
-                }
-            } catch (Throwable t) {
-                logger.warn("fail to check pass for url: " + url + ", check id is: " + checkId);
-            }
-        }
-    }
-
-    private Response<List<HealthService>> getHealthServices(String service, long index, int watchTimeout) {
-        HealthServicesRequest request = HealthServicesRequest.newBuilder()
-                .setTag(SERVICE_TAG)
-                .setQueryParams(new QueryParams(watchTimeout, index))
-                .setPassing(true)
-                .build();
-        return client.getHealthServices(service, request);
-    }
-
-    private Response<Map<String, List<String>>> getAllServices(long index, int watchTimeout) {
-        CatalogServicesRequest request = CatalogServicesRequest.newBuilder()
-                .setQueryParams(new QueryParams(watchTimeout, index))
-                .build();
-        return client.getCatalogServices(request);
-    }
-
-    private List<HealthService> getHealthServices(Map<String, List<String>> services) {
-        return services.entrySet().stream()
-                .filter(s -> s.getValue().contains(SERVICE_TAG))
-                .map(s -> getHealthServices(s.getKey(), -1, -1).getValue())
-                .flatMap(Collection::stream)
-                .collect(Collectors.toList());
-    }
-
-
-    private boolean isConsumerSide(URL url) {
-        return url.getProtocol().equals(CONSUMER_PROTOCOL);
-    }
-
-    private boolean isProviderSide(URL url) {
-        return url.getProtocol().equals(PROVIDER_PROTOCOL);
-    }
-
-    private List<URL> convert(List<HealthService> services, URL consumerURL) {
-        if (CollectionUtils.isEmpty(services)) {
-            return emptyURL(consumerURL);
-        }
-        return services.stream()
-                .map(HealthService::getService)
-                .filter(Objects::nonNull)
-                .map(HealthService.Service::getMeta)
-                .filter(m -> m != null && m.containsKey(URL_META_KEY))
-                .map(m -> m.get(URL_META_KEY))
-                .map(URL::valueOf)
-                .filter(url -> UrlUtils.isMatch(consumerURL, url))
-                .collect(Collectors.toList());
-    }
-
-    private List<URL> emptyURL(URL consumerURL) {
-        // No Category Parameter
-        URL empty = URLBuilder.from(consumerURL)
-                .setProtocol(EMPTY_PROTOCOL)
-                .removeParameter(CATEGORY_KEY)
-                .build();
-        List<URL> result = new ArrayList<URL>();
-        result.add(empty);
-        return result;
-    }
-
-    private NewService buildService(URL url) {
-        NewService service = new NewService();
-        service.setAddress(url.getHost());
-        service.setPort(url.getPort());
-        service.setId(buildId(url));
-        service.setName(url.getServiceInterface());
-        service.setCheck(buildCheck(url));
-        service.setTags(buildTags(url));
-        service.setMeta(Collections.singletonMap(URL_META_KEY, url.toFullString()));
-        return service;
-    }
-
-    private List<String> buildTags(URL url) {
-        Map<String, String> params = url.getParameters();
-        List<String> tags = params.entrySet().stream()
-                .map(k -> k.getKey() + "=" + k.getValue())
-                .collect(Collectors.toList());
-        tags.add(SERVICE_TAG);
-        return tags;
-    }
-
-    private String buildId(URL url) {
-        // let's simply use url's hashcode to generate unique service id for now
-        return Integer.toHexString(url.hashCode());
-    }
-
-    private NewService.Check buildCheck(URL url) {
-        NewService.Check check = new NewService.Check();
-        check.setTtl((checkPassInterval / 1000) + "s");
-        check.setDeregisterCriticalServiceAfter(url.getParameter(DEREGISTER_AFTER, DEFAULT_DEREGISTER_TIME));
-        return check;
-    }
-
-    private int buildWatchTimeout(URL url) {
-        return url.getParameter(WATCH_TIMEOUT, DEFAULT_WATCH_TIMEOUT) / 1000;
-    }
-
-    private class ConsulNotifier implements Runnable {
-        private URL url;
-        private long consulIndex;
-        private boolean running;
-
-        ConsulNotifier(URL url, long consulIndex) {
-            this.url = url;
-            this.consulIndex = consulIndex;
-            this.running = true;
-        }
-
-        @Override
-        public void run() {
-            while (this.running) {
-                if (ANY_VALUE.equals(url.getServiceInterface())) {
-                    processServices();
-                } else {
-                    processService();
-                }
-            }
-        }
-
-        private void processService() {
-            String service = url.getServiceKey();
-            Response<List<HealthService>> response = getHealthServices(service, consulIndex, buildWatchTimeout(url));
-            Long currentIndex = response.getConsulIndex();
-            if (currentIndex != null && currentIndex > consulIndex) {
-                consulIndex = currentIndex;
-                List<HealthService> services = response.getValue();
-                List<URL> urls = convert(services, url);
-                for (NotifyListener listener : getSubscribed().get(url)) {
-                    doNotify(url, listener, urls);
-                }
-            }
-        }
-
-        private void processServices() {
-            Response<Map<String, List<String>>> response = getAllServices(consulIndex, buildWatchTimeout(url));
-            Long currentIndex = response.getConsulIndex();
-            if (currentIndex != null && currentIndex > consulIndex) {
-                consulIndex = currentIndex;
-                List<HealthService> services = getHealthServices(response.getValue());
-                List<URL> urls = convert(services, url);
-                for (NotifyListener listener : getSubscribed().get(url)) {
-                    doNotify(url, listener, urls);
-                }
-            }
-        }
-
-        void stop() {
-            this.running = false;
-        }
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulRegistryFactory.java b/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulRegistryFactory.java
deleted file mode 100644
index c36f009..0000000
--- a/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulRegistryFactory.java
+++ /dev/null
@@ -1,32 +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.registry.consul;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.registry.Registry;
-import org.apache.dubbo.registry.support.AbstractRegistryFactory;
-
-/**
- * registry center factory implementation for consul
- */
-public class ConsulRegistryFactory extends AbstractRegistryFactory {
-    @Override
-    protected Registry createRegistry(URL url) {
-        return new ConsulRegistry(url);
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscovery.java b/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscovery.java
deleted file mode 100644
index f1d3d3b..0000000
--- a/dubbo-spi-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscovery.java
+++ /dev/null
@@ -1,397 +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.registry.consul;
-
-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.common.utils.NamedThreadFactory;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.event.EventListener;
-import org.apache.dubbo.registry.client.AbstractServiceDiscovery;
-import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.ServiceDiscovery;
-import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
-import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
-
-import com.ecwid.consul.v1.ConsulClient;
-import com.ecwid.consul.v1.QueryParams;
-import com.ecwid.consul.v1.Response;
-import com.ecwid.consul.v1.agent.model.NewService;
-import com.ecwid.consul.v1.health.HealthServicesRequest;
-import com.ecwid.consul.v1.health.model.HealthService;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import static java.util.concurrent.Executors.newCachedThreadPool;
-import static org.apache.dubbo.common.constants.CommonConstants.SEMICOLON_SPLIT_PATTERN;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.CHECK_PASS_INTERVAL;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEFAULT_CHECK_PASS_INTERVAL;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEFAULT_DEREGISTER_TIME;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEFAULT_PORT;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEFAULT_WATCH_TIMEOUT;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.DEREGISTER_AFTER;
-import static org.apache.dubbo.registry.consul.AbstractConsulRegistry.WATCH_TIMEOUT;
-
-/**
- * 2019-07-31
- */
-public class ConsulServiceDiscovery extends AbstractServiceDiscovery implements EventListener<ServiceInstancesChangedEvent> {
-
-    private static final Logger logger = LoggerFactory.getLogger(ConsulServiceDiscovery.class);
-
-    private static final String QUERY_TAG = "consul_query_tag";
-    private static final String REGISTER_TAG = "consul_register_tag";
-
-    private List<String> registeringTags = new ArrayList<>();
-    private String tag;
-    private ConsulClient client;
-    private ExecutorService notifierExecutor = newCachedThreadPool(
-            new NamedThreadFactory("dubbo-service-discovery-consul-notifier", true));
-    private ConsulNotifier notifier;
-    private TtlScheduler ttlScheduler;
-    private long checkPassInterval;
-    private URL url;
-
-    @Override
-    public void onEvent(ServiceInstancesChangedEvent event) {
-
-    }
-
-    @Override
-    public void initialize(URL registryURL) throws Exception {
-        this.url = registryURL;
-        String host = url.getHost();
-        int port = url.getPort() != 0 ? url.getPort() : DEFAULT_PORT;
-        checkPassInterval = url.getParameter(CHECK_PASS_INTERVAL, DEFAULT_CHECK_PASS_INTERVAL);
-        client = new ConsulClient(host, port);
-        ttlScheduler = new TtlScheduler(checkPassInterval, client);
-        this.tag = registryURL.getParameter(QUERY_TAG);
-        this.registeringTags.addAll(getRegisteringTags(url));
-    }
-
-    private List<String> getRegisteringTags(URL url) {
-        List<String> tags = new ArrayList<>();
-        String rawTag = url.getParameter(REGISTER_TAG);
-        if (StringUtils.isNotEmpty(rawTag)) {
-            tags.addAll(Arrays.asList(SEMICOLON_SPLIT_PATTERN.split(rawTag)));
-        }
-        return tags;
-    }
-
-    @Override
-    public void destroy() {
-        if (notifier != null) {
-            notifier.stop();
-        }
-        notifier = null;
-        notifierExecutor.shutdownNow();
-        ttlScheduler.stop();
-    }
-
-    @Override
-    public void register(ServiceInstance serviceInstance) throws RuntimeException {
-        super.register(serviceInstance);
-        NewService consulService = buildService(serviceInstance);
-        ttlScheduler.add(consulService.getId());
-        client.agentServiceRegister(consulService);
-    }
-
-    @Override
-    public void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener) throws NullPointerException, IllegalArgumentException {
-//        if (notifier == null) {
-//            String serviceName = listener.getServiceNames();
-//            Response<List<HealthService>> response = getHealthServices(serviceName, -1, buildWatchTimeout());
-//            Long consulIndex = response.getConsulIndex();
-//            notifier = new ConsulNotifier(serviceName, consulIndex);
-//        }
-//        notifierExecutor.execute(notifier);
-    }
-
-    @Override
-    public void update(ServiceInstance serviceInstance) throws RuntimeException {
-        super.register(serviceInstance);
-        // TODO
-        // client.catalogRegister(buildCatalogService(serviceInstance));
-    }
-
-    @Override
-    public void unregister(ServiceInstance serviceInstance) throws RuntimeException {
-        String id = buildId(serviceInstance);
-        ttlScheduler.remove(id);
-        client.agentServiceDeregister(id);
-    }
-
-    @Override
-    public Set<String> getServices() {
-        return null;
-    }
-
-    @Override
-    public List<ServiceInstance> getInstances(String serviceName) throws NullPointerException {
-        Response<List<HealthService>> response = getHealthServices(serviceName, -1, buildWatchTimeout());
-        Long consulIndex = response.getConsulIndex();
-        if (notifier == null) {
-            notifier = new ConsulNotifier(serviceName, consulIndex);
-        }
-        return convert(response.getValue());
-    }
-
-    private List<ServiceInstance> convert(List<HealthService> services) {
-        return services.stream()
-                .map(HealthService::getService)
-                .map(service -> {
-                    ServiceInstance instance = new DefaultServiceInstance(
-                            service.getId(),
-                            service.getService(),
-                            service.getAddress(),
-                            service.getPort());
-                    instance.getMetadata().putAll(getMetadata(service));
-                    return instance;
-                })
-                .collect(Collectors.toList());
-    }
-
-    private Response<List<HealthService>> getHealthServices(String service, long index, int watchTimeout) {
-        HealthServicesRequest request = HealthServicesRequest.newBuilder()
-                .setTag(tag)
-                .setQueryParams(new QueryParams(watchTimeout, index))
-                .setPassing(true)
-                .build();
-        return client.getHealthServices(service, request);
-    }
-
-    private Map<String, String> getMetadata(HealthService.Service service) {
-        Map<String, String> metadata = service.getMeta();
-        metadata = decodeMetadata(metadata);
-        if (CollectionUtils.isEmptyMap(metadata)) {
-            metadata = getScCompatibleMetadata(service.getTags());
-        }
-        return metadata;
-    }
-
-    private Map<String, String> getScCompatibleMetadata(List<String> tags) {
-        LinkedHashMap<String, String> metadata = new LinkedHashMap<>();
-        if (tags != null) {
-            for (String tag : tags) {
-                String[] parts = StringUtils.delimitedListToStringArray(tag, "=");
-                switch (parts.length) {
-                    case 0:
-                        break;
-                    case 1:
-                        metadata.put(parts[0], parts[0]);
-                        break;
-                    case 2:
-                        metadata.put(parts[0], parts[1]);
-                        break;
-                    default:
-                        String[] end = Arrays.copyOfRange(parts, 1, parts.length);
-                        metadata.put(parts[0], StringUtils.arrayToDelimitedString(end, "="));
-                        break;
-                }
-
-            }
-        }
-
-        return metadata;
-    }
-
-    private NewService buildService(ServiceInstance serviceInstance) {
-        NewService service = new NewService();
-        service.setAddress(serviceInstance.getHost());
-        service.setPort(serviceInstance.getPort());
-        service.setId(buildId(serviceInstance));
-        service.setName(serviceInstance.getServiceName());
-        service.setCheck(buildCheck(serviceInstance));
-        service.setTags(buildTags(serviceInstance));
-//        service.setMeta(buildMetadata(serviceInstance));
-        return service;
-    }
-
-    private String buildId(ServiceInstance serviceInstance) {
-        return Integer.toHexString(serviceInstance.hashCode());
-    }
-
-    private List<String> buildTags(ServiceInstance serviceInstance) {
-        Map<String, String> params = serviceInstance.getMetadata();
-        List<String> tags = params.keySet().stream()
-                .map(k -> k + "=" + params.get(k))
-                .collect(Collectors.toList());
-        tags.addAll(registeringTags);
-        return tags;
-    }
-
-    private Map<String, String> buildMetadata(ServiceInstance serviceInstance) {
-        Map<String, String> metadata = new LinkedHashMap<>();
-        metadata.putAll(getScCompatibleMetadata(registeringTags));
-        if (CollectionUtils.isNotEmptyMap(serviceInstance.getMetadata())) {
-            metadata.putAll(serviceInstance.getMetadata());
-        }
-        metadata = encodeMetadata(metadata);
-        return metadata;
-    }
-
-    private Map<String, String> encodeMetadata(Map<String, String> metadata) {
-        if (metadata == null) {
-            return metadata;
-        }
-        Map<String, String> encoded = new HashMap<>(metadata.size());
-        metadata.forEach((k, v) -> encoded.put(Base64.getEncoder().encodeToString(k.getBytes()), v));
-        return encoded;
-    }
-
-    private Map<String, String> decodeMetadata(Map<String, String> metadata) {
-        if (metadata == null) {
-            return metadata;
-        }
-        Map<String, String> decoded = new HashMap<>(metadata.size());
-        metadata.forEach((k, v) -> decoded.put(new String(Base64.getDecoder().decode(k)), v));
-        return decoded;
-    }
-
-    private NewService.Check buildCheck(ServiceInstance serviceInstance) {
-        NewService.Check check = new NewService.Check();
-        check.setTtl((checkPassInterval / 1000) + "s");
-        String deregister = serviceInstance.getMetadata().get(DEREGISTER_AFTER);
-        check.setDeregisterCriticalServiceAfter(deregister == null ? DEFAULT_DEREGISTER_TIME : deregister);
-
-        return check;
-    }
-
-    private int buildWatchTimeout() {
-        return url.getParameter(WATCH_TIMEOUT, DEFAULT_WATCH_TIMEOUT) / 1000;
-    }
-
-    private class ConsulNotifier implements Runnable {
-        private String serviceName;
-        private long consulIndex;
-        private boolean running;
-
-        ConsulNotifier(String serviceName, long consulIndex) {
-            this.serviceName = serviceName;
-            this.consulIndex = consulIndex;
-            this.running = true;
-        }
-
-        @Override
-        public void run() {
-            while (this.running) {
-                processService();
-            }
-        }
-
-        private void processService() {
-            Response<List<HealthService>> response = getHealthServices(serviceName, consulIndex, Integer.MAX_VALUE);
-            Long currentIndex = response.getConsulIndex();
-            if (currentIndex != null && currentIndex > consulIndex) {
-                consulIndex = currentIndex;
-                List<HealthService> services = response.getValue();
-                List<ServiceInstance> serviceInstances = convert(services);
-                dispatchServiceInstancesChangedEvent(serviceName, serviceInstances);
-            }
-        }
-
-        void stop() {
-            this.running = false;
-        }
-    }
-
-    private static class TtlScheduler {
-
-        private static final Logger logger = LoggerFactory.getLogger(TtlScheduler.class);
-
-        private final Map<String, ScheduledFuture> serviceHeartbeats = new ConcurrentHashMap<>();
-
-        private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
-
-        private long checkInterval;
-
-        private ConsulClient client;
-
-        public TtlScheduler(long checkInterval, ConsulClient client) {
-            this.checkInterval = checkInterval;
-            this.client = client;
-        }
-
-        /**
-         * Add a service to the checks loop.
-         *
-         * @param instanceId instance id
-         */
-        public void add(String instanceId) {
-            ScheduledFuture task = this.scheduler.scheduleAtFixedRate(
-                    new ConsulHeartbeatTask(instanceId),
-                    checkInterval / 8,
-                    checkInterval / 8,
-                    TimeUnit.MILLISECONDS);
-            ScheduledFuture previousTask = this.serviceHeartbeats.put(instanceId, task);
-            if (previousTask != null) {
-                previousTask.cancel(true);
-            }
-        }
-
-        public void remove(String instanceId) {
-            ScheduledFuture task = this.serviceHeartbeats.get(instanceId);
-            if (task != null) {
-                task.cancel(true);
-            }
-            this.serviceHeartbeats.remove(instanceId);
-        }
-
-        private class ConsulHeartbeatTask implements Runnable {
-
-            private String checkId;
-
-            ConsulHeartbeatTask(String serviceId) {
-                this.checkId = serviceId;
-                if (!this.checkId.startsWith("service:")) {
-                    this.checkId = "service:" + this.checkId;
-                }
-            }
-
-            @Override
-            public void run() {
-                TtlScheduler.this.client.agentCheckPass(this.checkId);
-                if (logger.isDebugEnabled()) {
-                    logger.debug("Sending consul heartbeat for: " + this.checkId);
-                }
-            }
-
-        }
-
-        public void stop() {
-            scheduler.shutdownNow();
-        }
-
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory b/dubbo-spi-registry/dubbo-registry-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
deleted file mode 100644
index 7aea18f..0000000
--- a/dubbo-spi-registry/dubbo-registry-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
+++ /dev/null
@@ -1 +0,0 @@
-consul=org.apache.dubbo.registry.consul.ConsulRegistryFactory
diff --git a/dubbo-spi-registry/dubbo-registry-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscovery b/dubbo-spi-registry/dubbo-registry-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscovery
deleted file mode 100644
index e46973b..0000000
--- a/dubbo-spi-registry/dubbo-registry-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscovery
+++ /dev/null
@@ -1 +0,0 @@
-consul=org.apache.dubbo.registry.consul.ConsulServiceDiscovery
\ No newline at end of file
diff --git a/dubbo-spi-registry/dubbo-registry-consul/src/test/java/org/apache/dubbo/registry/consul/ConsulRegistryTest.java b/dubbo-spi-registry/dubbo-registry-consul/src/test/java/org/apache/dubbo/registry/consul/ConsulRegistryTest.java
deleted file mode 100644
index 13a7a45..0000000
--- a/dubbo-spi-registry/dubbo-registry-consul/src/test/java/org/apache/dubbo/registry/consul/ConsulRegistryTest.java
+++ /dev/null
@@ -1,135 +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.registry.consul;
-
-import com.pszymczyk.consul.ConsulProcess;
-import com.pszymczyk.consul.ConsulStarterBuilder;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.status.Status;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.Registry;
-import org.apache.dubbo.registry.status.RegistryStatusChecker;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class ConsulRegistryTest {
-
-    private static ConsulProcess consul;
-    private ConsulRegistry consulRegistry;
-    private String service = "org.apache.dubbo.test.injvmServie";
-    private URL serviceUrl = URL.valueOf("consul://127.0.0.1:" + NetUtils.getAvailablePort() + "/" + service + "?notify=false&methods=test1,test2");
-    private URL registryUrl;
-    private ConsulRegistryFactory consulRegistryFactory;
-
-    @BeforeEach
-    public void setUp() throws Exception {
-        this.consul = ConsulStarterBuilder.consulStarter()
-                .build()
-                .start();
-        this.registryUrl = URL.valueOf("consul://localhost:" + consul.getHttpPort());
-
-        consulRegistryFactory = new ConsulRegistryFactory();
-        this.consulRegistry = (ConsulRegistry) consulRegistryFactory.createRegistry(registryUrl);
-    }
-
-    @AfterEach
-    public void tearDown() throws Exception {
-        consul.close();
-        this.consulRegistry.destroy();
-    }
-
-    @Test
-    public void testRegister() {
-        Set<URL> registered;
-
-        for (int i = 0; i < 2; i++) {
-            consulRegistry.register(serviceUrl);
-            registered = consulRegistry.getRegistered();
-            assertThat(registered.contains(serviceUrl), is(true));
-        }
-
-        registered = consulRegistry.getRegistered();
-
-        assertThat(registered.size(), is(1));
-    }
-
-    @Test
-    public void testSubscribe() {
-        NotifyListener listener = mock(NotifyListener.class);
-        consulRegistry.subscribe(serviceUrl, listener);
-
-        Map<URL, Set<NotifyListener>> subscribed = consulRegistry.getSubscribed();
-        assertThat(subscribed.size(), is(1));
-        assertThat(subscribed.get(serviceUrl).size(), is(1));
-
-        consulRegistry.unsubscribe(serviceUrl, listener);
-        subscribed = consulRegistry.getSubscribed();
-        assertThat(subscribed.size(), is(1));
-        assertThat(subscribed.get(serviceUrl).size(), is(0));
-    }
-
-    @Test
-    public void testAvailable() {
-        consulRegistry.register(serviceUrl);
-        assertThat(consulRegistry.isAvailable(), is(true));
-
-//        consulRegistry.destroy();
-//        assertThat(consulRegistry.isAvailable(), is(false));
-    }
-
-    @Test
-    public void testLookup() throws InterruptedException {
-        List<URL> lookup = consulRegistry.lookup(serviceUrl);
-        assertThat(lookup.size(), is(0));
-
-        consulRegistry.register(serviceUrl);
-        Thread.sleep(5000);
-        lookup = consulRegistry.lookup(serviceUrl);
-        assertThat(lookup.size(), is(1));
-    }
-
-    @Test
-    public void testStatusChecker() {
-        RegistryStatusChecker registryStatusChecker = new RegistryStatusChecker();
-        Status status = registryStatusChecker.check();
-        assertThat(status.getLevel(), is(Status.Level.UNKNOWN));
-
-        Registry registry = consulRegistryFactory.getRegistry(registryUrl);
-        assertThat(registry, not(nullValue()));
-
-        status = registryStatusChecker.check();
-        assertThat(status.getLevel(), is(Status.Level.OK));
-
-        registry.register(serviceUrl);
-        status = registryStatusChecker.check();
-        assertThat(status.getLevel(), is(Status.Level.OK));
-    }
-
-}
diff --git a/dubbo-spi-registry/dubbo-registry-consul/src/test/java/org/apache/dubbo/registry/consul/ConsulServiceDiscoveryTest.java b/dubbo-spi-registry/dubbo-registry-consul/src/test/java/org/apache/dubbo/registry/consul/ConsulServiceDiscoveryTest.java
deleted file mode 100644
index e106248..0000000
--- a/dubbo-spi-registry/dubbo-registry-consul/src/test/java/org/apache/dubbo/registry/consul/ConsulServiceDiscoveryTest.java
+++ /dev/null
@@ -1,108 +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.registry.consul;
-
-import com.pszymczyk.consul.ConsulProcess;
-import com.pszymczyk.consul.ConsulStarterBuilder;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.ServiceInstance;
-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.util.ArrayList;
-import java.util.List;
-
-import static java.lang.String.valueOf;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class ConsulServiceDiscoveryTest {
-
-    private static ConsulProcess consul;
-    private URL url;
-    static ConsulServiceDiscovery consulServiceDiscovery;
-    private static final String SERVICE_NAME = "A";
-    private static final String LOCALHOST = "127.0.0.1";
-
-    @BeforeEach
-    public void init() throws Exception {
-        this.consul = ConsulStarterBuilder.consulStarter()
-                .build()
-                .start();
-        url = URL.valueOf("consul://localhost:" + consul.getHttpPort());
-        consulServiceDiscovery = new ConsulServiceDiscovery();
-        Assertions.assertNull(consulServiceDiscovery.getServices());
-        consulServiceDiscovery.initialize(url);
-    }
-
-    @AfterEach
-    public void close() {
-        consulServiceDiscovery.destroy();
-        consul.close();
-    }
-
-    @Test
-    public void testRegistration() throws InterruptedException{
-        DefaultServiceInstance serviceInstance = createServiceInstance(SERVICE_NAME, LOCALHOST, NetUtils.getAvailablePort());
-        consulServiceDiscovery.register(serviceInstance);
-        Thread.sleep(5000);
-
-        List<ServiceInstance> serviceInstances = consulServiceDiscovery.getInstances(SERVICE_NAME);
-        assertEquals(serviceInstances.size(), 1);
-        assertEquals(serviceInstances.get(0).getId(), Integer.toHexString(serviceInstance.hashCode()));
-        assertEquals(serviceInstances.get(0).getHost(), serviceInstance.getHost());
-        assertEquals(serviceInstances.get(0).getServiceName(), serviceInstance.getServiceName());
-        assertEquals(serviceInstances.get(0).getPort(), serviceInstance.getPort());
-
-        consulServiceDiscovery.unregister(serviceInstance);
-        Thread.sleep(5000);
-        serviceInstances = consulServiceDiscovery.getInstances(SERVICE_NAME);
-        System.out.println(serviceInstances.size());
-        assertTrue(serviceInstances.isEmpty());
-    }
-
-    private DefaultServiceInstance createServiceInstance(String serviceName, String host, int port) {
-        return new DefaultServiceInstance(host + ":" + port, serviceName, host, port);
-    }
-
-    @Test
-    public void testGetInstances() throws Exception {
-        String serviceName = "ConsulTest77Service";
-        assertTrue(consulServiceDiscovery.getInstances(serviceName).isEmpty());
-        int portA = NetUtils.getAvailablePort();
-        int portB = NetUtils.getAvailablePort();
-        consulServiceDiscovery.register(new DefaultServiceInstance(valueOf(System.nanoTime()), serviceName, "127.0.0.1", portA));
-        consulServiceDiscovery.register(new DefaultServiceInstance(valueOf(System.nanoTime()), serviceName, "127.0.0.1", portB));
-        Thread.sleep(5000);
-        Assertions.assertFalse(consulServiceDiscovery.getInstances(serviceName).isEmpty());
-        List<String> r = convertToIpPort(consulServiceDiscovery.getInstances(serviceName));
-        assertTrue(r.contains("127.0.0.1:"+portA));
-        assertTrue(r.contains("127.0.0.1:"+portB));
-    }
-
-    private List<String> convertToIpPort(List<ServiceInstance> serviceInstances) {
-        List<String> result = new ArrayList<>();
-        for (ServiceInstance serviceInstance : serviceInstances) {
-            result.add(serviceInstance.getHost() + ":" + serviceInstance.getPort());
-        }
-        return result;
-    }
-}
\ No newline at end of file
diff --git a/dubbo-spi-registry/dubbo-registry-default/pom.xml b/dubbo-spi-registry/dubbo-registry-default/pom.xml
deleted file mode 100644
index 1dd05a9..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/pom.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?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/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.apache.dubbo</groupId>
-        <artifactId>dubbo-registry</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
-    </parent>
-    <artifactId>dubbo-registry-default</artifactId>
-    <packaging>jar</packaging>
-    <name>${project.artifactId}</name>
-    <description>The default registry module of dubbo project</description>
-    <properties>
-        <skip_maven_deploy>false</skip_maven_deploy>
-    </properties>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-registry-api</artifactId>
-            <version>${project.parent.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-dubbo</artifactId>
-            <version>${project.parent.version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-rpc-injvm</artifactId>
-            <version>${project.parent.version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-remoting-netty4</artifactId>
-            <version>${project.parent.version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-serialization-hessian2</artifactId>
-            <version>${project.parent.version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file
diff --git a/dubbo-spi-registry/dubbo-registry-default/src/main/java/org/apache/dubbo/registry/dubbo/DubboRegistry.java b/dubbo-spi-registry/dubbo-registry-default/src/main/java/org/apache/dubbo/registry/dubbo/DubboRegistry.java
deleted file mode 100644
index 825b8c7..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/src/main/java/org/apache/dubbo/registry/dubbo/DubboRegistry.java
+++ /dev/null
@@ -1,161 +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.registry.dubbo;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.Version;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.ExecutorUtil;
-import org.apache.dubbo.common.utils.NamedThreadFactory;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.RegistryService;
-import org.apache.dubbo.registry.support.FailbackRegistry;
-import org.apache.dubbo.remoting.Constants;
-import org.apache.dubbo.rpc.Invoker;
-
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.ReentrantLock;
-
-import static org.apache.dubbo.registry.Constants.REGISTRY_RECONNECT_PERIOD_KEY;
-
-/**
- * DubboRegistry
- */
-public class DubboRegistry extends FailbackRegistry {
-
-    private final static Logger logger = LoggerFactory.getLogger(DubboRegistry.class);
-
-    // Reconnecting detection cycle: 3 seconds (unit:millisecond)
-    private static final int RECONNECT_PERIOD_DEFAULT = 3 * 1000;
-
-    // Scheduled executor service
-    private final ScheduledExecutorService reconnectTimer = Executors.newScheduledThreadPool(1, new NamedThreadFactory("DubboRegistryReconnectTimer", true));
-
-    // Reconnection timer, regular check connection is available. If unavailable, unlimited reconnection.
-    private final ScheduledFuture<?> reconnectFuture;
-
-    // The lock for client acquisition process, lock the creation process of the client instance to prevent repeated clients
-    private final ReentrantLock clientLock = new ReentrantLock();
-
-    private final Invoker<RegistryService> registryInvoker;
-
-    private final RegistryService registryService;
-
-    /**
-     * The time in milliseconds the reconnectTimer will wait
-     */
-    private final int reconnectPeriod;
-
-    public DubboRegistry(Invoker<RegistryService> registryInvoker, RegistryService registryService) {
-        super(registryInvoker.getUrl());
-        this.registryInvoker = registryInvoker;
-        this.registryService = registryService;
-        // Start reconnection timer
-        this.reconnectPeriod = registryInvoker.getUrl().getParameter(REGISTRY_RECONNECT_PERIOD_KEY, RECONNECT_PERIOD_DEFAULT);
-        reconnectFuture = reconnectTimer.scheduleWithFixedDelay(() -> {
-            // Check and connect to the registry
-            try {
-                connect();
-            } catch (Throwable t) { // Defensive fault tolerance
-                logger.error("Unexpected error occur at reconnect, cause: " + t.getMessage(), t);
-            }
-        }, reconnectPeriod, reconnectPeriod, TimeUnit.MILLISECONDS);
-    }
-
-    protected final void connect() {
-        try {
-            // Check whether or not it is connected
-            if (isAvailable()) {
-                return;
-            }
-            if (logger.isInfoEnabled()) {
-                logger.info("Reconnect to registry " + getUrl());
-            }
-            clientLock.lock();
-            try {
-                // Double check whether or not it is connected
-                if (isAvailable()) {
-                    return;
-                }
-                recover();
-            } finally {
-                clientLock.unlock();
-            }
-        } catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
-            if (getUrl().getParameter(Constants.CHECK_KEY, true)) {
-                if (t instanceof RuntimeException) {
-                    throw (RuntimeException) t;
-                }
-                throw new RuntimeException(t.getMessage(), t);
-            }
-            logger.error("Failed to connect to registry " + getUrl().getAddress() + " from provider/consumer " + NetUtils.getLocalHost() + " use dubbo " + Version.getVersion() + ", cause: " + t.getMessage(), t);
-        }
-    }
-
-    @Override
-    public boolean isAvailable() {
-        if (registryInvoker == null) {
-            return false;
-        }
-        return registryInvoker.isAvailable();
-    }
-
-    @Override
-    public void destroy() {
-        super.destroy();
-        try {
-            // Cancel the reconnection timer
-            ExecutorUtil.cancelScheduledFuture(reconnectFuture);
-        } catch (Throwable t) {
-            logger.warn("Failed to cancel reconnect timer", t);
-        }
-        registryInvoker.destroy();
-        ExecutorUtil.gracefulShutdown(reconnectTimer, reconnectPeriod);
-    }
-
-    @Override
-    public void doRegister(URL url) {
-        registryService.register(url);
-    }
-
-    @Override
-    public void doUnregister(URL url) {
-        registryService.unregister(url);
-    }
-
-    @Override
-    public void doSubscribe(URL url, NotifyListener listener) {
-        registryService.subscribe(url, listener);
-    }
-
-    @Override
-    public void doUnsubscribe(URL url, NotifyListener listener) {
-        registryService.unsubscribe(url, listener);
-    }
-
-    @Override
-    public List<URL> lookup(URL url) {
-        return registryService.lookup(url);
-    }
-
-}
diff --git a/dubbo-spi-registry/dubbo-registry-default/src/main/java/org/apache/dubbo/registry/dubbo/DubboRegistryFactory.java b/dubbo-spi-registry/dubbo-registry-default/src/main/java/org/apache/dubbo/registry/dubbo/DubboRegistryFactory.java
deleted file mode 100644
index 8ee7fbb..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/src/main/java/org/apache/dubbo/registry/dubbo/DubboRegistryFactory.java
+++ /dev/null
@@ -1,118 +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.registry.dubbo;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.URLBuilder;
-import org.apache.dubbo.common.bytecode.Wrapper;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.registry.Registry;
-import org.apache.dubbo.registry.RegistryService;
-import org.apache.dubbo.registry.integration.RegistryDirectory;
-import org.apache.dubbo.registry.support.AbstractRegistryFactory;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Protocol;
-import org.apache.dubbo.rpc.ProxyFactory;
-import org.apache.dubbo.rpc.cluster.Cluster;
-import org.apache.dubbo.rpc.cluster.RouterChain;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-
-import static org.apache.dubbo.common.constants.CommonConstants.CALLBACK_INSTANCES_LIMIT_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.LAZY_CONNECT_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
-import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
-import static org.apache.dubbo.registry.Constants.CONSUMER_PROTOCOL;
-import static org.apache.dubbo.remoting.Constants.CONNECT_TIMEOUT_KEY;
-import static org.apache.dubbo.remoting.Constants.RECONNECT_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.CLUSTER_STICKY_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.EXPORT_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
-
-/**
- * DubboRegistryFactory
- *
- */
-public class DubboRegistryFactory extends AbstractRegistryFactory {
-
-    private Protocol protocol;
-    private ProxyFactory proxyFactory;
-    private Cluster cluster;
-
-    private static URL getRegistryURL(URL url) {
-        return URLBuilder.from(url)
-                .setPath(RegistryService.class.getName())
-                .removeParameter(EXPORT_KEY).removeParameter(REFER_KEY)
-                .addParameter(INTERFACE_KEY, RegistryService.class.getName())
-                .addParameter(CLUSTER_STICKY_KEY, "true")
-                .addParameter(LAZY_CONNECT_KEY, "true")
-                .addParameter(RECONNECT_KEY, "false")
-                .addParameterIfAbsent(TIMEOUT_KEY, "10000")
-                .addParameterIfAbsent(CALLBACK_INSTANCES_LIMIT_KEY, "10000")
-                .addParameterIfAbsent(CONNECT_TIMEOUT_KEY, "10000")
-                .addParameter(METHODS_KEY, StringUtils.join(new HashSet<>(Arrays.asList(Wrapper.getWrapper(RegistryService.class).getDeclaredMethodNames())), ","))
-                //.addParameter(Constants.STUB_KEY, RegistryServiceStub.class.getName())
-                //.addParameter(Constants.STUB_EVENT_KEY, Boolean.TRUE.toString()) //for event dispatch
-                //.addParameter(Constants.ON_DISCONNECT_KEY, "disconnect")
-                .addParameter("subscribe.1.callback", "true")
-                .addParameter("unsubscribe.1.callback", "false")
-                .build();
-    }
-
-    public void setProtocol(Protocol protocol) {
-        this.protocol = protocol;
-    }
-
-    public void setProxyFactory(ProxyFactory proxyFactory) {
-        this.proxyFactory = proxyFactory;
-    }
-
-    public void setCluster(Cluster cluster) {
-        this.cluster = cluster;
-    }
-
-    @Override
-    public Registry createRegistry(URL url) {
-        url = getRegistryURL(url);
-        List<URL> urls = new ArrayList<>();
-        urls.add(url.removeParameter(BACKUP_KEY));
-        String backup = url.getParameter(BACKUP_KEY);
-        if (backup != null && backup.length() > 0) {
-            String[] addresses = COMMA_SPLIT_PATTERN.split(backup);
-            for (String address : addresses) {
-                urls.add(url.setAddress(address));
-            }
-        }
-        RegistryDirectory<RegistryService> directory = new RegistryDirectory<>(RegistryService.class, url.addParameter(INTERFACE_KEY, RegistryService.class.getName()).addParameterAndEncoded(REFER_KEY, url.toParameterString()));
-        Invoker<RegistryService> registryInvoker = cluster.join(directory);
-        RegistryService registryService = proxyFactory.getProxy(registryInvoker);
-        DubboRegistry registry = new DubboRegistry(registryInvoker, registryService);
-        directory.setRegistry(registry);
-        directory.setProtocol(protocol);
-        directory.setRouterChain(RouterChain.buildChain(url));
-        directory.notify(urls);
-        directory.subscribe(new URL(CONSUMER_PROTOCOL, NetUtils.getLocalHost(), 0, RegistryService.class.getName(), url.getParameters()));
-        return registry;
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory b/dubbo-spi-registry/dubbo-registry-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
deleted file mode 100644
index a2c6f12..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
+++ /dev/null
@@ -1 +0,0 @@
-dubbo=org.apache.dubbo.registry.dubbo.DubboRegistryFactory
\ No newline at end of file
diff --git a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/AbstractRegistryService.java b/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/AbstractRegistryService.java
deleted file mode 100644
index b281416..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/AbstractRegistryService.java
+++ /dev/null
@@ -1,237 +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.registry.dubbo;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.RegistryService;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * AbstractRegistryService
- *
- */
-public abstract class AbstractRegistryService implements RegistryService {
-
-    // Log output
-    protected final Logger logger = LoggerFactory.getLogger(getClass());
-
-    // Registered services
-    // Map<serviceName, Map<url, queryString>>
-    private final ConcurrentMap<String, List<URL>> registered = new ConcurrentHashMap<String, List<URL>>();
-
-    // Subscribed services
-    // Map<serviceName, queryString>
-    private final ConcurrentMap<String, Map<String, String>> subscribed = new ConcurrentHashMap<String, Map<String, String>>();
-
-    // Notified services
-    // Map<serviceName, Map<url, queryString>>
-    private final ConcurrentMap<String, List<URL>> notified = new ConcurrentHashMap<String, List<URL>>();
-
-    // Listeners list for subscribed services
-    // Map<serviceName, List<notificationListener>>
-    private final ConcurrentMap<String, List<NotifyListener>> notifyListeners = new ConcurrentHashMap<String, List<NotifyListener>>();
-
-    @Override
-    public void register(URL url) {
-        if (logger.isInfoEnabled()) {
-            logger.info("Register service: " + url.getServiceKey() + ",url:" + url);
-        }
-        register(url.getServiceKey(), url);
-    }
-
-    @Override
-    public void unregister(URL url) {
-        if (logger.isInfoEnabled()) {
-            logger.info("Unregister service: " + url.getServiceKey() + ",url:" + url);
-        }
-        unregister(url.getServiceKey(), url);
-    }
-
-    @Override
-    public void subscribe(URL url, NotifyListener listener) {
-        if (logger.isInfoEnabled()) {
-            logger.info("Subscribe service: " + url.getServiceKey() + ",url:" + url);
-        }
-        subscribe(url.getServiceKey(), url, listener);
-    }
-
-    @Override
-    public void unsubscribe(URL url, NotifyListener listener) {
-        if (logger.isInfoEnabled()) {
-            logger.info("Unsubscribe service: " + url.getServiceKey() + ",url:" + url);
-        }
-        unsubscribe(url.getServiceKey(), url, listener);
-    }
-
-    @Override
-    public List<URL> lookup(URL url) {
-        return getRegistered(url.getServiceKey());
-    }
-
-    public void register(String service, URL url) {
-        if (service == null) {
-            throw new IllegalArgumentException("service == null");
-        }
-        if (url == null) {
-            throw new IllegalArgumentException("url == null");
-        }
-        List<URL> urls = registered.computeIfAbsent(service, k -> new CopyOnWriteArrayList<>());
-        if (!urls.contains(url)) {
-            urls.add(url);
-        }
-    }
-
-    public void unregister(String service, URL url) {
-        if (service == null) {
-            throw new IllegalArgumentException("service == null");
-        }
-        if (url == null) {
-            throw new IllegalArgumentException("url == null");
-        }
-        List<URL> urls = registered.get(service);
-        if (urls != null) {
-            URL deleteURL = null;
-            for (URL u : urls) {
-                if (u.toIdentityString().equals(url.toIdentityString())) {
-                    deleteURL = u;
-                    break;
-                }
-            }
-            if (deleteURL != null) {
-                urls.remove(deleteURL);
-            }
-        }
-    }
-
-    public void subscribe(String service, URL url, NotifyListener listener) {
-        if (service == null) {
-            throw new IllegalArgumentException("service == null");
-        }
-        if (url == null) {
-            throw new IllegalArgumentException("parameters == null");
-        }
-        if (listener == null) {
-            throw new IllegalArgumentException("listener == null");
-        }
-        subscribed.put(service, url.getParameters());
-        addListener(service, listener);
-    }
-
-    public void unsubscribe(String service, URL url, NotifyListener listener) {
-        if (service == null) {
-            throw new IllegalArgumentException("service == null");
-        }
-        if (url == null) {
-            throw new IllegalArgumentException("parameters == null");
-        }
-        if (listener == null) {
-            throw new IllegalArgumentException("listener == null");
-        }
-        subscribed.remove(service);
-        removeListener(service, listener);
-    }
-
-    //The listener of the consumer and the provider can be stored together, all based on the service name
-    private void addListener(final String service, final NotifyListener listener) {
-        if (listener == null) {
-            return;
-        }
-        List<NotifyListener> listeners = notifyListeners.computeIfAbsent(service, k -> new CopyOnWriteArrayList<>());
-        if (!listeners.contains(listener)) {
-            listeners.add(listener);
-        }
-    }
-
-    private void removeListener(final String service, final NotifyListener listener) {
-        if (listener == null) {
-            return;
-        }
-        List<NotifyListener> listeners = notifyListeners.get(service);
-        if (listeners != null) {
-            listeners.remove(listener);
-        }
-    }
-
-    private void doNotify(String service, List<URL> urls) {
-        notified.put(service, urls);
-        List<NotifyListener> listeners = notifyListeners.get(service);
-        if (listeners != null) {
-            for (NotifyListener listener : listeners) {
-                try {
-                    notify(service, urls, listener);
-                } catch (Throwable t) {
-                    logger.error("Failed to notify registry event, service: " + service + ", urls: " + urls + ", cause: " + t.getMessage(), t);
-                }
-            }
-        }
-    }
-
-    protected void notify(String service, List<URL> urls, NotifyListener listener) {
-        listener.notify(urls);
-    }
-
-    protected final void forbid(String service) {
-        doNotify(service, new ArrayList<URL>(0));
-    }
-
-    protected final void notify(String service, List<URL> urls) {
-        if (service == null || service.length() == 0
-                || urls == null || urls.size() == 0) {
-            return;
-        }
-        doNotify(service, urls);
-    }
-
-    public Map<String, List<URL>> getRegistered() {
-        return Collections.unmodifiableMap(registered);
-    }
-
-    public List<URL> getRegistered(String service) {
-        return Collections.unmodifiableList(registered.get(service));
-    }
-
-    public Map<String, Map<String, String>> getSubscribed() {
-        return Collections.unmodifiableMap(subscribed);
-    }
-
-    public Map<String, String> getSubscribed(String service) {
-        return subscribed.get(service);
-    }
-
-    public Map<String, List<URL>> getNotified() {
-        return Collections.unmodifiableMap(notified);
-    }
-
-    public List<URL> getNotified(String service) {
-        return Collections.unmodifiableList(notified.get(service));
-    }
-
-    public Map<String, List<NotifyListener>> getListeners() {
-        return Collections.unmodifiableMap(notifyListeners);
-    }
-
-}
diff --git a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/DemoService.java b/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/DemoService.java
deleted file mode 100644
index 3167c9b..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/DemoService.java
+++ /dev/null
@@ -1,27 +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.registry.dubbo;
-
-/**
- * <code>TestService</code>
- */
-
-public interface DemoService {
-    void sayHello(String name);
-
-    int plus(int a, int b);
-}
\ No newline at end of file
diff --git a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/DemoServiceImpl.java b/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/DemoServiceImpl.java
deleted file mode 100644
index 5b92872..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/DemoServiceImpl.java
+++ /dev/null
@@ -1,32 +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.registry.dubbo;
-
-/**
- *
- */
-public class DemoServiceImpl implements DemoService {
-    @Override
-    public void sayHello(String name) {
-
-    }
-
-    @Override
-    public int plus(int a, int b) {
-        return 0;
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/DubboRegistryTest.java b/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/DubboRegistryTest.java
deleted file mode 100644
index b757d4a..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/DubboRegistryTest.java
+++ /dev/null
@@ -1,155 +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.registry.dubbo;
-
-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.NetUtils;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.RegistryService;
-import org.apache.dubbo.registry.support.FailbackRegistry;
-import org.apache.dubbo.remoting.Constants;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTOCOL;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.BDDMockito.mock;
-
-public class DubboRegistryTest {
-
-    private static final Logger logger = LoggerFactory.getLogger(DubboRegistryTest.class);
-
-    private DubboRegistry dubboRegistry;
-
-    private URL registryURL;
-
-    private URL serviceURL;
-
-    private NotifyListener notifyListener;
-
-    private Invoker<RegistryService> invoker;
-
-    private RegistryService registryService;
-
-    @BeforeEach
-    public void setUp() {
-        registryURL = new URL(REGISTRY_PROTOCOL, NetUtils.getLocalHost(), NetUtils.getAvailablePort())
-                .addParameter(Constants.CHECK_KEY, false)
-                .setServiceInterface(RegistryService.class.getName());
-        serviceURL = new URL(DubboProtocol.NAME, NetUtils.getLocalHost(), NetUtils.getAvailablePort())
-                .addParameter(Constants.CHECK_KEY, false)
-                .setServiceInterface(RegistryService.class.getName());
-
-        registryService = new MockDubboRegistry(registryURL);
-
-        invoker = mock(Invoker.class);
-        given(invoker.getUrl()).willReturn(serviceURL);
-        given(invoker.getInterface()).willReturn(RegistryService.class);
-        given(invoker.invoke(new RpcInvocation())).willReturn(null);
-
-        dubboRegistry = new DubboRegistry(invoker, registryService);
-        notifyListener = mock(NotifyListener.class);
-    }
-
-    @Test
-    public void testRegister() {
-        dubboRegistry.register(serviceURL);
-        assertEquals(1, getRegisteredSize());
-    }
-
-    @Test
-    public void testUnRegister() {
-        assertEquals(0, getRegisteredSize());
-        dubboRegistry.register(serviceURL);
-        assertEquals(1, getRegisteredSize());
-        dubboRegistry.unregister(serviceURL);
-        assertEquals(0, getRegisteredSize());
-    }
-
-    @Test
-    public void testSubscribe() {
-        dubboRegistry.register(serviceURL);
-        assertEquals(1, getRegisteredSize());
-        dubboRegistry.subscribe(serviceURL, notifyListener);
-        assertEquals(1, getSubscribedSize());
-        assertEquals(1, getNotifiedListeners());
-    }
-
-    @Test
-    public void testUnsubscribe() {
-        dubboRegistry.subscribe(serviceURL, notifyListener);
-        assertEquals(1, getSubscribedSize());
-        assertEquals(1, getNotifiedListeners());
-        dubboRegistry.unsubscribe(serviceURL, notifyListener);
-        assertEquals(0, getNotifiedListeners());
-    }
-
-    private class MockDubboRegistry extends FailbackRegistry {
-
-        private volatile boolean isAvailable = false;
-
-        public MockDubboRegistry(URL url) {
-            super(url);
-        }
-
-        @Override
-        public void doRegister(URL url) {
-            logger.info("Begin to register: " + url);
-            isAvailable = true;
-        }
-
-        @Override
-        public void doUnregister(URL url) {
-            logger.info("Begin to ungister: " + url);
-            isAvailable = false;
-        }
-
-        @Override
-        public void doSubscribe(URL url, NotifyListener listener) {
-            logger.info("Begin to subscribe: " + url);
-        }
-
-        @Override
-        public void doUnsubscribe(URL url, NotifyListener listener) {
-            logger.info("Begin to unSubscribe: " + url);
-        }
-
-        @Override
-        public boolean isAvailable() {
-            return isAvailable;
-        }
-    }
-
-    private int getNotifiedListeners() {
-        return dubboRegistry.getSubscribed().get(serviceURL).size();
-    }
-
-    private int getRegisteredSize() {
-        return dubboRegistry.getRegistered().size();
-    }
-
-    private int getSubscribedSize() {
-        return dubboRegistry.getSubscribed().size();
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockChannel.java b/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockChannel.java
deleted file mode 100644
index e563da6..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockChannel.java
+++ /dev/null
@@ -1,141 +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.registry.dubbo;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.remoting.ChannelHandler;
-import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.exchange.ExchangeChannel;
-import org.apache.dubbo.remoting.exchange.ExchangeHandler;
-
-import java.net.InetSocketAddress;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutorService;
-
-public class MockChannel implements ExchangeChannel {
-
-    public static boolean closed = false;
-    public static boolean closing = true;
-    final InetSocketAddress localAddress;
-    final InetSocketAddress remoteAddress;
-
-    public MockChannel(String localHostname, int localPort, String remoteHostName, int remotePort) {
-        localAddress = new InetSocketAddress(localHostname, localPort);
-        remoteAddress = new InetSocketAddress(remoteHostName, remotePort);
-        closed = false;
-    }
-
-    @Override
-    public InetSocketAddress getLocalAddress() {
-        return localAddress;
-    }
-
-    @Override
-    public InetSocketAddress getRemoteAddress() {
-        return remoteAddress;
-    }
-
-    @Override
-    public boolean isConnected() {
-        return true;
-    }
-
-    @Override
-    public void close() {
-        closed = true;
-    }
-
-    @Override
-    public void send(Object message) throws RemotingException {
-    }
-
-    @Override
-    public void close(int timeout) {
-    }
-
-    @Override
-    public void startClose() {
-        closing = true;
-    }
-
-    @Override
-    public URL getUrl() {
-        return null;
-    }
-
-    public CompletableFuture<Object> send(Object request, int timeout) throws RemotingException {
-        return null;
-    }
-
-    @Override
-    public ChannelHandler getChannelHandler() {
-        return null;
-    }
-
-    public CompletableFuture<Object> request(Object request) throws RemotingException {
-        return null;
-    }
-
-    public CompletableFuture<Object> request(Object request, int timeout) throws RemotingException {
-        return null;
-    }
-
-    @Override
-    public CompletableFuture<Object> request(Object request, ExecutorService executor) throws RemotingException {
-        return null;
-    }
-
-    @Override
-    public CompletableFuture<Object> request(Object request, int timeout, ExecutorService executor) throws RemotingException {
-        return null;
-    }
-
-    public ExchangeHandler getExchangeHandler() {
-        return null;
-    }
-
-    @Override
-    public Object getAttribute(String key) {
-        return null;
-    }
-
-    @Override
-    public void setAttribute(String key, Object value) {
-
-    }
-
-    @Override
-    public boolean hasAttribute(String key) {
-        return false;
-    }
-
-    @Override
-    public boolean isClosed() {
-        return false;
-    }
-
-    @Override
-    public void removeAttribute(String key) {
-
-    }
-
-    @Override
-    public void send(Object message, boolean sent) throws RemotingException {
-
-    }
-
-}
diff --git a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockedClient.java b/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockedClient.java
deleted file mode 100644
index ad06cd2..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockedClient.java
+++ /dev/null
@@ -1,298 +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.registry.dubbo;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.remoting.Channel;
-import org.apache.dubbo.remoting.ChannelHandler;
-import org.apache.dubbo.remoting.Codec;
-import org.apache.dubbo.remoting.RemotingException;
-import org.apache.dubbo.remoting.exchange.ExchangeClient;
-import org.apache.dubbo.remoting.exchange.ExchangeHandler;
-import org.apache.dubbo.remoting.exchange.support.Replier;
-
-import java.net.InetSocketAddress;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeoutException;
-
-/**
- * MockedClient
- *
- */
-public class MockedClient implements ExchangeClient {
-
-    //private String host;
-
-    //private int port;
-
-    private boolean connected;
-
-    private Object received;
-
-    private Object sent;
-
-    private Object invoked;
-
-    private Replier<?> handler;
-
-    private InetSocketAddress address;
-
-    private boolean closed = false;
-
-    //private ChannelListener listener;
-
-    public MockedClient(String host, int port, boolean connected) {
-        this(host, port, connected, null);
-    }
-
-    public MockedClient(String host, int port, boolean connected, Object received) {
-        this.address = new InetSocketAddress(host, port);
-        this.connected = connected;
-        this.received = received;
-    }
-
-    public void open() {
-    }
-
-    @Override
-    public void close() {
-        this.closed = true;
-    }
-
-    @Override
-    public void send(Object msg) throws RemotingException {
-        this.sent = msg;
-    }
-
-    public CompletableFuture<Object> request(Object msg) throws RemotingException {
-        return request(msg, null);
-    }
-
-    public CompletableFuture<Object> request(Object msg, int timeout) throws RemotingException {
-        return this.request(msg, timeout, null);
-    }
-
-    @Override
-    public CompletableFuture<Object> request(Object msg, ExecutorService executor) throws RemotingException {
-        return this.request(msg, 0, executor);
-    }
-
-    @Override
-    public CompletableFuture<Object> request(Object msg, int timeout, ExecutorService executor) throws RemotingException {
-        this.invoked = msg;
-        return new CompletableFuture<Object>() {
-            public Object get() throws InterruptedException, ExecutionException {
-                return received;
-            }
-
-            public Object get(int timeoutInMillis) throws InterruptedException, ExecutionException, TimeoutException {
-                return received;
-            }
-
-            public boolean isDone() {
-                return true;
-            }
-        };
-    }
-
-    public void registerHandler(Replier<?> handler) {
-        this.handler = handler;
-    }
-
-    public void unregisterHandler(Replier<?> handler) {
-        //this.handler = null;
-    }
-
-    public void addChannelListener(ChannelHandler listener) {
-        //this.listener = listener;
-    }
-
-    public void removeChannelListener(ChannelHandler listener) {
-        //this.listener = null;
-    }
-
-    @Override
-    public boolean isConnected() {
-        return connected;
-    }
-
-    /**
-     * @param connected the connected to set
-     */
-    public void setConnected(boolean connected) {
-        this.connected = connected;
-    }
-
-    public Object getSent() {
-        return sent;
-    }
-
-    public Replier<?> getHandler() {
-        return handler;
-    }
-
-    public Object getInvoked() {
-        return invoked;
-    }
-
-    @Override
-    public InetSocketAddress getRemoteAddress() {
-        return address;
-    }
-
-    public String getName() {
-        return "mocked";
-    }
-
-    @Override
-    public InetSocketAddress getLocalAddress() {
-        return null;
-    }
-
-    public int getTimeout() {
-        return 0;
-    }
-
-    public void setTimeout(int timeout) {
-    }
-
-    @Override
-    public void close(int timeout) {
-        close();
-    }
-
-    @Override
-    public void startClose() {
-
-    }
-
-    public boolean isOpen() {
-        return closed;
-    }
-
-    public Codec getCodec() {
-        return null;
-    }
-
-    public void setCodec(Codec codec) {
-    }
-
-    public String getHost() {
-        return null;
-    }
-
-    public void setHost(String host) {
-    }
-
-    public int getPort() {
-        return 0;
-    }
-
-    public void setPort(int port) {
-    }
-
-    public int getThreadCount() {
-        return 0;
-    }
-
-    public void setThreadCount(int threadCount) {
-    }
-
-    @Override
-    public URL getUrl() {
-        return null;
-    }
-
-    public Replier<?> getReceiver() {
-        return null;
-    }
-
-    @Override
-    public ChannelHandler getChannelHandler() {
-        return null;
-    }
-
-    public void reset(Map<String, String> parameters) {
-    }
-
-    public Channel getChannel() {
-        return this;
-    }
-
-    public ExchangeHandler getExchangeHandler() {
-        return null;
-    }
-
-    @Override
-    public void reconnect() throws RemotingException {
-    }
-
-    @Override
-    public Object getAttribute(String key) {
-        return null;
-    }
-
-    @Override
-    public void setAttribute(String key, Object value) {
-
-    }
-
-    @Override
-    public boolean hasAttribute(String key) {
-        return false;
-    }
-
-    @Override
-    public boolean isClosed() {
-        return closed;
-    }
-
-    @Override
-    public void removeAttribute(String key) {
-
-    }
-
-    /**
-     * @return the received
-     */
-    public Object getReceived() {
-        return received;
-    }
-
-    /**
-     * @param received the received to set
-     */
-    public void setReceived(Object received) {
-        this.received = received;
-    }
-
-    @Override
-    public void send(Object message, boolean sent) throws RemotingException {
-    }
-
-    @Override
-    public void reset(URL url) {
-    }
-
-    @Deprecated
-    public void reset(org.apache.dubbo.common.Parameters parameters) {
-    }
-
-}
diff --git a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryDirectoryTest.java b/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryDirectoryTest.java
deleted file mode 100644
index 9abfc9a..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryDirectoryTest.java
+++ /dev/null
@@ -1,1143 +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.registry.dubbo;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.common.utils.LogUtil;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.Registry;
-import org.apache.dubbo.registry.RegistryFactory;
-import org.apache.dubbo.registry.integration.RegistryDirectory;
-import org.apache.dubbo.remoting.Constants;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Protocol;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.cluster.RouterChain;
-import org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance;
-import org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance;
-import org.apache.dubbo.rpc.cluster.router.script.ScriptRouterFactory;
-import org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.service.GenericService;
-
-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 org.mockito.Mockito;
-
-import javax.script.ScriptEngineManager;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-
-import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
-import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
-import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.DISABLED_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.ENABLED_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.LOADBALANCE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.CONFIGURATORS_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
-import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDERS_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.ROUTERS_CATEGORY;
-import static org.apache.dubbo.common.constants.RegistryConstants.ROUTE_PROTOCOL;
-import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.INVOCATION_NEED_MOCK;
-import static org.apache.dubbo.rpc.cluster.Constants.MOCK_PROTOCOL;
-import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.ROUTER_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.RULE_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.TYPE_KEY;
-import static org.junit.jupiter.api.Assertions.fail;
-
-@SuppressWarnings({"rawtypes", "unchecked"})
-public class RegistryDirectoryTest {
-
-    private static boolean isScriptUnsupported = new ScriptEngineManager().getEngineByName("javascript") == null;
-    RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
-    Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
-    String service = DemoService.class.getName();
-    RpcInvocation invocation = new RpcInvocation();
-    URL noMeaningUrl = URL.valueOf("notsupport:/" + service + "?refer=" + URL.encode("interface=" + service));
-    URL SERVICEURL = URL.valueOf("dubbo://127.0.0.1:9091/" + service + "?lazy=true&side=consumer&application=mockName");
-    URL SERVICEURL2 = URL.valueOf("dubbo://127.0.0.1:9092/" + service + "?lazy=true&side=consumer&application=mockName");
-    URL SERVICEURL3 = URL.valueOf("dubbo://127.0.0.1:9093/" + service + "?lazy=true&side=consumer&application=mockName");
-    URL SERVICEURL_DUBBO_NOPATH = URL.valueOf("dubbo://127.0.0.1:9092" + "?lazy=true&side=consumer&application=mockName");
-
-    private Registry registry = Mockito.mock(Registry.class);
-
-    @BeforeEach
-    public void setUp() {
-        ApplicationModel.setApplication("RegistryDirectoryTest");
-    }
-
-    private RegistryDirectory getRegistryDirectory(URL url) {
-        RegistryDirectory registryDirectory = new RegistryDirectory(URL.class, url);
-        registryDirectory.setProtocol(protocol);
-        registryDirectory.setRegistry(registry);
-        registryDirectory.setRouterChain(RouterChain.buildChain(url));
-        registryDirectory.subscribe(url);
-        // asert empty
-        List invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(0, invokers.size());
-        Assertions.assertFalse(registryDirectory.isAvailable());
-        return registryDirectory;
-    }
-
-    private RegistryDirectory getRegistryDirectory() {
-        return getRegistryDirectory(noMeaningUrl);
-    }
-
-    @Test
-    public void test_Constructor_WithErrorParam() {
-        try {
-            new RegistryDirectory(null, null);
-            fail();
-        } catch (IllegalArgumentException e) {
-
-        }
-        try {
-            // null url
-            new RegistryDirectory(null, noMeaningUrl);
-            fail();
-        } catch (IllegalArgumentException e) {
-
-        }
-        try {
-            // no servicekey
-            new RegistryDirectory(RegistryDirectoryTest.class, URL.valueOf("dubbo://10.20.30.40:9090"));
-            fail();
-        } catch (IllegalArgumentException e) {
-
-        }
-    }
-
-    @Test
-    public void test_Constructor_CheckStatus() throws Exception {
-        URL url = URL.valueOf("notsupported://10.20.30.40/" + service + "?a=b").addParameterAndEncoded(REFER_KEY,
-                "foo=bar");
-        RegistryDirectory reg = getRegistryDirectory(url);
-        Field field = reg.getClass().getDeclaredField("queryMap");
-        field.setAccessible(true);
-        Map<String, String> queryMap = (Map<String, String>) field.get(reg);
-        Assertions.assertEquals("bar", queryMap.get("foo"));
-        Assertions.assertEquals(url.clearParameters().addParameter("foo", "bar"), reg.getConsumerUrl());
-    }
-
-    @Test
-    public void testNotified_Normal() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        test_Notified2invokers(registryDirectory);
-        test_Notified1invokers(registryDirectory);
-        test_Notified3invokers(registryDirectory);
-        testforbid(registryDirectory);
-    }
-
-    /**
-     * Test push only router
-     */
-    @Test
-    public void testNotified_Normal_withRouters() {
-        LogUtil.start();
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        test_Notified1invokers(registryDirectory);
-        test_Notified_only_routers(registryDirectory);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-        Assertions.assertTrue(LogUtil.checkNoError(), "notify no invoker urls ,should not error");
-        LogUtil.stop();
-        test_Notified2invokers(registryDirectory);
-
-    }
-
-    @Test
-    public void testNotified_WithError() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        List<URL> serviceUrls = new ArrayList<URL>();
-        // ignore error log
-        URL badurl = URL.valueOf("notsupported://127.0.0.1/" + service);
-        serviceUrls.add(badurl);
-        serviceUrls.add(SERVICEURL);
-
-        registryDirectory.notify(serviceUrls);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-        List invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers.size());
-    }
-
-    @Test
-    public void testNotified_WithDuplicateUrls() {
-        List<URL> serviceUrls = new ArrayList<URL>();
-        // ignore error log
-        serviceUrls.add(SERVICEURL);
-        serviceUrls.add(SERVICEURL);
-
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        registryDirectory.notify(serviceUrls);
-        List invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers.size());
-    }
-
-    // forbid
-    private void testforbid(RegistryDirectory registryDirectory) {
-        invocation = new RpcInvocation();
-        List<URL> serviceUrls = new ArrayList<URL>();
-        serviceUrls.add(new URL(EMPTY_PROTOCOL, ANYHOST_VALUE, 0, service, CATEGORY_KEY, PROVIDERS_CATEGORY));
-        registryDirectory.notify(serviceUrls);
-        Assertions.assertFalse(registryDirectory.isAvailable(),
-            "invokers size=0 ,then the registry directory is not available");
-        try {
-            registryDirectory.list(invocation);
-            fail("forbid must throw RpcException");
-        } catch (RpcException e) {
-            Assertions.assertEquals(RpcException.FORBIDDEN_EXCEPTION, e.getCode());
-        }
-    }
-
-    //The test call is independent of the path of the registry url
-    @Test
-    public void test_NotifiedDubbo1() {
-        URL errorPathUrl = URL.valueOf("notsupport:/" + "xxx" + "?refer=" + URL.encode("interface=" + service));
-        RegistryDirectory registryDirectory = getRegistryDirectory(errorPathUrl);
-        List<URL> serviceUrls = new ArrayList<URL>();
-        URL Dubbo1URL = URL.valueOf("dubbo://127.0.0.1:9098?lazy=true");
-        serviceUrls.add(Dubbo1URL.addParameter("methods", "getXXX"));
-        registryDirectory.notify(serviceUrls);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-
-        invocation = new RpcInvocation();
-
-        List<Invoker<DemoService>> invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers.size());
-
-        invocation.setMethodName("getXXX");
-        invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers.size());
-        Assertions.assertEquals(DemoService.class.getName(), invokers.get(0).getUrl().getPath());
-    }
-
-    // notify one invoker
-    private void test_Notified_only_routers(RegistryDirectory registryDirectory) {
-        List<URL> serviceUrls = new ArrayList<URL>();
-        serviceUrls.add(URL.valueOf("empty://127.0.0.1/?category=routers"));
-        registryDirectory.notify(serviceUrls);
-    }
-
-    // notify one invoker
-    private void test_Notified1invokers(RegistryDirectory registryDirectory) {
-
-        List<URL> serviceUrls = new ArrayList<URL>();
-        serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1").addParameter(APPLICATION_KEY, "mockApplicationName"));// .addParameter("refer.autodestroy", "true")
-        registryDirectory.notify(serviceUrls);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-
-        invocation = new RpcInvocation();
-
-        List invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers.size());
-
-        invocation.setMethodName("getXXX");
-        invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers.size());
-
-        invocation.setMethodName("getXXX1");
-        invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers.size());
-
-        invocation.setMethodName("getXXX2");
-        invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers.size());
-    }
-
-    // 2 invokers===================================
-    private void test_Notified2invokers(RegistryDirectory registryDirectory) {
-        List<URL> serviceUrls = new ArrayList<URL>();
-        serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
-        serviceUrls.add(SERVICEURL2.addParameter("methods", "getXXX1,getXXX2"));
-        serviceUrls.add(SERVICEURL2.addParameter("methods", "getXXX1,getXXX2"));
-
-        registryDirectory.notify(serviceUrls);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-
-        invocation = new RpcInvocation();
-
-        List invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers.size());
-
-        invocation.setMethodName("getXXX");
-        invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers.size());
-
-        invocation.setMethodName("getXXX1");
-        invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers.size());
-    }
-
-    // 3 invoker notifications===================================
-    private void test_Notified3invokers(RegistryDirectory registryDirectory) {
-        List<URL> serviceUrls = new ArrayList<URL>();
-        serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
-        serviceUrls.add(SERVICEURL2.addParameter("methods", "getXXX1,getXXX2"));
-        serviceUrls.add(SERVICEURL3.addParameter("methods", "getXXX1,getXXX2,getXXX3"));
-
-        registryDirectory.notify(serviceUrls);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-
-        invocation = new RpcInvocation();
-
-        List invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(3, invokers.size());
-
-        invocation.setMethodName("getXXX");
-        invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(3, invokers.size());
-
-        invocation.setMethodName("getXXX1");
-        invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(3, invokers.size());
-
-        invocation.setMethodName("getXXX2");
-        invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(3, invokers.size());
-
-        invocation.setMethodName("getXXX3");
-        invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(3, invokers.size());
-    }
-
-    @Test
-    public void testParametersMerge() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        URL regurl = noMeaningUrl.addParameter("test", "reg").addParameterAndEncoded(REFER_KEY,
-                "key=query&" + LOADBALANCE_KEY + "=" + LeastActiveLoadBalance.NAME);
-        RegistryDirectory<RegistryDirectoryTest> registryDirectory2 = new RegistryDirectory(
-                RegistryDirectoryTest.class,
-                regurl);
-        registryDirectory2.setProtocol(protocol);
-
-        List<URL> serviceUrls = new ArrayList<URL>();
-        // The parameters of the inspection registry need to be cleared
-        {
-            serviceUrls.clear();
-            serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
-            registryDirectory.notify(serviceUrls);
-
-            invocation = new RpcInvocation();
-            List invokers = registryDirectory.list(invocation);
-
-            Invoker invoker = (Invoker) invokers.get(0);
-            URL url = invoker.getUrl();
-            Assertions.assertNull(url.getParameter("key"));
-        }
-        // The parameters of the provider for the inspection service need merge
-        {
-            serviceUrls.clear();
-            serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX2").addParameter("key", "provider"));
-
-            registryDirectory.notify(serviceUrls);
-            invocation = new RpcInvocation();
-            List invokers = registryDirectory.list(invocation);
-
-            Invoker invoker = (Invoker) invokers.get(0);
-            URL url = invoker.getUrl();
-            Assertions.assertEquals("provider", url.getParameter("key"));
-        }
-        // The parameters of the test service query need to be with the providermerge.
-        {
-            serviceUrls.clear();
-            serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX3").addParameter("key", "provider"));
-            registryDirectory2.setRegistry(registry);
-            registryDirectory2.setRouterChain(RouterChain.buildChain(noMeaningUrl));
-            registryDirectory2.subscribe(noMeaningUrl);
-            registryDirectory2.notify(serviceUrls);
-            invocation = new RpcInvocation();
-            List invokers = registryDirectory2.list(invocation);
-
-            Invoker invoker = (Invoker) invokers.get(0);
-            URL url = invoker.getUrl();
-            Assertions.assertEquals("query", url.getParameter("key"));
-        }
-
-        {
-            serviceUrls.clear();
-            serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
-            registryDirectory.notify(serviceUrls);
-
-            invocation = new RpcInvocation();
-            List invokers = registryDirectory.list(invocation);
-
-            Invoker invoker = (Invoker) invokers.get(0);
-            URL url = invoker.getUrl();
-            Assertions.assertFalse(url.getParameter(Constants.CHECK_KEY, false));
-        }
-        {
-            serviceUrls.clear();
-            serviceUrls.add(SERVICEURL.addParameter(LOADBALANCE_KEY, RoundRobinLoadBalance.NAME));
-            registryDirectory2.notify(serviceUrls);
-
-            invocation = new RpcInvocation();
-            invocation.setMethodName("get");
-            List invokers = registryDirectory2.list(invocation);
-
-            Invoker invoker = (Invoker) invokers.get(0);
-            URL url = invoker.getUrl();
-            Assertions.assertEquals(LeastActiveLoadBalance.NAME, url.getMethodParameter("get", LOADBALANCE_KEY));
-        }
-        //test geturl
-        {
-            Assertions.assertNull(registryDirectory2.getUrl().getParameter("mock"));
-            serviceUrls.clear();
-            serviceUrls.add(SERVICEURL.addParameter(MOCK_KEY, "true"));
-            registryDirectory2.notify(serviceUrls);
-
-            Assertions.assertEquals("true", registryDirectory2.getConsumerUrl().getParameter("mock"));
-        }
-    }
-
-    /**
-     * When destroying, RegistryDirectory should: 1. be disconnected from Registry 2. destroy all invokers
-     */
-    @Test
-    public void testDestroy() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-
-        List<URL> serviceUrls = new ArrayList<URL>();
-        serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
-        serviceUrls.add(SERVICEURL2.addParameter("methods", "getXXX1,getXXX2"));
-        serviceUrls.add(SERVICEURL3.addParameter("methods", "getXXX1,getXXX2,getXXX3"));
-
-        registryDirectory.notify(serviceUrls);
-        List<Invoker> invokers = registryDirectory.list(invocation);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-        Assertions.assertTrue(invokers.get(0).isAvailable());
-
-        registryDirectory.destroy();
-        Assertions.assertFalse(registryDirectory.isAvailable());
-        Assertions.assertFalse(invokers.get(0).isAvailable());
-        registryDirectory.destroy();
-
-        List<Invoker<RegistryDirectoryTest>> cachedInvokers = registryDirectory.getInvokers();
-        Map<String, Invoker<RegistryDirectoryTest>> urlInvokerMap = registryDirectory.getUrlInvokerMap();
-
-        Assertions.assertNull(cachedInvokers);
-        Assertions.assertEquals(0, urlInvokerMap.size());
-        // List<U> urls = mockRegistry.getSubscribedUrls();
-
-        RpcInvocation inv = new RpcInvocation();
-        try {
-            registryDirectory.list(inv);
-            fail();
-        } catch (RpcException e) {
-            Assertions.assertTrue(e.getMessage().contains("already destroyed"));
-        }
-    }
-
-    @Test
-    public void testDestroy_WithDestroyRegistry() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        CountDownLatch latch = new CountDownLatch(1);
-        registryDirectory.setRegistry(new MockRegistry(latch));
-        registryDirectory.subscribe(URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/DemoService?category=providers"));
-        registryDirectory.destroy();
-        Assertions.assertEquals(0, latch.getCount());
-    }
-
-    @Test
-    public void testDestroy_WithDestroyRegistry_WithError() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        registryDirectory.setRegistry(new MockRegistry(true));
-        registryDirectory.destroy();
-    }
-
-    @Test
-    public void testDubbo1UrlWithGenericInvocation() {
-
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-
-        List<URL> serviceUrls = new ArrayList<URL>();
-        URL serviceURL = SERVICEURL_DUBBO_NOPATH.addParameter("methods", "getXXX1,getXXX2,getXXX3");
-        serviceUrls.add(serviceURL);
-
-        registryDirectory.notify(serviceUrls);
-
-        // Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException;
-        invocation = new RpcInvocation($INVOKE, GenericService.class.getName(), new Class[]{String.class, String[].class, Object[].class},
-                new Object[]{"getXXX1", "", new Object[]{}});
-
-        List<Invoker> invokers = registryDirectory.list(invocation);
-
-        Assertions.assertEquals(1, invokers.size());
-//        Assertions.assertEquals(
-//                serviceURL.setPath(service).addParameters("check", "false", "interface", DemoService.class.getName(), REMOTE_APPLICATION_KEY, serviceURL.getParameter(APPLICATION_KEY))
-//                , invokers.get(0).getUrl()
-//        );
-
-    }
-
-    /**
-     * When the first arg of a method is String or Enum, Registry server can do parameter-value-based routing.
-     */
-    @Disabled("Parameter routing is not available at present.")
-    @Test
-    public void testParmeterRoute() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        List<URL> serviceUrls = new ArrayList<URL>();
-        serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1.napoli"));
-        serviceUrls.add(SERVICEURL2.addParameter("methods", "getXXX1.MORGAN,getXXX2"));
-        serviceUrls.add(SERVICEURL3.addParameter("methods", "getXXX1.morgan,getXXX2,getXXX3"));
-
-        registryDirectory.notify(serviceUrls);
-
-        invocation = new RpcInvocation($INVOKE, GenericService.class.getName(),
-                new Class[]{String.class, String[].class, Object[].class},
-                new Object[]{"getXXX1", new String[]{"Enum"}, new Object[]{Param.MORGAN}});
-
-        List invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers.size());
-    }
-
-    /**
-     * Empty notify cause forbidden, non-empty notify cancels forbidden state
-     */
-    @Test
-    public void testEmptyNotifyCauseForbidden() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        List invokers = null;
-
-        List<URL> serviceUrls = new ArrayList<URL>();
-        registryDirectory.notify(serviceUrls);
-
-        RpcInvocation inv = new RpcInvocation();
-        try {
-            invokers = registryDirectory.list(inv);
-        } catch (RpcException e) {
-            Assertions.assertEquals(RpcException.FORBIDDEN_EXCEPTION, e.getCode());
-            Assertions.assertFalse(registryDirectory.isAvailable());
-        }
-
-        serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
-        serviceUrls.add(SERVICEURL2.addParameter("methods", "getXXX1,getXXX2"));
-        serviceUrls.add(SERVICEURL3.addParameter("methods", "getXXX1,getXXX2,getXXX3"));
-
-        registryDirectory.notify(serviceUrls);
-        inv.setMethodName("getXXX2");
-        invokers = registryDirectory.list(inv);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-        Assertions.assertEquals(3, invokers.size());
-    }
-
-    /**
-     * 1. notify twice, the second time notified router rules should completely replace the former one. 2. notify with
-     * no router url, do nothing to current routers 3. notify with only one router url, with router=clean, clear all
-     * current routers
-     */
-    @Test
-    public void testNotifyRouterUrls() {
-        if (isScriptUnsupported) return;
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        URL routerurl = URL.valueOf(ROUTE_PROTOCOL + "://127.0.0.1:9096/");
-        URL routerurl2 = URL.valueOf(ROUTE_PROTOCOL + "://127.0.0.1:9097/");
-
-        List<URL> serviceUrls = new ArrayList<URL>();
-        // without ROUTER_KEY, the first router should not be created.
-        serviceUrls.add(routerurl.addParameter(CATEGORY_KEY, ROUTERS_CATEGORY).addParameter(TYPE_KEY, "javascript").addParameter(ROUTER_KEY, "notsupported").addParameter(RULE_KEY, "function test1(){}"));
-        serviceUrls.add(routerurl2.addParameter(CATEGORY_KEY, ROUTERS_CATEGORY).addParameter(TYPE_KEY, "javascript").addParameter(ROUTER_KEY,
-                ScriptRouterFactory.NAME).addParameter(RULE_KEY,
-                "function test1(){}"));
-
-        // FIXME
-        /*registryDirectory.notify(serviceUrls);
-        RouterChain routerChain = registryDirectory.getRouterChain();
-        //default invocation selector
-        Assertions.assertEquals(1 + 1, routers.size());
-        Assertions.assertTrue(ScriptRouter.class == routers.get(1).getClass() || ScriptRouter.class == routers.get(0).getClass());
-
-        registryDirectory.notify(new ArrayList<URL>());
-        routers = registryDirectory.getRouters();
-        Assertions.assertEquals(1 + 1, routers.size());
-        Assertions.assertTrue(ScriptRouter.class == routers.get(1).getClass() || ScriptRouter.class == routers.get(0).getClass());
-
-        serviceUrls.clear();
-        serviceUrls.add(routerurl.addParameter(Constants.ROUTER_KEY, Constants.ROUTER_TYPE_CLEAR));
-        registryDirectory.notify(serviceUrls);
-        routers = registryDirectory.getRouters();
-        Assertions.assertEquals(0 + 1, routers.size());*/
-    }
-
-    /**
-     * Test whether the override rule have a high priority
-     * Scene: first push override , then push invoker
-     */
-    @Test
-    public void testNotifyoverrideUrls_beforeInvoker() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        List<URL> overrideUrls = new ArrayList<URL>();
-        overrideUrls.add(URL.valueOf("override://0.0.0.0?timeout=1&connections=5"));
-        registryDirectory.notify(overrideUrls);
-        //The registry is initially pushed to override only, and the dirctory state should be false because there is no invoker.
-        Assertions.assertFalse(registryDirectory.isAvailable());
-
-        //After pushing two provider, the directory state is restored to true
-        List<URL> serviceUrls = new ArrayList<URL>();
-        serviceUrls.add(SERVICEURL.addParameter("timeout", "1000"));
-        serviceUrls.add(SERVICEURL2.addParameter("timeout", "1000").addParameter("connections", "10"));
-
-        registryDirectory.notify(serviceUrls);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-
-        //Start validation of parameter values
-
-        invocation = new RpcInvocation();
-
-        List<Invoker<?>> invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers.size());
-
-        Assertions.assertEquals("1", invokers.get(0).getUrl().getParameter("timeout"), "override rute must be first priority");
-        Assertions.assertEquals("5", invokers.get(0).getUrl().getParameter("connections"), "override rute must be first priority");
-    }
-
-    /**
-     * Test whether the override rule have a high priority
-     * Scene: first push override , then push invoker
-     */
-    @Test
-    public void testNotifyoverrideUrls_afterInvoker() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-
-        //After pushing two provider, the directory state is restored to true
-        List<URL> serviceUrls = new ArrayList<URL>();
-        serviceUrls.add(SERVICEURL.addParameter("timeout", "1000"));
-        serviceUrls.add(SERVICEURL2.addParameter("timeout", "1000").addParameter("connections", "10"));
-
-        registryDirectory.notify(serviceUrls);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-
-        List<URL> overrideUrls = new ArrayList<URL>();
-        overrideUrls.add(URL.valueOf("override://0.0.0.0?timeout=1&connections=5"));
-        registryDirectory.notify(overrideUrls);
-
-        //Start validation of parameter values
-
-        invocation = new RpcInvocation();
-
-        List<Invoker<?>> invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers.size());
-
-        Assertions.assertEquals("1", invokers.get(0).getUrl().getParameter("timeout"), "override rute must be first priority");
-        Assertions.assertEquals("5", invokers.get(0).getUrl().getParameter("connections"), "override rute must be first priority");
-    }
-
-    /**
-     * Test whether the override rule have a high priority
-     * Scene: push override rules with invoker
-     */
-    @Test
-    public void testNotifyoverrideUrls_withInvoker() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-
-        List<URL> durls = new ArrayList<URL>();
-        durls.add(SERVICEURL.addParameter("timeout", "1000"));
-        durls.add(SERVICEURL2.addParameter("timeout", "1000").addParameter("connections", "10"));
-        durls.add(URL.valueOf("override://0.0.0.0?timeout=1&connections=5"));
-
-        registryDirectory.notify(durls);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-
-        //Start validation of parameter values
-
-        invocation = new RpcInvocation();
-
-        List<Invoker<?>> invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers.size());
-
-        Assertions.assertEquals("1", invokers.get(0).getUrl().getParameter("timeout"), "override rute must be first priority");
-        Assertions.assertEquals("5", invokers.get(0).getUrl().getParameter("connections"), "override rute must be first priority");
-    }
-
-    /**
-     * Test whether the override rule have a high priority
-     * Scene: the rules of the push are the same as the parameters of the provider
-     * Expectation: no need to be re-referenced
-     */
-    @Test
-    public void testNotifyoverrideUrls_Nouse() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        invocation = new RpcInvocation();
-
-        List<URL> durls = new ArrayList<URL>();
-        durls.add(SERVICEURL.addParameter("timeout", "1"));//One is the same, one is different
-        durls.add(SERVICEURL2.addParameter("timeout", "1").addParameter("connections", "5"));
-        registryDirectory.notify(durls);
-        List<Invoker<?>> invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers.size());
-        Map<String, Invoker<?>> map = new HashMap<>();
-        map.put(invokers.get(0).getUrl().getAddress(), invokers.get(0));
-        map.put(invokers.get(1).getUrl().getAddress(), invokers.get(1));
-
-        durls = new ArrayList<URL>();
-        durls.add(URL.valueOf("override://0.0.0.0?timeout=1&connections=5"));
-        registryDirectory.notify(durls);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-
-        invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers.size());
-
-        Map<String, Invoker<?>> map2 = new HashMap<>();
-        map2.put(invokers.get(0).getUrl().getAddress(), invokers.get(0));
-        map2.put(invokers.get(1).getUrl().getAddress(), invokers.get(1));
-
-        //The parameters are different and must be rereferenced.
-        Assertions.assertNotSame(map.get(SERVICEURL.getAddress()), map2.get(SERVICEURL.getAddress()),
-            "object should not same");
-
-        //The parameters can not be rereferenced
-        Assertions.assertSame(map.get(SERVICEURL2.getAddress()), map2.get(SERVICEURL2.getAddress()),
-            "object should not same");
-    }
-
-    /**
-     * Test override rules for a certain provider
-     */
-    @Test
-    public void testNofityOverrideUrls_Provider() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        invocation = new RpcInvocation();
-
-        List<URL> durls = new ArrayList<URL>();
-        durls.add(SERVICEURL.setHost("10.20.30.140").addParameter("timeout", "1").addParameter(SIDE_KEY, CONSUMER_SIDE));//One is the same, one is different
-        durls.add(SERVICEURL2.setHost("10.20.30.141").addParameter("timeout", "2").addParameter(SIDE_KEY, CONSUMER_SIDE));
-        registryDirectory.notify(durls);
-
-        durls = new ArrayList<URL>();
-        durls.add(URL.valueOf("override://0.0.0.0?timeout=3"));
-        durls.add(URL.valueOf("override://10.20.30.141:9092?timeout=4"));
-        registryDirectory.notify(durls);
-
-        List<Invoker<?>> invokers = registryDirectory.list(invocation);
-        URL aUrl = invokers.get(0).getUrl();
-        URL bUrl = invokers.get(1).getUrl();
-        Assertions.assertEquals(aUrl.getHost().equals("10.20.30.140") ? "3" : "4", aUrl.getParameter("timeout"));
-        Assertions.assertEquals(bUrl.getHost().equals("10.20.30.141") ? "4" : "3", bUrl.getParameter("timeout"));
-    }
-
-    /**
-     * Test cleanup override rules, and sent remove rules and other override rules
-     * Whether the test can be restored to the providerUrl when it is pushed
-     */
-    @Test
-    public void testNofityOverrideUrls_Clean1() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        invocation = new RpcInvocation();
-
-        List<URL> durls = new ArrayList<URL>();
-        durls.add(SERVICEURL.setHost("10.20.30.140").addParameter("timeout", "1"));
-        registryDirectory.notify(durls);
-
-        durls = new ArrayList<URL>();
-        durls.add(URL.valueOf("override://0.0.0.0?timeout=1000"));
-        registryDirectory.notify(durls);
-
-        durls = new ArrayList<URL>();
-        durls.add(URL.valueOf("override://0.0.0.0?timeout=3"));
-        durls.add(URL.valueOf("override://0.0.0.0"));
-        registryDirectory.notify(durls);
-
-        List<Invoker<?>> invokers = registryDirectory.list(invocation);
-        Invoker<?> aInvoker = invokers.get(0);
-        //Need to be restored to the original providerUrl
-        Assertions.assertEquals("1", aInvoker.getUrl().getParameter("timeout"));
-    }
-
-    /**
-     * The test clears the override rule and only sends the override cleanup rules
-     * Whether the test can be restored to the providerUrl when it is pushed
-     */
-    @Test
-    public void testNofityOverrideUrls_CleanOnly() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        invocation = new RpcInvocation();
-
-        List<URL> durls = new ArrayList<URL>();
-        durls.add(SERVICEURL.setHost("10.20.30.140").addParameter("timeout", "1"));
-        registryDirectory.notify(durls);
-        Assertions.assertNull(registryDirectory.getConsumerUrl().getParameter("mock"));
-
-        //override
-        durls = new ArrayList<URL>();
-        durls.add(URL.valueOf("override://0.0.0.0?timeout=1000&mock=fail"));
-        registryDirectory.notify(durls);
-        List<Invoker<?>> invokers = registryDirectory.list(invocation);
-        Invoker<?> aInvoker = invokers.get(0);
-        Assertions.assertEquals("1000", aInvoker.getUrl().getParameter("timeout"));
-        Assertions.assertEquals("fail", registryDirectory.getConsumerUrl().getParameter("mock"));
-
-        //override clean
-        durls = new ArrayList<URL>();
-        durls.add(URL.valueOf("override://0.0.0.0/dubbo.test.api.HelloService"));
-        registryDirectory.notify(durls);
-        invokers = registryDirectory.list(invocation);
-        aInvoker = invokers.get(0);
-        //Need to be restored to the original providerUrl
-        Assertions.assertEquals("1", aInvoker.getUrl().getParameter("timeout"));
-
-        Assertions.assertNull(registryDirectory.getConsumerUrl().getParameter("mock"));
-    }
-
-    /**
-     * Test the simultaneous push to clear the override and the override for a certain provider
-     * See if override can take effect
-     */
-    @Test
-    public void testNofityOverrideUrls_CleanNOverride() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        invocation = new RpcInvocation();
-
-        List<URL> durls = new ArrayList<URL>();
-        durls.add(SERVICEURL.setHost("10.20.30.140").addParameter("timeout", "1"));
-        registryDirectory.notify(durls);
-
-        durls = new ArrayList<URL>();
-        durls.add(URL.valueOf("override://0.0.0.0?timeout=3"));
-        durls.add(URL.valueOf("override://0.0.0.0"));
-        durls.add(URL.valueOf("override://10.20.30.140:9091?timeout=4"));
-        registryDirectory.notify(durls);
-
-        List<Invoker<?>> invokers = registryDirectory.list(invocation);
-        Invoker<?> aInvoker = invokers.get(0);
-        Assertions.assertEquals("4", aInvoker.getUrl().getParameter("timeout"));
-    }
-
-    /**
-     * Test override disables all service providers through enable=false
-     * Expectation: all service providers can not be disabled through override.
-     */
-    @Test
-    public void testNofityOverrideUrls_disabled_allProvider() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        invocation = new RpcInvocation();
-
-        List<URL> durls = new ArrayList<URL>();
-        durls.add(SERVICEURL.setHost("10.20.30.140"));
-        durls.add(SERVICEURL.setHost("10.20.30.141"));
-        registryDirectory.notify(durls);
-
-        durls = new ArrayList<URL>();
-        durls.add(URL.valueOf("override://0.0.0.0?" + ENABLED_KEY + "=false"));
-        registryDirectory.notify(durls);
-
-        List<Invoker<?>> invokers = registryDirectory.list(invocation);
-        //All service providers can not be disabled through override.
-        Assertions.assertEquals(2, invokers.size());
-    }
-
-    /**
-     * Test override disables a specified service provider through enable=false
-     * It is expected that a specified service provider can be disable.
-     */
-    @Test
-    public void testNofityOverrideUrls_disabled_specifiedProvider() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        invocation = new RpcInvocation();
-
-        List<URL> durls = new ArrayList<URL>();
-        durls.add(SERVICEURL.setHost("10.20.30.140"));
-        durls.add(SERVICEURL.setHost("10.20.30.141"));
-        registryDirectory.notify(durls);
-
-        durls = new ArrayList<URL>();
-        durls.add(URL.valueOf("override://10.20.30.140:9091?" + DISABLED_KEY + "=true"));
-        registryDirectory.notify(durls);
-
-        List<Invoker<?>> invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers.size());
-        Assertions.assertEquals("10.20.30.141", invokers.get(0).getUrl().getHost());
-
-        durls = new ArrayList<URL>();
-        durls.add(URL.valueOf("empty://0.0.0.0?" + DISABLED_KEY + "=true&" + CATEGORY_KEY + "=" + CONFIGURATORS_CATEGORY));
-        registryDirectory.notify(durls);
-        List<Invoker<?>> invokers2 = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers2.size());
-    }
-
-    /**
-     * Test override disables a specified service provider through enable=false
-     * It is expected that a specified service provider can be disable.
-     */
-    @Test
-    public void testNofity_To_Decrease_provider() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        invocation = new RpcInvocation();
-
-        List<URL> durls = new ArrayList<URL>();
-        durls.add(SERVICEURL.setHost("10.20.30.140"));
-        durls.add(SERVICEURL.setHost("10.20.30.141"));
-        registryDirectory.notify(durls);
-
-        List<Invoker<?>> invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers.size());
-
-        durls = new ArrayList<URL>();
-        durls.add(SERVICEURL.setHost("10.20.30.140"));
-        registryDirectory.notify(durls);
-        List<Invoker<?>> invokers2 = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers2.size());
-        Assertions.assertEquals("10.20.30.140", invokers2.get(0).getUrl().getHost());
-
-        durls = new ArrayList<URL>();
-        durls.add(URL.valueOf("empty://0.0.0.0?" + DISABLED_KEY + "=true&" + CATEGORY_KEY + "=" + CONFIGURATORS_CATEGORY));
-        registryDirectory.notify(durls);
-        List<Invoker<?>> invokers3 = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers3.size());
-    }
-
-    /**
-     * Test override disables a specified service provider through enable=false
-     * It is expected that a specified service provider can be disable.
-     */
-    @Test
-    public void testNofity_disabled_specifiedProvider() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        invocation = new RpcInvocation();
-
-        // Initially disable
-        List<URL> durls = new ArrayList<URL>();
-        durls.add(SERVICEURL.setHost("10.20.30.140").addParameter(ENABLED_KEY, "false"));
-        durls.add(SERVICEURL.setHost("10.20.30.141"));
-        registryDirectory.notify(durls);
-
-        List<Invoker<?>> invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers.size());
-        Assertions.assertEquals("10.20.30.141", invokers.get(0).getUrl().getHost());
-
-        //Enabled by override rule
-        durls = new ArrayList<URL>();
-        durls.add(URL.valueOf("override://10.20.30.140:9091?" + DISABLED_KEY + "=false"));
-        registryDirectory.notify(durls);
-        List<Invoker<?>> invokers2 = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers2.size());
-    }
-
-    @Test
-    public void testNotifyRouterUrls_Clean() {
-        if (isScriptUnsupported) return;
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-        URL routerurl = URL.valueOf(ROUTE_PROTOCOL + "://127.0.0.1:9096/").addParameter(ROUTER_KEY,
-                "javascript").addParameter(RULE_KEY,
-                "function test1(){}").addParameter(ROUTER_KEY,
-                "script"); // FIX
-        // BAD
-
-        List<URL> serviceUrls = new ArrayList<URL>();
-        // without ROUTER_KEY, the first router should not be created.
-        serviceUrls.add(routerurl);
-        registryDirectory.notify(serviceUrls);
-        // FIXME
-       /* List routers = registryDirectory.getRouters();
-        Assertions.assertEquals(1 + 1, routers.size());
-
-        serviceUrls.clear();
-        serviceUrls.add(routerurl.addParameter(Constants.ROUTER_KEY, Constants.ROUTER_TYPE_CLEAR));
-        registryDirectory.notify(serviceUrls);
-        routers = registryDirectory.getRouters();
-        Assertions.assertEquals(0 + 1, routers.size());*/
-    }
-
-    /**
-     * Test mock provider distribution
-     */
-    @Test
-    public void testNotify_MockProviderOnly() {
-        RegistryDirectory registryDirectory = getRegistryDirectory();
-
-        List<URL> serviceUrls = new ArrayList<URL>();
-        serviceUrls.add(SERVICEURL.addParameter("methods", "getXXX1"));
-        serviceUrls.add(SERVICEURL2.addParameter("methods", "getXXX1,getXXX2"));
-        serviceUrls.add(SERVICEURL.setProtocol(MOCK_PROTOCOL));
-
-        registryDirectory.notify(serviceUrls);
-        Assertions.assertTrue(registryDirectory.isAvailable());
-        invocation = new RpcInvocation();
-
-        List invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers.size());
-
-        RpcInvocation mockinvocation = new RpcInvocation();
-        mockinvocation.setAttachment(INVOCATION_NEED_MOCK, "true");
-        invokers = registryDirectory.list(mockinvocation);
-        Assertions.assertEquals(1, invokers.size());
-    }
-
-    // mock protocol
-
-    //Test the matching of protocol and select only the matched protocol for refer
-    @Test
-    public void test_Notified_acceptProtocol0() {
-        URL errorPathUrl = URL.valueOf("notsupport:/xxx?refer=" + URL.encode("interface=" + service));
-        RegistryDirectory registryDirectory = getRegistryDirectory(errorPathUrl);
-        List<URL> serviceUrls = new ArrayList<URL>();
-        URL dubbo1URL = URL.valueOf("dubbo://127.0.0.1:9098?lazy=true&methods=getXXX");
-        URL dubbo2URL = URL.valueOf("injvm://127.0.0.1:9099?lazy=true&methods=getXXX");
-        serviceUrls.add(dubbo1URL);
-        serviceUrls.add(dubbo2URL);
-        registryDirectory.notify(serviceUrls);
-
-        invocation = new RpcInvocation();
-
-        List<Invoker<DemoService>> invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers.size());
-    }
-
-    //Test the matching of protocol and select only the matched protocol for refer
-    @Test
-    public void test_Notified_acceptProtocol1() {
-        URL errorPathUrl = URL.valueOf("notsupport:/xxx");
-        errorPathUrl = errorPathUrl.addParameterAndEncoded(REFER_KEY, "interface=" + service + "&protocol=dubbo");
-        RegistryDirectory registryDirectory = getRegistryDirectory(errorPathUrl);
-        List<URL> serviceUrls = new ArrayList<URL>();
-        URL dubbo1URL = URL.valueOf("dubbo://127.0.0.1:9098?lazy=true&methods=getXXX");
-        URL dubbo2URL = URL.valueOf("injvm://127.0.0.1:9098?lazy=true&methods=getXXX");
-        serviceUrls.add(dubbo1URL);
-        serviceUrls.add(dubbo2URL);
-        registryDirectory.notify(serviceUrls);
-
-        invocation = new RpcInvocation();
-
-        List<Invoker<DemoService>> invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(1, invokers.size());
-    }
-
-    //Test the matching of protocol and select only the matched protocol for refer
-    @Test
-    public void test_Notified_acceptProtocol2() {
-        URL errorPathUrl = URL.valueOf("notsupport:/xxx");
-        errorPathUrl = errorPathUrl.addParameterAndEncoded(REFER_KEY, "interface=" + service + "&protocol=dubbo,injvm");
-        RegistryDirectory registryDirectory = getRegistryDirectory(errorPathUrl);
-        List<URL> serviceUrls = new ArrayList<URL>();
-        URL dubbo1URL = URL.valueOf("dubbo://127.0.0.1:9098?lazy=true&methods=getXXX");
-        URL dubbo2URL = URL.valueOf("injvm://127.0.0.1:9099?lazy=true&methods=getXXX");
-        serviceUrls.add(dubbo1URL);
-        serviceUrls.add(dubbo2URL);
-        registryDirectory.notify(serviceUrls);
-
-        invocation = new RpcInvocation();
-
-        List<Invoker<DemoService>> invokers = registryDirectory.list(invocation);
-        Assertions.assertEquals(2, invokers.size());
-    }
-
-    @Test
-    public void test_Notified_withGroupFilter() {
-        URL directoryUrl = noMeaningUrl.addParameterAndEncoded(REFER_KEY, "interface" + service + "&group=group1,group2");
-        RegistryDirectory directory = this.getRegistryDirectory(directoryUrl);
-        URL provider1 = URL.valueOf("dubbo://10.134.108.1:20880/" + service + "?methods=getXXX&group=group1&mock=false&application=mockApplication");
-        URL provider2 = URL.valueOf("dubbo://10.134.108.1:20880/" + service + "?methods=getXXX&group=group2&mock=false&application=mockApplication");
-
-        List<URL> providers = new ArrayList<>();
-        providers.add(provider1);
-        providers.add(provider2);
-        directory.notify(providers);
-
-        invocation = new RpcInvocation();
-        invocation.setMethodName("getXXX");
-        List<Invoker<DemoService>> invokers = directory.list(invocation);
-
-        Assertions.assertEquals(2, invokers.size());
-        Assertions.assertTrue(invokers.get(0) instanceof MockClusterInvoker);
-        Assertions.assertTrue(invokers.get(1) instanceof MockClusterInvoker);
-
-        directoryUrl = noMeaningUrl.addParameterAndEncoded(REFER_KEY, "interface" + service + "&group=group1");
-        directory = this.getRegistryDirectory(directoryUrl);
-        directory.notify(providers);
-
-        invokers = directory.list(invocation);
-
-        Assertions.assertEquals(2, invokers.size());
-        Assertions.assertFalse(invokers.get(0) instanceof MockClusterInvoker);
-        Assertions.assertFalse(invokers.get(1) instanceof MockClusterInvoker);
-    }
-
-    enum Param {
-        MORGAN,
-    }
-
-    private interface DemoService {
-    }
-
-    private static class MockRegistry implements Registry {
-
-        CountDownLatch latch;
-        boolean destroyWithError;
-
-        public MockRegistry(CountDownLatch latch) {
-            this.latch = latch;
-        }
-
-        public MockRegistry(boolean destroyWithError) {
-            this.destroyWithError = destroyWithError;
-        }
-
-        @Override
-        public void register(URL url) {
-
-        }
-
-        @Override
-        public void unregister(URL url) {
-
-        }
-
-        @Override
-        public void subscribe(URL url, NotifyListener listener) {
-
-        }
-
-        @Override
-        public void unsubscribe(URL url, NotifyListener listener) {
-            if (latch != null) latch.countDown();
-        }
-
-        @Override
-        public List<URL> lookup(URL url) {
-            return null;
-        }
-
-        public URL getUrl() {
-            return null;
-        }
-
-        @Override
-        public boolean isAvailable() {
-            return true;
-        }
-
-        @Override
-        public void destroy() {
-            if (destroyWithError) {
-                throw new RpcException("test exception ignore.");
-            }
-        }
-    }
-}
diff --git a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryProtocolTest.java b/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryProtocolTest.java
deleted file mode 100644
index 5e0d8a4..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryProtocolTest.java
+++ /dev/null
@@ -1,233 +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.registry.dubbo;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.ConfigurationUtils;
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.RegistryFactory;
-import org.apache.dubbo.registry.RegistryService;
-import org.apache.dubbo.registry.integration.RegistryProtocol;
-import org.apache.dubbo.registry.support.AbstractRegistry;
-import org.apache.dubbo.remoting.exchange.ExchangeClient;
-import org.apache.dubbo.rpc.Exporter;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.Protocol;
-import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.cluster.support.FailfastCluster;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.ServiceDescriptor;
-import org.apache.dubbo.rpc.protocol.AbstractInvoker;
-import org.apache.dubbo.rpc.protocol.dubbo.DubboInvoker;
-import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;
-
-import org.apache.commons.lang3.ArrayUtils;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static org.apache.dubbo.registry.integration.RegistryProtocol.DEFAULT_REGISTER_PROVIDER_KEYS;
-import static org.apache.dubbo.rpc.cluster.Constants.EXPORT_KEY;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-/**
- * RegistryProtocolTest
- */
-public class RegistryProtocolTest {
-
-    static {
-        SimpleRegistryExporter.exportIfAbsent(9090);
-    }
-
-    final String service = DemoService.class.getName() + ":1.0.0";
-    final String serviceUrl = "dubbo://127.0.0.1:9453/" + service + "?notify=true&methods=test1,test2&side=con&side=consumer";
-    final URL registryUrl = URL.valueOf("registry://127.0.0.1:9090/");
-    final private Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
-
-    public static RegistryProtocol getRegistryProtocol() {
-        return RegistryProtocol.getRegistryProtocol();
-    }
-
-    @BeforeEach
-    public void setUp() {
-        ApplicationModel.setApplication("RegistryProtocolTest");
-        ApplicationModel.getServiceRepository().registerService(RegistryService.class);
-    }
-
-    @Test
-    public void testDefaultPort() {
-        RegistryProtocol registryProtocol = getRegistryProtocol();
-        assertEquals(9090, registryProtocol.getDefaultPort());
-    }
-
-    @Test
-    public void testExportUrlNull() {
-        Assertions.assertThrows(IllegalArgumentException.class, () -> {
-            RegistryProtocol registryProtocol = getRegistryProtocol();
-            registryProtocol.setCluster(new FailfastCluster());
-
-            Protocol dubboProtocol = DubboProtocol.getDubboProtocol();
-            registryProtocol.setProtocol(dubboProtocol);
-            Invoker<DemoService> invoker = new DubboInvoker<DemoService>(DemoService.class,
-                    registryUrl, new ExchangeClient[]{new MockedClient("10.20.20.20", 2222, true)});
-            registryProtocol.export(invoker);
-        });
-    }
-
-    @Test
-    public void testExport() {
-        RegistryProtocol registryProtocol = getRegistryProtocol();
-        registryProtocol.setCluster(new FailfastCluster());
-        registryProtocol.setRegistryFactory(ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension());
-
-        Protocol dubboProtocol = DubboProtocol.getDubboProtocol();
-        registryProtocol.setProtocol(dubboProtocol);
-        URL newRegistryUrl = registryUrl.addParameter(EXPORT_KEY, serviceUrl);
-        DubboInvoker<DemoService> invoker = new DubboInvoker<DemoService>(DemoService.class,
-                newRegistryUrl, new ExchangeClient[]{new MockedClient("10.20.20.20", 2222, true)});
-        Exporter<DemoService> exporter = registryProtocol.export(invoker);
-        Exporter<DemoService> exporter2 = registryProtocol.export(invoker);
-        //The same invoker, exporter that multiple exported are different
-        Assertions.assertNotSame(exporter, exporter2);
-        exporter.unexport();
-        exporter2.unexport();
-
-    }
-
-//    @Test
-//    public void testNotifyOverride() throws Exception {
-//        URL newRegistryUrl = registryUrl.addParameter(EXPORT_KEY, serviceUrl);
-//        Invoker<RegistryProtocolTest> invoker = new MockInvoker<RegistryProtocolTest>(RegistryProtocolTest.class, newRegistryUrl);
-//
-//        ServiceDescriptor descriptor = ApplicationModel.getServiceRepository().registerService(DemoService.class);
-//        ApplicationModel.getServiceRepository().registerProvider(service, new DemoServiceImpl(), descriptor, null, null);
-//
-//        Exporter<?> exporter = protocol.export(invoker);
-//        RegistryProtocol rprotocol = getRegistryProtocol();
-//        NotifyListener listener = getListener(rprotocol);
-//        List<URL> urls = new ArrayList<URL>();
-//        urls.add(URL.valueOf("override://0.0.0.0/?timeout=1000"));
-//        urls.add(URL.valueOf("override://0.0.0.0/" + service + "?timeout=100"));
-//        urls.add(URL.valueOf("override://0.0.0.0/" + service + "?x=y"));
-//        listener.notify(urls);
-//
-//        assertTrue(exporter.getInvoker().isAvailable());
-//        assertEquals("100", exporter.getInvoker().getUrl().getParameter("timeout"));
-//        assertEquals("y", exporter.getInvoker().getUrl().getParameter("x"));
-//
-//        exporter.unexport();
-////        int timeout = ConfigUtils.getServerShutdownTimeout();
-////        Thread.sleep(timeout + 1000);
-////        assertEquals(false, exporter.getInvoker().isAvailable());
-//        destroyRegistryProtocol();
-//
-//    }
-
-
-    /**
-     * The name of the service does not match and can't override invoker
-     * Service name matching, service version number mismatch
-     */
-    @Test
-    public void testNotifyOverride_notmatch() throws Exception {
-        URL newRegistryUrl = registryUrl.addParameter(EXPORT_KEY, serviceUrl);
-        Invoker<RegistryProtocolTest> invoker = new MockInvoker<RegistryProtocolTest>(RegistryProtocolTest.class, newRegistryUrl);
-
-        ServiceDescriptor descriptor = ApplicationModel.getServiceRepository().registerService(DemoService.class);
-        ApplicationModel.getServiceRepository().registerProvider(service, new DemoServiceImpl(), descriptor, null, null);
-
-        Exporter<?> exporter = protocol.export(invoker);
-        RegistryProtocol rprotocol = getRegistryProtocol();
-        NotifyListener listener = getListener(rprotocol);
-        List<URL> urls = new ArrayList<URL>();
-        urls.add(URL.valueOf("override://0.0.0.0/org.apache.dubbo.registry.protocol.HackService?timeout=100"));
-        listener.notify(urls);
-        assertTrue(exporter.getInvoker().isAvailable());
-        assertNull(exporter.getInvoker().getUrl().getParameter("timeout"));
-        exporter.unexport();
-        destroyRegistryProtocol();
-    }
-
-    /**
-     * Test destory registry, exporter can be normal by destroyed
-     */
-    @Test
-    public void testDestoryRegistry() {
-        URL newRegistryUrl = registryUrl.addParameter(EXPORT_KEY, serviceUrl);
-        Invoker<RegistryProtocolTest> invoker = new MockInvoker<RegistryProtocolTest>(RegistryProtocolTest.class, newRegistryUrl);
-        Exporter<?> exporter = protocol.export(invoker);
-        destroyRegistryProtocol();
-        try {
-            Thread.sleep(ConfigurationUtils.getServerShutdownTimeout() + 100);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-        assertFalse(exporter.getInvoker().isAvailable());
-
-    }
-
-    @Test
-    public void testGetParamsToRegistry() {
-        RegistryProtocol registryProtocol = getRegistryProtocol();
-        String[] additionalParams = new String[]{"key1", "key2"};
-        String[] registryParams = registryProtocol.getParamsToRegistry(DEFAULT_REGISTER_PROVIDER_KEYS, additionalParams);
-        String[] expectParams = ArrayUtils.addAll(DEFAULT_REGISTER_PROVIDER_KEYS, additionalParams);
-        Assertions.assertArrayEquals(expectParams, registryParams);
-    }
-
-    private void destroyRegistryProtocol() {
-        Protocol registry = getRegistryProtocol();
-        registry.destroy();
-    }
-
-    private NotifyListener getListener(RegistryProtocol protocol) throws Exception {
-        return protocol.getOverrideListeners().values().iterator().next();
-    }
-
-    static class MockInvoker<T> extends AbstractInvoker<T> {
-        public MockInvoker(Class<T> type, URL url) {
-            super(type, url);
-        }
-
-        @Override
-        protected Result doInvoke(Invocation invocation) throws Throwable {
-            //do nothing
-            return null;
-        }
-    }
-
-    static class MockRegistry extends AbstractRegistry {
-
-        public MockRegistry(URL url) {
-            super(url);
-        }
-
-        @Override
-        public boolean isAvailable() {
-            return true;
-        }
-    }
-
-}
diff --git a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryStatusCheckerTest.java b/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryStatusCheckerTest.java
deleted file mode 100644
index a33a858..0000000
--- a/dubbo-spi-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/RegistryStatusCheckerTest.java
+++ /dev/null
@@ -1,69 +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.registry.dubbo;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.common.status.Status;
-import org.apache.dubbo.registry.RegistryFactory;
-import org.apache.dubbo.registry.RegistryService;
-import org.apache.dubbo.registry.status.RegistryStatusChecker;
-import org.apache.dubbo.registry.support.AbstractRegistryFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
... 69543 lines suppressed ...