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/08/23 05:24:33 UTC

[dubbo] branch 3.0 updated: [3.0] Verify additional configuration during service reference (#8543)

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

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


The following commit(s) were added to refs/heads/3.0 by this push:
     new 2d26e11  [3.0] Verify additional configuration during service reference (#8543)
2d26e11 is described below

commit 2d26e11458790c34abc8ef2240e0246e71877d31
Author: huazhongming <cr...@gmail.com>
AuthorDate: Mon Aug 23 13:24:22 2021 +0800

    [3.0] Verify additional configuration during service reference (#8543)
    
    * verify additional parameters
    
    * reset static mock
    
    * fix test
    
    * close
---
 .../dubbo/common/constants/CommonConstants.java    |  18 +-
 .../org/apache/dubbo/common/utils/ConfigUtils.java |   3 +-
 .../org/apache/dubbo/config/AbstractConfig.java    |   2 +-
 .../org/apache/dubbo/config/ApplicationConfig.java |  32 +-
 .../java/org/apache/dubbo/config/ModuleConfig.java |   2 +
 .../dubbo/config/AbstractInterfaceConfigTest.java  |  70 +---
 .../java/org/apache/dubbo/config/Greeting.java     |  24 ++
 .../org/apache/dubbo/config/GreetingLocal1.java    |  21 ++
 .../org/apache/dubbo/config/GreetingLocal2.java    |  24 ++
 .../org/apache/dubbo/config/GreetingLocal3.java    |  30 ++
 .../org/apache/dubbo/config/ReferenceConfig.java   |   2 +-
 .../apache/dubbo/config/ReferenceConfigTest.java   | 377 ++++++++++++++++++++-
 .../dubbo/config/bootstrap/DubboBootstrapTest.java |  11 +-
 .../org/apache/dubbo/config/url/UrlTestBase.java   |  61 ++--
 .../config/utils/ConfigValidationUtilsTest.java    |  63 ++++
 15 files changed, 611 insertions(+), 129 deletions(-)

diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
index 87bfe54..5f2ef2d 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
@@ -27,7 +27,7 @@ import java.util.regex.Pattern;
 public interface CommonConstants {
     String DUBBO = "dubbo";
 
-    String TRIPLE= "tri";
+    String TRIPLE = "tri";
 
     String PROVIDER = "provider";
 
@@ -35,6 +35,18 @@ public interface CommonConstants {
 
     String APPLICATION_KEY = "application";
 
+    String APPLICATION_VERSION_KEY = "application.version";
+
+    String APPLICATION_PROTOCOL_KEY = "application-protocol";
+
+    String METADATA_SERVICE_PORT_KEY = "metadata-service-port";
+
+    String LIVENESS_PROBE_KEY = "liveness-probe";
+
+    String READINESS_PROBE_KEY = "readiness-probe";
+
+    String STARTUP_PROBE = "startup-probe";
+
     String REMOTE_APPLICATION_KEY = "remote.application";
 
     String ENABLED_KEY = "enabled";
@@ -413,7 +425,9 @@ public interface CommonConstants {
 
     String UTF8ENCODE = "UTF-8";
 
-    /** Pseudo URL prefix for loading from the class path: "classpath:". */
+    /**
+     * Pseudo URL prefix for loading from the class path: "classpath:".
+     */
     String CLASSPATH_URL_PREFIX = "classpath:";
 
     String DEFAULT_VERSION = "0.0.0";
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConfigUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConfigUtils.java
index 93d01ce..5a55ce2 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConfigUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ConfigUtils.java
@@ -384,7 +384,8 @@ public class ConfigUtils {
         if (PID < 0) {
             try {
                 RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
-                String name = runtime.getName(); // format: "pid@hostname"
+                // format: "pid@hostname"
+                String name = runtime.getName();
                 PID = Integer.parseInt(name.substring(0, name.indexOf('@')));
             } catch (Throwable e) {
                 PID = 0;
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
index 1d685c9..249fd3e 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
@@ -146,7 +146,7 @@ public abstract class AbstractConfig implements Serializable {
 
         // How to select the appropriate one from multiple getter methods of the property?
         // e.g. Using String getGeneric() or Boolean isGeneric()? Judge by field type ?
-        // Currently use @Parameter.attribute() to determine whether it is an attribute.
+        // Currently, use @Parameter.attribute() to determine whether it is an attribute.
 
         BeanInfo beanInfo = getBeanInfo(config.getClass());
         for (MethodDescriptor methodDescriptor : beanInfo.getMethodDescriptors()) {
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
index 2a2758a..4521c6b 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java
@@ -40,6 +40,12 @@ import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_LOCAL_FILE_CACHE_ENABLED;
 import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_VERSION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_PROTOCOL_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PORT_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.LIVENESS_PROBE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.READINESS_PROBE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.STARTUP_PROBE;
 import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP;
 import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE;
 import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST;
@@ -217,7 +223,7 @@ public class ApplicationConfig extends AbstractConfig {
         //this.updateIdIfAbsent(name);
     }
 
-    @Parameter(key = "application.version")
+    @Parameter(key = APPLICATION_VERSION_KEY)
     public String getVersion() {
         return version;
     }
@@ -257,15 +263,15 @@ public class ApplicationConfig extends AbstractConfig {
     public void setEnvironment(String environment) {
         if (environment != null) {
             if (!(DEVELOPMENT_ENVIRONMENT.equals(environment)
-                    || TEST_ENVIRONMENT.equals(environment)
-                    || PRODUCTION_ENVIRONMENT.equals(environment))) {
+                || TEST_ENVIRONMENT.equals(environment)
+                || PRODUCTION_ENVIRONMENT.equals(environment))) {
 
                 throw new IllegalStateException(String.format("Unsupported environment: %s, only support %s/%s/%s, default is %s.",
-                        environment,
-                        DEVELOPMENT_ENVIRONMENT,
-                        TEST_ENVIRONMENT,
-                        PRODUCTION_ENVIRONMENT,
-                        PRODUCTION_ENVIRONMENT));
+                    environment,
+                    DEVELOPMENT_ENVIRONMENT,
+                    TEST_ENVIRONMENT,
+                    PRODUCTION_ENVIRONMENT,
+                    PRODUCTION_ENVIRONMENT));
             }
         }
         this.environment = environment;
@@ -495,7 +501,7 @@ public class ApplicationConfig extends AbstractConfig {
         this.publishInstance = publishInstance;
     }
 
-    @Parameter(excluded = true, key="application-protocol")
+    @Parameter(excluded = true, key = APPLICATION_PROTOCOL_KEY)
     public String getProtocol() {
         return protocol;
     }
@@ -504,7 +510,7 @@ public class ApplicationConfig extends AbstractConfig {
         this.protocol = protocol;
     }
 
-    @Parameter(key = "metadata-service-port")
+    @Parameter(key = METADATA_SERVICE_PORT_KEY)
     public Integer getMetadataServicePort() {
         return metadataServicePort;
     }
@@ -513,7 +519,7 @@ public class ApplicationConfig extends AbstractConfig {
         this.metadataServicePort = metadataServicePort;
     }
 
-    @Parameter(key = "liveness-probe")
+    @Parameter(key = LIVENESS_PROBE_KEY)
     public String getLivenessProbe() {
         return livenessProbe;
     }
@@ -522,7 +528,7 @@ public class ApplicationConfig extends AbstractConfig {
         this.livenessProbe = livenessProbe;
     }
 
-    @Parameter(key = "readiness-probe")
+    @Parameter(key = READINESS_PROBE_KEY)
     public String getReadinessProbe() {
         return readinessProbe;
     }
@@ -531,7 +537,7 @@ public class ApplicationConfig extends AbstractConfig {
         this.readinessProbe = readinessProbe;
     }
 
-    @Parameter(key = "startup-probe")
+    @Parameter(key = STARTUP_PROBE)
     public String getStartupProbe() {
         return startupProbe;
     }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ModuleConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ModuleConfig.java
index 9033a1c..b8b10a3 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/ModuleConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ModuleConfig.java
@@ -87,6 +87,7 @@ public class ModuleConfig extends AbstractConfig {
         this.version = version;
     }
 
+    @Parameter(key = "module.owner")
     public String getOwner() {
         return owner;
     }
@@ -95,6 +96,7 @@ public class ModuleConfig extends AbstractConfig {
         this.owner = owner;
     }
 
+    @Parameter(key = "module.organization")
     public String getOrganization() {
         return organization;
     }
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java b/dubbo-common/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
similarity index 76%
rename from dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
rename to dubbo-common/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
index 38bbcc9..c9044fe 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java
@@ -16,21 +16,12 @@
  */
 package org.apache.dubbo.config;
 
-import org.apache.dubbo.common.constants.CommonConstants;
-import org.apache.dubbo.config.api.Greeting;
-import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.config.mock.GreetingLocal1;
-import org.apache.dubbo.config.mock.GreetingLocal2;
-import org.apache.dubbo.config.mock.GreetingLocal3;
-import org.apache.dubbo.config.mock.GreetingMock1;
-import org.apache.dubbo.config.mock.GreetingMock2;
-import org.apache.dubbo.config.utils.ConfigValidationUtils;
 
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.AfterEach;
+import org.apache.dubbo.common.constants.CommonConstants;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.io.TempDir;
 
 import java.io.File;
@@ -38,110 +29,67 @@ import java.nio.file.Path;
 import java.util.Collections;
 
 public class AbstractInterfaceConfigTest {
-    private static File dubboProperties;
 
     @BeforeAll
     public static void setUp(@TempDir Path folder) {
-        DubboBootstrap.reset();
-        dubboProperties = folder.resolve(CommonConstants.DUBBO_PROPERTIES_KEY).toFile();
+        File dubboProperties = folder.resolve(CommonConstants.DUBBO_PROPERTIES_KEY).toFile();
         System.setProperty(CommonConstants.DUBBO_PROPERTIES_KEY, dubboProperties.getAbsolutePath());
     }
 
     @AfterAll
     public static void tearDown() {
-        DubboBootstrap.reset();
         System.clearProperty(CommonConstants.DUBBO_PROPERTIES_KEY);
     }
 
-    @AfterEach
-    public void tearMethodAfterEachUT() {
-        DubboBootstrap.reset();
-    }
 
     @Test
-    public void checkStubAndMock1() {
+    public void checkStub1() {
         Assertions.assertThrows(IllegalStateException.class, () -> {
             InterfaceConfig interfaceConfig = new InterfaceConfig();
             interfaceConfig.setLocal(GreetingLocal1.class.getName());
             interfaceConfig.checkStubAndLocal(Greeting.class);
-            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
         });
     }
 
     @Test
-    public void checkStubAndMock2() {
+    public void checkStub2() {
         Assertions.assertThrows(IllegalStateException.class, () -> {
             InterfaceConfig interfaceConfig = new InterfaceConfig();
             interfaceConfig.setLocal(GreetingLocal2.class.getName());
             interfaceConfig.checkStubAndLocal(Greeting.class);
-            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
         });
     }
 
     @Test
-    public void checkStubAndMock3() {
+    public void checkStub3() {
         InterfaceConfig interfaceConfig = new InterfaceConfig();
         interfaceConfig.setLocal(GreetingLocal3.class.getName());
         interfaceConfig.checkStubAndLocal(Greeting.class);
-        ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
     }
 
     @Test
-    public void checkStubAndMock4() {
+    public void checkStub4() {
         Assertions.assertThrows(IllegalStateException.class, () -> {
             InterfaceConfig interfaceConfig = new InterfaceConfig();
             interfaceConfig.setStub(GreetingLocal1.class.getName());
             interfaceConfig.checkStubAndLocal(Greeting.class);
-            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
         });
     }
 
     @Test
-    public void checkStubAndMock5() {
+    public void checkStub5() {
         Assertions.assertThrows(IllegalStateException.class, () -> {
             InterfaceConfig interfaceConfig = new InterfaceConfig();
             interfaceConfig.setStub(GreetingLocal2.class.getName());
             interfaceConfig.checkStubAndLocal(Greeting.class);
-            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
         });
     }
 
     @Test
-    public void checkStubAndMock6() {
+    public void checkStub6() {
         InterfaceConfig interfaceConfig = new InterfaceConfig();
         interfaceConfig.setStub(GreetingLocal3.class.getName());
         interfaceConfig.checkStubAndLocal(Greeting.class);
-        ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
-    }
-
-    @Test
-    public void checkStubAndMock7() {
-        Assertions.assertThrows(IllegalStateException.class, () -> {
-            InterfaceConfig interfaceConfig = new InterfaceConfig();
-            interfaceConfig.setMock("return {a, b}");
-            interfaceConfig.checkStubAndLocal(Greeting.class);
-            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
-        });
-    }
-
-    @Test
-    public void checkStubAndMock8() {
-        Assertions.assertThrows(IllegalStateException.class, () -> {
-            InterfaceConfig interfaceConfig = new InterfaceConfig();
-            interfaceConfig.setMock(GreetingMock1.class.getName());
-            interfaceConfig.checkStubAndLocal(Greeting.class);
-            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
-        });
-    }
-
-    @Test
-    public void checkStubAndMock9() {
-        Assertions.assertThrows(IllegalStateException.class, () -> {
-            InterfaceConfig interfaceConfig = new InterfaceConfig();
-            interfaceConfig.setMock(GreetingMock2.class.getName());
-            interfaceConfig.checkStubAndLocal(Greeting.class);
-            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
-        });
     }
 
     @Test
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/config/Greeting.java b/dubbo-common/src/test/java/org/apache/dubbo/config/Greeting.java
new file mode 100644
index 0000000..4ee8fc5
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/config/Greeting.java
@@ -0,0 +1,24 @@
+/*
+ * 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.config;
+
+import org.apache.dubbo.common.extension.SPI;
+
+@SPI
+public interface Greeting {
+    String hello();
+}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/config/GreetingLocal1.java b/dubbo-common/src/test/java/org/apache/dubbo/config/GreetingLocal1.java
new file mode 100644
index 0000000..212758e
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/config/GreetingLocal1.java
@@ -0,0 +1,21 @@
+/*
+ * 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.config;
+
+public class GreetingLocal1 {
+
+}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/config/GreetingLocal2.java b/dubbo-common/src/test/java/org/apache/dubbo/config/GreetingLocal2.java
new file mode 100644
index 0000000..e25653c
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/config/GreetingLocal2.java
@@ -0,0 +1,24 @@
+/*
+ * 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.config;
+
+public class GreetingLocal2 implements Greeting {
+    @Override
+    public String hello() {
+        return "local";
+    }
+}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/config/GreetingLocal3.java b/dubbo-common/src/test/java/org/apache/dubbo/config/GreetingLocal3.java
new file mode 100644
index 0000000..37e2bf9
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/config/GreetingLocal3.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config;
+
+public class GreetingLocal3 implements Greeting {
+    private Greeting greeting;
+
+    public GreetingLocal3(Greeting greeting) {
+        this.greeting = greeting;
+    }
+
+    @Override
+    public String hello() {
+        return null;
+    }
+}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index 9063c1c..894b34e 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@ -570,7 +570,7 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
         URL tmpUrl = new ServiceConfigURL("temp", "localhost", 0, map);
         boolean isJvmRefer;
         if (isInjvm() == null) {
-            // if a url is specified, don't do local reference
+            // if an url is specified, don't do local reference
             if (url != null && url.length() > 0) {
                 isJvmRefer = false;
             } else {
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
index b6c45dc..71e5878 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
@@ -16,33 +16,89 @@
  */
 package org.apache.dubbo.config;
 
+import org.apache.dubbo.common.Version;
+import org.apache.dubbo.common.config.CompositeConfiguration;
+import org.apache.dubbo.common.config.Configuration;
+import org.apache.dubbo.common.config.Environment;
+import org.apache.dubbo.common.utils.ConfigUtils;
 import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.config.annotation.Argument;
 import org.apache.dubbo.config.annotation.Method;
 import org.apache.dubbo.config.annotation.Reference;
 import org.apache.dubbo.config.api.DemoService;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
+import org.apache.dubbo.config.context.ConfigManager;
 import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
 
+import org.apache.dubbo.metadata.report.MetadataReport;
+import org.apache.dubbo.metadata.report.MetadataReportInstance;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.curator.test.TestingServer;
+import org.apache.dubbo.rpc.model.ConsumerModel;
+import org.apache.dubbo.rpc.model.ServiceMetadata;
+import org.apache.dubbo.rpc.model.ServiceRepository;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
 
 import java.io.IOException;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.Optional;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
-import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+
+import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
+import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.METRICS_PROTOCOL;
+import static org.apache.dubbo.common.constants.CommonConstants.METRICS_PORT;
+import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_VERSION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.DUMP_DIRECTORY;
+import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_LOCAL_FILE_CACHE_ENABLED;
+import static org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PORT_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.LIVENESS_PROBE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.READINESS_PROBE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.STARTUP_PROBE;
+import static org.apache.dubbo.common.constants.CommonConstants.URL_MERGE_PROCESSOR_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.REFER_THREAD_NUM_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.REFER_BACKGROUND_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.REFER_ASYNC_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
+
+
+import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE;
+import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST;
+import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT;
+import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP;
+import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PUBLISH_INSTANCE_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PUBLISH_INTERFACE_KEY;
+import static org.apache.dubbo.registry.Constants.ENABLE_CONFIGURATION_LISTEN;
+import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
 import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
+import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
+import static org.apache.dubbo.rpc.Constants.DEFAULT_STUB_EVENT;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class ReferenceConfigTest {
     private TestingServer zkServer;
@@ -55,9 +111,6 @@ public class ReferenceConfigTest {
         this.zkServer = new TestingServer(zkServerPort, true);
         this.zkServer.start();
         this.registryUrl = "zookeeper://localhost:" + zkServerPort;
-
-        // preload
-        ReferenceConfig preloadReferenceConfig = new ReferenceConfig();
         ApplicationModel.getConfigManager();
         DubboBootstrap.getInstance();
     }
@@ -66,6 +119,296 @@ public class ReferenceConfigTest {
     public void tearDown() throws IOException {
         DubboBootstrap.reset();
         zkServer.stop();
+        Mockito.framework().clearInlineMocks();
+
+    }
+
+    /**
+     * Test whether the configuration required for the aggregation service reference meets expectations
+     */
+    @Test
+    public void testAppendConfig() {
+
+        ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
+        referenceConfig.setClient("netty");
+        referenceConfig.setGeneric(Boolean.FALSE.toString());
+        referenceConfig.setProtocol("dubbo");
+        referenceConfig.setInit(true);
+        referenceConfig.setLazy(false);
+        referenceConfig.setInjvm(false);
+        referenceConfig.setReconnect("reconnect");
+        referenceConfig.setSticky(false);
+        referenceConfig.setStub(DEFAULT_STUB_EVENT);
+        referenceConfig.setRouter("default");
+        referenceConfig.setReferAsync(true);
+
+        DubboBootstrap.getInstance()
+            .application("application1")
+            .initialize();
+        referenceConfig.setBootstrap(DubboBootstrap.getInstance());
+
+        ApplicationConfig applicationConfig = new ApplicationConfig();
+        applicationConfig.setName("application1");
+        applicationConfig.setVersion("v1");
+        applicationConfig.setOwner("owner1");
+        applicationConfig.setOrganization("bu1");
+        applicationConfig.setArchitecture("architecture1");
+        applicationConfig.setEnvironment("test");
+        applicationConfig.setCompiler("javassist");
+        applicationConfig.setLogger("log4j");
+        applicationConfig.setDumpDirectory("/");
+        applicationConfig.setQosEnable(false);
+        applicationConfig.setQosHost("127.0.0.1");
+        applicationConfig.setQosPort(77777);
+        applicationConfig.setQosAcceptForeignIp(false);
+        Map<String, String> parameters = new HashMap<>();
+        parameters.put("key1", "value1");
+        parameters.put("key2", "value2");
+        applicationConfig.setParameters(parameters);
+        applicationConfig.setShutwait("5");
+        applicationConfig.setMetadataType("local");
+        applicationConfig.setRegisterConsumer(false);
+        applicationConfig.setRepository("repository1");
+        applicationConfig.setEnableFileCache(false);
+        applicationConfig.setPublishInstance(false);
+        applicationConfig.setPublishInterface(false);
+        applicationConfig.setProtocol("dubbo");
+        applicationConfig.setMetadataServicePort(88888);
+        applicationConfig.setLivenessProbe("livenessProbe");
+        applicationConfig.setReadinessProbe("readinessProb");
+        applicationConfig.setStartupProbe("startupProbe");
+
+        MonitorConfig monitorConfig = new MonitorConfig();
+        applicationConfig.setMonitor(monitorConfig);
+
+        MetricsConfig metricsConfig = new MetricsConfig();
+        metricsConfig.setProtocol("metricProtocol");
+        metricsConfig.setPort("55555");
+
+        ModuleConfig moduleConfig = new ModuleConfig();
+        moduleConfig.setMonitor("default");
+        moduleConfig.setName("module1");
+        moduleConfig.setOrganization("application1");
+        moduleConfig.setVersion("v1");
+        moduleConfig.setOwner("owner1");
+
+        ConsumerConfig consumerConfig = new ConsumerConfig();
+        consumerConfig.setClient("netty");
+        consumerConfig.setThreadpool("fixed");
+        consumerConfig.setCorethreads(200);
+        consumerConfig.setQueues(500);
+        consumerConfig.setThreads(300);
+        consumerConfig.setShareconnections(10);
+        consumerConfig.setUrlMergeProcessor("default");
+        consumerConfig.setReferThreadNum(20);
+        consumerConfig.setReferBackground(false);
+        referenceConfig.setConsumer(consumerConfig);
+
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setName("method1");
+        methodConfig.setStat(1);
+        methodConfig.setRetries(0);
+        methodConfig.setExecutes(10);
+        methodConfig.setDeprecated(false);
+        methodConfig.setSticky(false);
+        methodConfig.setReturn(false);
+        methodConfig.setService("service");
+        methodConfig.setServiceId(DemoService.class.getName());
+        methodConfig.setParentPrefix("demo");
+
+
+        referenceConfig.setMethods(Collections.singletonList(methodConfig));
+
+        ConfigManager configManager = mock(ConfigManager.class);
+        Environment environment = mock(Environment.class);
+        CompositeConfiguration compositeConfiguration = mock(CompositeConfiguration.class);
+        Configuration dynamicGlobalConfiguration = mock(Configuration.class);
+        ServiceRepository serviceRepository = mock(ServiceRepository.class);
+        ConsumerModel consumerModel = mock(ConsumerModel.class);
+
+        when(configManager.getApplicationOrElseThrow()).thenReturn(applicationConfig);
+        when(configManager.getMetrics()).thenReturn(Optional.of(metricsConfig));
+        when(configManager.getModule()).thenReturn(Optional.of(moduleConfig));
+
+        MockedStatic<ApplicationModel> applicationModelMockedStatic = Mockito.mockStatic(ApplicationModel.class);
+        applicationModelMockedStatic.when(ApplicationModel::getConfigManager).thenReturn(configManager);
+        applicationModelMockedStatic.when(ApplicationModel::getEnvironment).thenReturn(environment);
+        applicationModelMockedStatic.when(ApplicationModel::getServiceRepository).thenReturn(serviceRepository);
+        when(environment.getConfiguration()).thenReturn(compositeConfiguration);
+        when(environment.getDynamicGlobalConfiguration()).thenReturn(dynamicGlobalConfiguration);
+        when(compositeConfiguration.convert(Boolean.class, ENABLE_CONFIGURATION_LISTEN, true))
+            .thenReturn(true);
+
+        MockedStatic<MetadataReportInstance> metadataReportInstanceMockedStatic =
+            Mockito.mockStatic(MetadataReportInstance.class);
+
+        MetadataReport metadataReport = mock(MetadataReport.class);
+        metadataReportInstanceMockedStatic.when(() -> MetadataReportInstance.getMetadataReport("default"))
+            .thenReturn(metadataReport);
+
+
+        when(serviceRepository.lookupReferredService("org.apache.dubbo.config.api.DemoService"))
+            .thenReturn(consumerModel);
+
+        referenceConfig.refreshed.set(true);
+        referenceConfig.setInterface(DemoService.class);
+        referenceConfig.getInterfaceClass();
+        referenceConfig.setCheck(false);
+        RegistryConfig registry = new RegistryConfig();
+        registry.setAddress(registryUrl);
+        applicationConfig.setRegistries(Collections.singletonList(registry));
+        applicationConfig.setRegistryIds(registry.getId());
+        moduleConfig.setRegistries(Collections.singletonList(registry));
+
+        referenceConfig.setRegistry(registry);
+
+        referenceConfig.init();
+
+        ServiceMetadata serviceMetadata = referenceConfig.getServiceMetadata();
+
+        // verify additional side parameter
+        Assertions.assertEquals(CONSUMER_SIDE, serviceMetadata.getAttachments().get(SIDE_KEY));
+
+        // verify additional interface parameter
+        Assertions.assertEquals(DemoService.class.getName(), serviceMetadata.getAttachments().get(INTERFACE_KEY));
+
+        // verify additional metadata-type parameter
+        Assertions.assertEquals(DEFAULT_METADATA_STORAGE_TYPE, serviceMetadata.getAttachments().get(METADATA_KEY));
+
+        // verify additional register.ip parameter
+        Assertions.assertEquals(NetUtils.getLocalHost(), serviceMetadata.getAttachments().get(REGISTER_IP_KEY));
+
+        // verify additional runtime parameters
+        Assertions.assertEquals(Version.getProtocolVersion(), serviceMetadata.getAttachments().get(DUBBO_VERSION_KEY));
+        Assertions.assertEquals(Version.getVersion(), serviceMetadata.getAttachments().get(RELEASE_KEY));
+        Assertions.assertTrue(serviceMetadata.getAttachments().containsKey(TIMESTAMP_KEY));
+        Assertions.assertEquals(String.valueOf(ConfigUtils.getPid()), serviceMetadata.getAttachments().get(PID_KEY));
+
+        // verify additional metric config
+        Assertions.assertEquals(metricsConfig.getProtocol(), serviceMetadata.getAttachments().get(METRICS_PROTOCOL));
+        Assertions.assertEquals(metricsConfig.getPort(), serviceMetadata.getAttachments().get(METRICS_PORT));
+
+        // verify additional application config
+        Assertions.assertEquals(applicationConfig.getName(), serviceMetadata.getAttachments().get(APPLICATION_KEY));
+        Assertions.assertEquals(applicationConfig.getOwner(), serviceMetadata.getAttachments().get("owner"));
+        Assertions.assertEquals(applicationConfig.getVersion(),
+            serviceMetadata.getAttachments().get(APPLICATION_VERSION_KEY));
+        Assertions.assertEquals(applicationConfig.getOrganization(),
+            serviceMetadata.getAttachments().get("organization"));
+        Assertions.assertEquals(applicationConfig.getArchitecture(),
+            serviceMetadata.getAttachments().get("architecture"));
+        Assertions.assertEquals(applicationConfig.getEnvironment(),
+            serviceMetadata.getAttachments().get("environment"));
+        Assertions.assertEquals(applicationConfig.getCompiler(), serviceMetadata.getAttachments().get("compiler"));
+        Assertions.assertEquals(applicationConfig.getLogger(), serviceMetadata.getAttachments().get("logger"));
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("registries"));
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("registry.ids"));
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("monitor"));
+        Assertions.assertEquals(applicationConfig.getDumpDirectory(),
+            serviceMetadata.getAttachments().get(DUMP_DIRECTORY));
+        Assertions.assertEquals(applicationConfig.getQosEnable().toString(),
+            serviceMetadata.getAttachments().get(QOS_ENABLE));
+        Assertions.assertEquals(applicationConfig.getQosHost(),
+            serviceMetadata.getAttachments().get(QOS_HOST));
+        Assertions.assertEquals(applicationConfig.getQosPort().toString(),
+            serviceMetadata.getAttachments().get(QOS_PORT));
+        Assertions.assertEquals(applicationConfig.getQosAcceptForeignIp().toString(),
+            serviceMetadata.getAttachments().get(ACCEPT_FOREIGN_IP));
+        Assertions.assertEquals(applicationConfig.getParameters().get("key1"),
+            serviceMetadata.getAttachments().get("key1"));
+        Assertions.assertEquals(applicationConfig.getParameters().get("key2"),
+            serviceMetadata.getAttachments().get("key2"));
+        Assertions.assertEquals(applicationConfig.getShutwait(),
+            serviceMetadata.getAttachments().get("shutwait"));
+        Assertions.assertEquals(applicationConfig.getMetadataType(),
+            serviceMetadata.getAttachments().get(METADATA_KEY));
+        Assertions.assertEquals(applicationConfig.getRegisterConsumer().toString(),
+            serviceMetadata.getAttachments().get("register.consumer"));
+        Assertions.assertEquals(applicationConfig.getRepository(),
+            serviceMetadata.getAttachments().get("repository"));
+        Assertions.assertEquals(applicationConfig.getEnableFileCache().toString(),
+            serviceMetadata.getAttachments().get(REGISTRY_LOCAL_FILE_CACHE_ENABLED));
+        Assertions.assertEquals(applicationConfig.getPublishInstance().toString(),
+            serviceMetadata.getAttachments().get(REGISTRY_PUBLISH_INSTANCE_KEY));
+        Assertions.assertEquals(applicationConfig.getPublishInterface().toString(),
+            serviceMetadata.getAttachments().get(REGISTRY_PUBLISH_INTERFACE_KEY));
+        Assertions.assertTrue(serviceMetadata.getAttachments().containsKey(REGISTRY_PUBLISH_INTERFACE_KEY));
+        Assertions.assertEquals(applicationConfig.getMetadataServicePort().toString(),
+            serviceMetadata.getAttachments().get(METADATA_SERVICE_PORT_KEY));
+        Assertions.assertEquals(applicationConfig.getLivenessProbe(),
+            serviceMetadata.getAttachments().get(LIVENESS_PROBE_KEY));
+        Assertions.assertEquals(applicationConfig.getReadinessProbe(),
+            serviceMetadata.getAttachments().get(READINESS_PROBE_KEY));
+        Assertions.assertEquals(applicationConfig.getStartupProbe(),
+            serviceMetadata.getAttachments().get(STARTUP_PROBE));
+
+        // verify additional module config
+        Assertions.assertEquals(moduleConfig.getName(), serviceMetadata.getAttachments().get("module"));
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("monitor"));
+        Assertions.assertEquals(moduleConfig.getOrganization(),
+            serviceMetadata.getAttachments().get("module.organization"));
+        Assertions.assertEquals(moduleConfig.getOwner(), serviceMetadata.getAttachments().get("module.owner"));
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("registries"));
+        Assertions.assertEquals(moduleConfig.getVersion(), serviceMetadata.getAttachments().get("module.version"));
+
+        // verify additional consumer config
+        Assertions.assertEquals(consumerConfig.getClient(), serviceMetadata.getAttachments().get("client"));
+        Assertions.assertEquals(consumerConfig.getThreadpool(), serviceMetadata.getAttachments().get("threadpool"));
+        Assertions.assertEquals(consumerConfig.getCorethreads().toString(),
+            serviceMetadata.getAttachments().get("corethreads"));
+        Assertions.assertEquals(consumerConfig.getQueues().toString(),
+            serviceMetadata.getAttachments().get("queues"));
+        Assertions.assertEquals(consumerConfig.getThreads().toString(),
+            serviceMetadata.getAttachments().get("threads"));
+        Assertions.assertEquals(consumerConfig.getShareconnections().toString(),
+            serviceMetadata.getAttachments().get("shareconnections"));
+        Assertions.assertEquals(consumerConfig.getUrlMergeProcessor(),
+            serviceMetadata.getAttachments().get(URL_MERGE_PROCESSOR_KEY));
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey(REFER_THREAD_NUM_KEY));
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey(REFER_BACKGROUND_KEY));
+
+        // verify additional reference config
+        Assertions.assertEquals(referenceConfig.getClient(), serviceMetadata.getAttachments().get("client"));
+        Assertions.assertEquals(referenceConfig.getGeneric(), serviceMetadata.getAttachments().get("generic"));
+        Assertions.assertEquals(referenceConfig.getProtocol(), serviceMetadata.getAttachments().get("protocol"));
+        Assertions.assertEquals(referenceConfig.isInit().toString(), serviceMetadata.getAttachments().get("init"));
+        Assertions.assertEquals(referenceConfig.getLazy().toString(), serviceMetadata.getAttachments().get("lazy"));
+        Assertions.assertEquals(referenceConfig.isInjvm().toString(), serviceMetadata.getAttachments().get("injvm"));
+        Assertions.assertEquals(referenceConfig.getReconnect(), serviceMetadata.getAttachments().get("reconnect"));
+        Assertions.assertEquals(referenceConfig.getSticky().toString(), serviceMetadata.getAttachments().get("sticky"));
+        Assertions.assertEquals(referenceConfig.getStub(), serviceMetadata.getAttachments().get("stub"));
+        Assertions.assertEquals(referenceConfig.getProvidedBy(), serviceMetadata.getAttachments().get("provided-by"));
+        Assertions.assertEquals(referenceConfig.getRouter(), serviceMetadata.getAttachments().get("router"));
+        Assertions.assertEquals(referenceConfig.getReferAsync().toString(),
+            serviceMetadata.getAttachments().get(REFER_ASYNC_KEY));
+
+        // verify additional method config
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("name"));
+        Assertions.assertEquals(methodConfig.getStat().toString(),
+            serviceMetadata.getAttachments().get("method1.stat"));
+        Assertions.assertEquals(methodConfig.getRetries().toString(),
+            serviceMetadata.getAttachments().get("method1.retries"));
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("method1.reliable"));
+        Assertions.assertEquals(methodConfig.getExecutes().toString(),
+            serviceMetadata.getAttachments().get("method1.executes"));
+        Assertions.assertEquals(methodConfig.getDeprecated().toString(),
+            serviceMetadata.getAttachments().get("method1.deprecated"));
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("method1.stick"));
+        Assertions.assertEquals(methodConfig.isReturn().toString(),
+            serviceMetadata.getAttachments().get("method1.return"));
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("method1.service"));
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("method1.service.id"));
+        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("method1.parent.prefix"));
+
+        // verify additional revision and methods parameter
+        Assertions.assertEquals(Version.getVersion(referenceConfig.getInterfaceClass(), referenceConfig.getVersion()),
+            serviceMetadata.getAttachments().get(REVISION_KEY));
+        Assertions.assertTrue(serviceMetadata.getAttachments().containsKey(METHODS_KEY));
+        Assertions.assertEquals(DemoService.class.getMethods().length,
+            StringUtils.split((String) serviceMetadata.getAttachments().get(METHODS_KEY), ',').length);
+
+        applicationModelMockedStatic.closeOnDemand();
+        metadataReportInstanceMockedStatic.closeOnDemand();
     }
 
     @Test
@@ -98,8 +441,8 @@ public class ReferenceConfigTest {
             System.setProperty("java.net.preferIPv4Stack", "true");
             demoService.export();
             rc.get();
-            Assertions.assertTrue(!LOCAL_PROTOCOL.equalsIgnoreCase(
-                    rc.getInvoker().getUrl().getProtocol()));
+            Assertions.assertFalse(LOCAL_PROTOCOL.equalsIgnoreCase(
+                rc.getInvoker().getUrl().getProtocol()));
         } finally {
             System.clearProperty("java.net.preferIPv4Stack");
             rc.destroy();
@@ -125,7 +468,7 @@ public class ReferenceConfigTest {
         ProtocolConfig protocol = new ProtocolConfig();
         protocol.setName("mockprotocol");
 
-        ReferenceConfig<DemoService> rc = new ReferenceConfig<DemoService>();
+        ReferenceConfig<DemoService> rc = new ReferenceConfig<>();
         rc.setRegistry(registry);
         rc.setInterface(DemoService.class.getName());
 
@@ -140,7 +483,7 @@ public class ReferenceConfigTest {
         Assertions.assertFalse(success);
         Assertions.assertNull(demoService);
 
-        ServiceConfig<DemoService> sc = new ServiceConfig<DemoService>();
+        ServiceConfig<DemoService> sc = new ServiceConfig<>();
         sc.setInterface(DemoService.class);
         sc.setRef(new DemoServiceImpl());
         sc.setRegistry(registry);
@@ -167,7 +510,7 @@ public class ReferenceConfigTest {
     public void testMetaData() {
         ReferenceConfig config = new ReferenceConfig();
         Map<String, String> metaData = config.getMetaData();
-        Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: "+metaData);
+        Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: " + metaData);
 
         // test merged and override consumer attributes
         ConsumerConfig consumerConfig = new ConsumerConfig();
@@ -218,16 +561,16 @@ public class ReferenceConfigTest {
         long t1 = System.currentTimeMillis();
         int nThreads = 8;
         ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
-        for(int i=0;i<nThreads;i++) {
-            int perCount = (int) (1.0* amount / nThreads);
+        for (int i = 0; i < nThreads; i++) {
+            int perCount = (int) (1.0 * amount / nThreads);
             int start = perCount * i;
             int end = start + perCount;
             if (i == nThreads - 1) {
                 end = amount;
             }
             int finalEnd = end;
-            System.out.println(String.format("start thread %s: range: %s - %s, count: %s", i, start, end, (end-start)));
-            executorService.submit(()->{
+            System.out.println(String.format("start thread %s: range: %s - %s, count: %s", i, start, end, (end - start)));
+            executorService.submit(() -> {
                 testInitReferences(start, finalEnd, applicationConfig, metadataReportConfig, configCenterConfig);
             });
         }
@@ -238,7 +581,7 @@ public class ReferenceConfigTest {
         long cost = t2 - t1;
         System.out.println("Init large references cost: " + cost + "ms");
         Assertions.assertEquals(amount, DubboBootstrap.getInstance().getConfigManager().getReferences().size());
-        Assertions.assertTrue( cost < 1000, "Init large references too slowly: "+cost);
+        Assertions.assertTrue(cost < 1000, "Init large references too slowly: " + cost);
 
         //test equals
         testSearchReferences();
@@ -254,7 +597,7 @@ public class ReferenceConfigTest {
         long cost = t2 - t1;
         System.out.println("Search large references cost: " + cost + "ms");
         Assertions.assertEquals(1, results.size());
-        Assertions.assertTrue( cost < 1000, "Search large references too slowly: "+cost);
+        Assertions.assertTrue(cost < 1000, "Search large references too slowly: " + cost);
     }
 
     private long testInitReferences(int start, int end, ApplicationConfig applicationConfig, MetadataReportConfig metadataReportConfig, ConfigCenterConfig configCenterConfig) {
@@ -298,8 +641,8 @@ public class ReferenceConfigTest {
 
 
     @Reference(methods = {@Method(name = "sayHello", timeout = 1300, retries = 4, loadbalance = "random", async = true,
-            actives = 3, executes = 5, deprecated = true, sticky = true, oninvoke = "instance.i", onthrow = "instance.t", onreturn = "instance.r", cache = "c", validation = "v",
-            arguments = {@Argument(index = 24, callback = true, type = "sss")})})
+        actives = 3, executes = 5, deprecated = true, sticky = true, oninvoke = "instance.i", onthrow = "instance.t", onreturn = "instance.r", cache = "c", validation = "v",
+        arguments = {@Argument(index = 24, callback = true, type = "sss")})})
     private InnerTest innerTest;
 
     private class InnerTest {
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
index 7a5c68a..484c315 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
@@ -20,11 +20,11 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.constants.CommonConstants;
 import org.apache.dubbo.common.url.component.ServiceConfigURL;
 import org.apache.dubbo.common.utils.ConfigUtils;
-import org.apache.dubbo.config.AbstractInterfaceConfigTest;
 import org.apache.dubbo.config.ApplicationConfig;
 import org.apache.dubbo.config.MonitorConfig;
 import org.apache.dubbo.config.ServiceConfig;
 import org.apache.dubbo.config.SysProps;
+import org.apache.dubbo.config.AbstractInterfaceConfig;
 import org.apache.dubbo.config.api.DemoService;
 import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
 import org.apache.dubbo.config.utils.ConfigValidationUtils;
@@ -200,8 +200,8 @@ public class DubboBootstrapTest {
         Assertions.assertEquals("value1", url.getParameter("param1"));
     }
 
-    private AbstractInterfaceConfigTest.InterfaceConfig getTestInterfaceConfig(MonitorConfig monitorConfig) {
-        AbstractInterfaceConfigTest.InterfaceConfig interfaceConfig = new AbstractInterfaceConfigTest.InterfaceConfig();
+    private InterfaceConfig getTestInterfaceConfig(MonitorConfig monitorConfig) {
+        InterfaceConfig interfaceConfig = new InterfaceConfig();
         interfaceConfig.setApplication(new ApplicationConfig("testLoadMonitor"));
         if(monitorConfig!=null) {
             interfaceConfig.setMonitor(monitorConfig);
@@ -228,4 +228,9 @@ public class DubboBootstrapTest {
         }
     }
 
+
+    public static class InterfaceConfig extends AbstractInterfaceConfig {
+
+    }
+
 }
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/UrlTestBase.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/UrlTestBase.java
index 1a313bb..3d7e320 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/UrlTestBase.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/UrlTestBase.java
@@ -60,55 +60,55 @@ public class UrlTestBase {
     protected MethodConfig methodConfForService;
     protected ServiceConfig<DemoService> servConf;
     protected Object servConfTable[][] = {
-            {"proxy", "proxy", "string", "javassist", "jdk", "javassist", "", "", "", ""},
-            {"actives", "actives", "int", 0, 90, "", "", "", "", ""},
-            {"executes", "executes", "int", 0, 90, "", "", "", "", ""},
-            {"deprecated", "deprecated", "boolean", false, true, "", "", "", "", ""},
-            {"dynamic", "dynamic", "boolean", true, false, "", "", "", "", ""},
-            {"accesslog", "accesslog", "string", "", "haominTest", "", "", "", "", ""},
-            {"document", "document", "string", "", "http://dubbo.apache.org/zh-cn/docs/user/quick-start.html?testquery=你好你好", "", "", "", "", ""},
-            {"weight", "weight", "int", 0, 90, "", "", "", "", ""},
-
-            //{"filter", "service.filter", "string", "", "", "", "", "", "", ""},
-            //{"listener", "listener", "string", "", "", "", "", "", "", ""},
+        {"proxy", "proxy", "string", "javassist", "jdk", "javassist", "", "", "", ""},
+        {"actives", "actives", "int", 0, 90, "", "", "", "", ""},
+        {"executes", "executes", "int", 0, 90, "", "", "", "", ""},
+        {"deprecated", "deprecated", "boolean", false, true, "", "", "", "", ""},
+        {"dynamic", "dynamic", "boolean", true, false, "", "", "", "", ""},
+        {"accesslog", "accesslog", "string", "", "haominTest", "", "", "", "", ""},
+        {"document", "document", "string", "", "http://dubbo.apache.org/zh-cn/docs/user/quick-start.html?testquery=你好你好", "", "", "", "", ""},
+        {"weight", "weight", "int", 0, 90, "", "", "", "", ""},
+
+        //{"filter", "service.filter", "string", "", "", "", "", "", "", ""},
+        //{"listener", "listener", "string", "", "", "", "", "", "", ""},
 
     };
     protected Object regConfForServiceTable[][] = {
-            //            {"timeout", "registry.timeout", "int", 5000, 9000, "", "", "", "", ""},
-            //            {"file", "registry.file", "string", "", "regConfForServiceTable.log", "", "", "", "", ""},
-            //            {"wait", "registry.wait", "int", 0, 9000, "", "", "", "", ""},
-            //            {"transport", "registry.transporter", "string", "netty", "mina", "", "", "", "", ""},
-            //            {"subscribe", "subscribe", "boolean", true, false, "", "", "", "", ""},
-            {"dynamic", "dynamic", "boolean", true, false, "", "", "", "", ""},
+        //            {"timeout", "registry.timeout", "int", 5000, 9000, "", "", "", "", ""},
+        //            {"file", "registry.file", "string", "", "regConfForServiceTable.log", "", "", "", "", ""},
+        //            {"wait", "registry.wait", "int", 0, 9000, "", "", "", "", ""},
+        //            {"transport", "registry.transporter", "string", "netty", "mina", "", "", "", "", ""},
+        //            {"subscribe", "subscribe", "boolean", true, false, "", "", "", "", ""},
+        {"dynamic", "dynamic", "boolean", true, false, "", "", "", "", ""},
     };
     protected Object provConfTable[][] = {{"cluster", "cluster", "string", "string", "failover", "failfast", "failsafe", "", "", ""}, {"async", "async", "boolean", false, true, "", "", "", "", ""}, {"loadbalance", "loadbalance", "string", "random", "leastactive", "", "", "", "", ""}, {"connections", "connections", "int", 0, 60, "", "", "", "", ""}, {"retries", "retries", "int", 2, 60, "", "", "", "", ""}, {"timeout", "timeout", "int", 5000, 60, "", "", "", "", ""},
-            //change by fengting listener 没有缺省值
-            //{"listener", "exporter.listener", "string", "", "", "", "", "", "", ""},
-            //{"filter", "service.filter", "string", "", "", "", "", "", "", ""},
+        //change by fengting listener 没有缺省值
+        //{"listener", "exporter.listener", "string", "", "", "", "", "", "", ""},
+        //{"filter", "service.filter", "string", "", "", "", "", "", "", ""},
 
     };
     protected Object methodConfForServiceTable[][] = {
-            {"actives", "sayName.actives", "int", 0, 90, "", "", "", "", ""},
-            {"executes", "sayName.executes", "int", 0, 90, "", "", "", "", ""},
-            {"deprecated", "sayName.deprecated", "boolean", false, true, "", "", "", "", ""},
-            {"async", "sayName.async", "boolean", false, true, "", "", "", "", ""},
-            {"timeout", "sayName.timeout", "int", 0, 90, "", "", "", "", ""},
+        {"actives", "sayName.actives", "int", 0, 90, "", "", "", "", ""},
+        {"executes", "sayName.executes", "int", 0, 90, "", "", "", "", ""},
+        {"deprecated", "sayName.deprecated", "boolean", false, true, "", "", "", "", ""},
+        {"async", "sayName.async", "boolean", false, true, "", "", "", "", ""},
+        {"timeout", "sayName.timeout", "int", 0, 90, "", "", "", "", ""},
     };
     protected DemoService demoService = new DemoServiceImpl();
     private Object appConfForProviderTable[][] = {
-            {"", "", "", "", "", "", "", "", "", ""},
+        {"", "", "", "", "", "", "", "", "", ""},
     };
     private Object appConfForServiceTable[][] = {
-            {"", "", "", "", "", "", "", "", "", ""},
+        {"", "", "", "", "", "", "", "", "", ""},
     };
     private Object regConfForProviderTable[][] = {
-            {"", "", "", "", "", "", "", "", "", ""},
+        {"", "", "", "", "", "", "", "", "", ""},
     };
     private Object protoConfForProviderTable[][] = {
-            {"", "", "", "", "", "", "", "", "", ""},
+        {"", "", "", "", "", "", "", "", "", ""},
     };
     private Object protoConfForServiceTable[][] = {
-            {"", "", "", "", "", "", "", "", "", ""},
+        {"", "", "", "", "", "", "", "", "", ""},
     };
 
     // ======================================================
@@ -144,6 +144,7 @@ public class UrlTestBase {
         servConf = new ServiceConfig<DemoService>();
 
 //        provConf.setApplication(appConfForProvider);
+        application.setMetadataServicePort(20881);
         servConf.setApplication(application);
 
         provConf.setRegistry(regConfForProvider);
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/ConfigValidationUtilsTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/ConfigValidationUtilsTest.java
new file mode 100644
index 0000000..8d98088
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/ConfigValidationUtilsTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.config.utils;
+
+import org.apache.dubbo.config.AbstractInterfaceConfig;
+import org.apache.dubbo.config.api.Greeting;
+
+import org.apache.dubbo.config.mock.GreetingMock1;
+import org.apache.dubbo.config.mock.GreetingMock2;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+
+public class ConfigValidationUtilsTest {
+
+
+    @Test
+    public void checkMock1() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.setMock("return {a, b}");
+            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
+
+        });
+    }
+
+    @Test
+    public void checkMock2() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.setMock(GreetingMock1.class.getName());
+            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
+        });
+    }
+
+    @Test
+    public void checkMock3() {
+        Assertions.assertThrows(IllegalStateException.class, () -> {
+            InterfaceConfig interfaceConfig = new InterfaceConfig();
+            interfaceConfig.setMock(GreetingMock2.class.getName());
+            ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
+        });
+    }
+
+    public static class InterfaceConfig extends AbstractInterfaceConfig {
+
+    }
+
+}