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 efc73a2  Improve config overrides of method and argument (#8054)
efc73a2 is described below

commit efc73a2e246d9977c83b318258447a0ebadffdf7
Author: Gong Dewei <[email protected]>
AuthorDate: Mon Jun 21 10:30:35 2021 +0800

    Improve config overrides of method and argument (#8054)
---
 .../dubbo/common/config/ConfigurationUtils.java    |  50 +++++--
 .../apache/dubbo/common/config/Environment.java    |  24 ++-
 .../org/apache/dubbo/config/AbstractConfig.java    |  20 ++-
 .../dubbo/config/AbstractInterfaceConfig.java      |  76 +++++++++-
 .../java/org/apache/dubbo/config/MethodConfig.java |  54 +++++++
 .../org/apache/dubbo/config/ServiceConfig.java     |   2 +
 .../dubbo/config/bootstrap/DubboBootstrap.java     |   8 +-
 .../apache/dubbo/config/AbstractConfigTest.java    |  26 ++--
 .../org/apache/dubbo/config/MethodConfigTest.java  | 166 +++++++++++++++------
 9 files changed, 339 insertions(+), 87 deletions(-)

diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/common/config/ConfigurationUtils.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/common/config/ConfigurationUtils.java
index ed0918a..b988d26 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/common/config/ConfigurationUtils.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/common/config/ConfigurationUtils.java
@@ -169,17 +169,21 @@ public class ConfigurationUtils {
         if (!prefix.endsWith(".")) {
             prefix += ".";
         }
-        String finalPrefix = prefix;
         Map<String, V> map = new LinkedHashMap<>();
         for (Map<String, V> configMap : configMaps) {
-            configMap.forEach((key, val) -> {
-                if (StringUtils.startsWithIgnoreCase(key, finalPrefix) && 
!ConfigurationUtils.isEmptyValue(val)) {
-                    String k = key.substring(finalPrefix.length());
+            for (Map.Entry<String, V> entry : configMap.entrySet()) {
+                String key = entry.getKey();
+                V val = entry.getValue();
+                if (StringUtils.startsWithIgnoreCase(key, prefix)
+                    && key.length() > prefix.length()
+                    && !ConfigurationUtils.isEmptyValue(val)) {
+
+                    String k = key.substring(prefix.length());
                     // convert camelCase/snake_case to kebab-case
                     k = StringUtils.convertToSplitName(k, "-");
                     map.putIfAbsent(k, val);
                 }
-            });
+            }
         }
         return map;
     }
@@ -189,11 +193,23 @@ public class ConfigurationUtils {
             prefix += ".";
         }
         for (Map<String, V> configMap : configMaps) {
-            for (Map.Entry<String, V> entry : configMap.entrySet()) {
-                String key = entry.getKey();
-                if (StringUtils.startsWithIgnoreCase(key, prefix) && 
!ConfigurationUtils.isEmptyValue(entry.getValue())) {
-                    return true;
-                }
+            if (hasSubProperties(configMap, prefix)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static <V extends Object> boolean hasSubProperties(Map<String, V> 
configMap, String prefix) {
+        if (!prefix.endsWith(".")) {
+            prefix += ".";
+        }
+        for (Map.Entry<String, V> entry : configMap.entrySet()) {
+            String key = entry.getKey();
+            if (StringUtils.startsWithIgnoreCase(key, prefix)
+                && key.length() > prefix.length()
+                && !ConfigurationUtils.isEmptyValue(entry.getValue())) {
+                return true;
             }
         }
         return false;
@@ -218,10 +234,18 @@ public class ConfigurationUtils {
      * @return
      */
     public static <V extends Object> Set<String> 
getSubIds(Collection<Map<String, V>> configMaps, String prefix) {
+        if (!prefix.endsWith(".")) {
+            prefix += ".";
+        }
         Set<String> ids = new LinkedHashSet<>();
         for (Map<String, V> configMap : configMaps) {
-            configMap.forEach((key, val) -> {
-                if (StringUtils.startsWithIgnoreCase(key, prefix) && 
!ConfigurationUtils.isEmptyValue(val)) {
+            for (Map.Entry<String, V> entry : configMap.entrySet()) {
+                String key = entry.getKey();
+                V val = entry.getValue();
+                if (StringUtils.startsWithIgnoreCase(key, prefix)
+                    && key.length() > prefix.length()
+                    && !ConfigurationUtils.isEmptyValue(val)) {
+
                     String k = key.substring(prefix.length());
                     int endIndex = k.indexOf(".");
                     if (endIndex > 0) {
@@ -229,7 +253,7 @@ public class ConfigurationUtils {
                         ids.add(id);
                     }
                 }
-            });
+            }
         }
         return ids;
     }
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java 
b/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java
index 34e5307..4fd5f67 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java
@@ -60,6 +60,9 @@ public class Environment extends LifecycleAdapter implements 
FrameworkExt {
     private CompositeConfiguration dynamicGlobalConfiguration;
 
     private DynamicConfiguration dynamicConfiguration;
+
+    private List<Map<String, String>> globalConfigurationMaps;
+
     private String localMigrationRule;
 
     private AtomicBoolean initialized = new AtomicBoolean(false);
@@ -181,13 +184,14 @@ public class Environment extends LifecycleAdapter 
implements FrameworkExt {
      */
     public CompositeConfiguration getConfiguration() {
         if (globalConfiguration == null) {
-            globalConfiguration = new CompositeConfiguration();
-            globalConfiguration.addConfiguration(systemConfiguration);
-            globalConfiguration.addConfiguration(environmentConfiguration);
-            globalConfiguration.addConfiguration(appExternalConfiguration);
-            globalConfiguration.addConfiguration(externalConfiguration);
-            globalConfiguration.addConfiguration(appConfiguration);
-            globalConfiguration.addConfiguration(propertiesConfiguration);
+            CompositeConfiguration configuration = new 
CompositeConfiguration();
+            configuration.addConfiguration(systemConfiguration);
+            configuration.addConfiguration(environmentConfiguration);
+            configuration.addConfiguration(appExternalConfiguration);
+            configuration.addConfiguration(externalConfiguration);
+            configuration.addConfiguration(appConfiguration);
+            configuration.addConfiguration(propertiesConfiguration);
+            globalConfiguration = configuration;
         }
         return globalConfiguration;
     }
@@ -220,7 +224,10 @@ public class Environment extends LifecycleAdapter 
implements FrameworkExt {
      * @return
      */
     public List<Map<String, String>> getConfigurationMaps() {
-        return getConfigurationMaps(null, null);
+        if (globalConfigurationMaps == null) {
+            globalConfigurationMaps = getConfigurationMaps(null, null);
+        }
+        return globalConfigurationMaps;
     }
 
     public Configuration getDynamicGlobalConfiguration() {
@@ -257,6 +264,7 @@ public class Environment extends LifecycleAdapter 
implements FrameworkExt {
         appExternalConfiguration = null;
         appConfiguration = null;
         globalConfiguration = null;
+        globalConfigurationMaps = null;
         dynamicConfiguration = null;
         dynamicGlobalConfiguration = null;
     }
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 5130e0e..d59b05b 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
@@ -262,7 +262,7 @@ public abstract class AbstractConfig implements 
Serializable {
         }).collect(Collectors.toSet());
     }
 
-    private static String extractPropertyName(String setter) throws Exception {
+    protected static String extractPropertyName(String setter) {
         String propertyName = setter.substring("set".length());
         propertyName = propertyName.substring(0, 1).toLowerCase() + 
propertyName.substring(1);
         return propertyName;
@@ -451,13 +451,14 @@ public abstract class AbstractConfig implements 
Serializable {
     public List<String> getPrefixes() {
         List<String> prefixes = new ArrayList<>();
         if (StringUtils.hasText(this.getId())) {
-            // dubbo.{tag-name}s.id
+            // dubbo.{tag-name}s.{id}
             prefixes.add(CommonConstants.DUBBO + "." + 
getPluralTagName(this.getClass()) + "." + this.getId());
         }
 
         // check name
         String name = ReflectUtils.getProperty(this, "getName");
         if (StringUtils.hasText(name)) {
+            // dubbo.{tag-name}s.{name}
             String prefix = CommonConstants.DUBBO + "." + 
getPluralTagName(this.getClass()) + "." + name;
             if (!prefixes.contains(prefix)) {
                 prefixes.add(prefix);
@@ -501,6 +502,21 @@ public abstract class AbstractConfig implements 
Serializable {
             Map<String, String> subProperties = 
ConfigurationUtils.getSubProperties(instanceConfigMaps, preferredPrefix);
             InmemoryConfiguration subPropsConfiguration = new 
InmemoryConfiguration(subProperties);
 
+            if (logger.isDebugEnabled()) {
+                String idOrName = "";
+                if (StringUtils.hasText(this.getId())) {
+                    idOrName = "[id=" + this.getId() + "]";
+                } else {
+                    String name = ReflectUtils.getProperty(this, "getName");
+                    if (StringUtils.hasText(name)) {
+                        idOrName = "[name=" + name + "]";
+                    }
+                }
+                logger.debug("Refreshing " + this.getClass().getSimpleName() + 
idOrName +
+                    " with prefix [" + preferredPrefix +
+                    "], extracted props: " + subProperties);
+            }
+
             // loop methods, get override value and set the new value back to 
method
             Method[] methods = getClass().getMethods();
             for (Method method : methods) {
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
index 2686a4e..7f027cc 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
@@ -18,7 +18,9 @@ package org.apache.dubbo.config;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.Version;
+import org.apache.dubbo.common.config.ConfigurationUtils;
 import org.apache.dubbo.common.config.InmemoryConfiguration;
+import org.apache.dubbo.common.utils.ClassUtils;
 import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.common.utils.ConfigUtils;
 import org.apache.dubbo.common.utils.ReflectUtils;
@@ -28,6 +30,7 @@ import org.apache.dubbo.config.support.Parameter;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.ServiceMetadata;
 
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -215,6 +218,44 @@ public abstract class AbstractInterfaceConfig extends 
AbstractMethodConfig {
 
     @Override
     protected void processExtraRefresh(String preferredPrefix, 
InmemoryConfiguration subPropsConfiguration) {
+        if (StringUtils.hasText(interfaceName)) {
+            Class<?> interfaceClass = null;
+            try {
+                interfaceClass = ClassUtils.forName(interfaceName);
+            } catch (ClassNotFoundException e) {
+                throw new IllegalStateException("The interface class is not 
found", e);
+            }
+            if (!interfaceClass.isInterface()) {
+                throw new IllegalStateException(interfaceName+" is not an 
interface");
+            }
+
+            Map<String, String> configProperties = 
subPropsConfiguration.getProperties();
+            Method[] methods = interfaceClass.getMethods();
+            for (Method method : methods) {
+                if (ConfigurationUtils.hasSubProperties(configProperties, 
method.getName())) {
+                    MethodConfig methodConfig = 
getMethodByName(method.getName());
+                    // Add method config if not found
+                    if (methodConfig == null) {
+                        methodConfig = new MethodConfig();
+                        methodConfig.setName(method.getName());
+                        this.addMethod(methodConfig);
+                    }
+                    // Add argument config
+                    // 
dubbo.service.{interfaceName}.{methodName}.{arg-index}.xxx=xxx
+                    java.lang.reflect.Parameter[] arguments = 
method.getParameters();
+                    for (int i = 0; i < arguments.length; i++) {
+                        if (getArgumentByIndex(methodConfig, i) == null &&
+                            hasArgumentConfigProps(configProperties, 
methodConfig.getName(), i)) {
+
+                            ArgumentConfig argumentConfig = new 
ArgumentConfig();
+                            argumentConfig.setIndex(i);
+                            methodConfig.addArgument(argumentConfig);
+                        }
+                    }
+                }
+            }
+        }
+
         List<MethodConfig> methodConfigs = this.getMethods();
         if (methodConfigs != null && methodConfigs.size() > 0) {
             for (MethodConfig methodConfig : methodConfigs) {
@@ -224,6 +265,33 @@ public abstract class AbstractInterfaceConfig extends 
AbstractMethodConfig {
         }
     }
 
+    private ArgumentConfig getArgumentByIndex(MethodConfig methodConfig, int 
argIndex) {
+        if (methodConfig.getArguments() != null && 
methodConfig.getArguments().size() > 0) {
+            for (ArgumentConfig argument : methodConfig.getArguments()) {
+                if (argument.getIndex() != null && argument.getIndex() == 
argIndex) {
+                    return argument;
+                }
+            }
+        }
+        return null;
+    }
+
+    private boolean hasArgumentConfigProps(Map<String, String> 
configProperties, String methodName, int argIndex) {
+        String argPrefix = methodName + "." + argIndex + ".";
+        return ConfigurationUtils.hasSubProperties(configProperties, 
argPrefix);
+    }
+
+    protected MethodConfig getMethodByName(String name) {
+        if (methods != null && methods.size() > 0) {
+            for (MethodConfig methodConfig : methods) {
+                if (StringUtils.isEquals(methodConfig.getName(), name)) {
+                    return methodConfig;
+                }
+            }
+        }
+        return null;
+    }
+
     /**
      * Legitimacy check of stub, note that: the local will deprecated, and 
replace with <code>stub</code>
      *
@@ -494,13 +562,17 @@ public abstract class AbstractInterfaceConfig extends 
AbstractMethodConfig {
         return methods;
     }
 
-    // ======== Deprecated ========
-
     @SuppressWarnings("unchecked")
     public void setMethods(List<? extends MethodConfig> methods) {
         this.methods = (List<MethodConfig>) methods;
     }
 
+    public void addMethod(MethodConfig methodConfig) {
+        if (this.methods == null) {
+            this.methods = new ArrayList<>();
+        }
+        this.methods.add(methodConfig);
+    }
 
     public MonitorConfig getMonitor() {
         if (monitor != null) {
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/MethodConfig.java 
b/dubbo-common/src/main/java/org/apache/dubbo/config/MethodConfig.java
index f93728f..02f933b 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/MethodConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/MethodConfig.java
@@ -16,8 +16,14 @@
  */
 package org.apache.dubbo.config;
 
+import org.apache.dubbo.common.config.Environment;
+import org.apache.dubbo.common.config.InmemoryConfiguration;
+import org.apache.dubbo.common.utils.ClassUtils;
+import org.apache.dubbo.common.utils.MethodUtils;
+import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.config.annotation.Method;
 import org.apache.dubbo.config.support.Parameter;
+import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -209,6 +215,47 @@ public class MethodConfig extends AbstractMethodConfig {
     }
 
     @Override
+    protected void processExtraRefresh(String preferredPrefix, 
InmemoryConfiguration subPropsConfiguration) {
+        if (this.getArguments() != null && this.getArguments().size() > 0) {
+            for (ArgumentConfig argument : this.getArguments()) {
+                refreshArgument(argument, subPropsConfiguration);
+            }
+        }
+    }
+
+    private void refreshArgument(ArgumentConfig argument, 
InmemoryConfiguration subPropsConfiguration) {
+        if (argument.getIndex() != null && argument.getIndex() >= 0) {
+            String prefix = argument.getIndex() + ".";
+            Environment environment = ApplicationModel.getEnvironment();
+            java.lang.reflect.Method[] methods = 
argument.getClass().getMethods();
+            for (java.lang.reflect.Method method : methods) {
+                if (MethodUtils.isSetter(method)) {
+                    String propertyName = 
extractPropertyName(method.getName());
+                    // ignore attributes: 'index' / 'type'
+                    if (StringUtils.isEquals(propertyName, "index") ||
+                        StringUtils.isEquals(propertyName, "type")) {
+                        continue;
+                    }
+                    // convert camelCase/snake_case to kebab-case
+                    String kebabPropertyName = prefix + 
StringUtils.convertToSplitName(propertyName, "-");
+
+                    try {
+                        String value = 
StringUtils.trim(subPropsConfiguration.getString(kebabPropertyName));
+                        if (StringUtils.hasText(value) && 
ClassUtils.isTypeMatch(method.getParameterTypes()[0], value)) {
+                            value = environment.resolvePlaceholders(value);
+                            method.invoke(argument, 
ClassUtils.convertPrimitive(method.getParameterTypes()[0], value));
+                        }
+                    } catch (Exception e) {
+                        logger.info("Failed to override the property " + 
method.getName() + " in " +
+                            this.getClass().getSimpleName() +
+                            ", please make sure every property has 
getter/setter method provided.");
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
     public void addIntoConfigManager() {
         // Don't add MethodConfig to ConfigManager
         // super.addIntoConfigManager();
@@ -377,4 +424,11 @@ public class MethodConfig extends AbstractMethodConfig {
     public String getParentPrefix() {
         return parentPrefix;
     }
+
+    public void addArgument(ArgumentConfig argumentConfig) {
+        if (arguments == null) {
+            arguments = new ArrayList<>();
+        }
+        arguments.add(argumentConfig);
+    }
 }
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 93c273c..e655863 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@ -368,6 +368,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
             map.putIfAbsent(METADATA_KEY, REMOTE_METADATA_STORAGE_TYPE);
         }
         if (CollectionUtils.isNotEmpty(getMethods())) {
+            //TODO Improve method config processing
             for (MethodConfig method : getMethods()) {
                 AbstractConfig.appendParameters(map, method, method.getName());
                 String retryKey = method.getName() + ".retry";
@@ -409,6 +410,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
                                                 }
                                             }
                                         }
+                                        break;
                                     }
                                 }
                             }
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
index b215eb2..394ce6e 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
@@ -792,7 +792,9 @@ public class DubboBootstrap {
                 .map(this::registryAsConfigCenter)
                 .forEach(configManager::addConfigCenter);
 
-            logger.info("use registry as config-center: " + 
configManager.getConfigCenters());
+            if (configManager.getConfigCenters().size() > 0) {
+                logger.info("use registry as config-center: " + 
configManager.getConfigCenters());
+            }
         }
     }
 
@@ -846,7 +848,9 @@ public class DubboBootstrap {
                 .map(this::registryAsMetadataCenter)
                 .forEach(configManager::addMetadataReport);
 
-            logger.info("use registry as metadata-center: " + 
configManager.getMetadataConfigs());
+            if (configManager.getMetadataConfigs().size() > 0) {
+                logger.info("use registry as metadata-center: " + 
configManager.getMetadataConfigs());
+            }
         }
     }
 
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java
index b9bc39e..a2468a6 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java
@@ -449,19 +449,14 @@ public class AbstractConfigTest {
 
             Map<String, String> external = new HashMap<>();
             external.put("dubbo.overrides.override-id.address", 
"external-override-id://127.0.0.1:2181");
-            external.put("dubbo.override.address", 
"external://127.0.0.1:2181");
-            // @Parameter(exclude=true)
-            external.put("dubbo.override.exclude", "external");
-            // @Parameter(key="key1", useKeyAsProperty=false)
             external.put("dubbo.overrides.override-id.key", "external");
-            // @Parameter(key="key2", useKeyAsProperty=true)
             external.put("dubbo.overrides.override-id.key2", "external");
+            external.put("dubbo.override.address", 
"external://127.0.0.1:2181");
+            external.put("dubbo.override.exclude", "external");
             ApplicationModel.getEnvironment().initialize();
             ApplicationModel.getEnvironment().setExternalConfigMap(external);
 
-            ConfigCenterConfig configCenter = new ConfigCenterConfig();
-            overrideConfig.setConfigCenter(configCenter);
-            // Load configuration from  system properties -> 
externalConfiguration -> RegistryConfig -> dubbo.properties
+            // refresh config
             overrideConfig.refresh();
 
             Assertions.assertEquals("external-override-id://127.0.0.1:2181", 
overrideConfig.getAddress());
@@ -489,9 +484,7 @@ public class AbstractConfigTest {
             ApplicationModel.getEnvironment().initialize();
             ApplicationModel.getEnvironment().setExternalConfigMap(external);
 
-            ConfigCenterConfig configCenter = new ConfigCenterConfig();
-            overrideConfig.setConfigCenter(configCenter);
-            // Load configuration from  system properties -> 
externalConfiguration -> RegistryConfig -> dubbo.properties
+            // refresh config
             overrideConfig.refresh();
 
             Assertions.assertEquals("value1", 
overrideConfig.getParameters().get("key1"));
@@ -603,7 +596,7 @@ public class AbstractConfigTest {
         ConfigField configField() default @ConfigField;
     }
 
-    private static class OverrideConfig extends AbstractInterfaceConfig {
+    private static class OverrideConfig extends AbstractConfig {
         public String address;
         public String protocol;
         public String exclude;
@@ -612,6 +605,7 @@ public class AbstractConfigTest {
         public String escape;
         public String notConflictKey;
         public String notConflictKey2;
+        protected Map<String, String> parameters;
 
         public String getAddress() {
             return address;
@@ -680,6 +674,14 @@ public class AbstractConfigTest {
         public void setNotConflictKey2(String notConflictKey2) {
             this.notConflictKey2 = notConflictKey2;
         }
+
+        public Map<String, String> getParameters() {
+            return parameters;
+        }
+
+        public void setParameters(Map<String, String> parameters) {
+            this.parameters = parameters;
+        }
     }
 
     private static class PropertiesConfig extends AbstractConfig {
diff --git 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/MethodConfigTest.java
 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/MethodConfigTest.java
index 9ea0f7a..6c1d032 100644
--- 
a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/MethodConfigTest.java
+++ 
b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/MethodConfigTest.java
@@ -265,7 +265,7 @@ public class MethodConfigTest {
     }
 
     @Test
-    public void testOverrideMethodConfig() {
+    public void testOverrideMethodConfigOfReference() {
 
         String interfaceName = DemoService.class.getName();
         SysProps.setProperty("dubbo.reference."+ interfaceName 
+".sayName.timeout", "1234");
@@ -273,29 +273,58 @@ public class MethodConfigTest {
         SysProps.setProperty("dubbo.reference."+ interfaceName 
+".sayName.parameters", "[{a:1},{b:2}]");
         SysProps.setProperty("dubbo.reference."+ interfaceName +".init", 
"false");
 
-        try {
-            ReferenceConfig referenceConfig = new ReferenceConfig();
-            referenceConfig.setInterface(interfaceName);
-            MethodConfig methodConfig = new MethodConfig();
-            methodConfig.setName("sayName");
-            methodConfig.setTimeout(1000);
-            referenceConfig.setMethods(Arrays.asList(methodConfig));
-
-            DubboBootstrap.getInstance()
-                    .application("demo-app")
-                    .reference(referenceConfig)
-                    .initialize();
-
-            Map<String, String> params = new LinkedHashMap<>();
-            params.put("a", "1");
-            params.put("b", "2");
-
-            Assertions.assertEquals(1234, methodConfig.getTimeout());
-            Assertions.assertEquals(true, methodConfig.getSticky());
-            Assertions.assertEquals(params, methodConfig.getParameters());
-            Assertions.assertEquals(false, referenceConfig.isInit());
-        } finally {
-        }
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setInterface(interfaceName);
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setName("sayName");
+        methodConfig.setTimeout(1000);
+        referenceConfig.setMethods(Arrays.asList(methodConfig));
+
+        DubboBootstrap.getInstance()
+            .application("demo-app")
+            .reference(referenceConfig)
+            .initialize();
+
+        Map<String, String> params = new LinkedHashMap<>();
+        params.put("a", "1");
+        params.put("b", "2");
+
+        Assertions.assertEquals(1234, methodConfig.getTimeout());
+        Assertions.assertEquals(true, methodConfig.getSticky());
+        Assertions.assertEquals(params, methodConfig.getParameters());
+        Assertions.assertEquals(false, referenceConfig.isInit());
+
+    }
+
+    @Test
+    public void testAddMethodConfigOfReference() {
+
+        String interfaceName = DemoService.class.getName();
+        SysProps.setProperty("dubbo.reference."+ interfaceName 
+".sayName.timeout", "1234");
+        SysProps.setProperty("dubbo.reference."+ interfaceName 
+".sayName.sticky", "true");
+        SysProps.setProperty("dubbo.reference."+ interfaceName 
+".sayName.parameters", "[{a:1},{b:2}]");
+        SysProps.setProperty("dubbo.reference."+ interfaceName +".init", 
"false");
+
+        ReferenceConfig referenceConfig = new ReferenceConfig();
+        referenceConfig.setInterface(interfaceName);
+
+        DubboBootstrap.getInstance()
+            .application("demo-app")
+            .reference(referenceConfig)
+            .initialize();
+
+        List<MethodConfig> methodConfigs = referenceConfig.getMethods();
+        Assertions.assertEquals(1, methodConfigs.size());
+        MethodConfig methodConfig = methodConfigs.get(0);
+
+        Map<String, String> params = new LinkedHashMap<>();
+        params.put("a", "1");
+        params.put("b", "2");
+
+        Assertions.assertEquals(1234, methodConfig.getTimeout());
+        Assertions.assertEquals(true, methodConfig.getSticky());
+        Assertions.assertEquals(params, methodConfig.getParameters());
+        Assertions.assertEquals(false, referenceConfig.isInit());
 
     }
 
@@ -309,30 +338,71 @@ public class MethodConfigTest {
         SysProps.setProperty("dubbo.service."+ interfaceName +".group", 
"demo");
         SysProps.setProperty("dubbo.registry.address", "N/A");
 
-        try {
-            ServiceConfig serviceConfig = new ServiceConfig();
-            serviceConfig.setInterface(interfaceName);
-            serviceConfig.setRef(new DemoServiceImpl());
-            MethodConfig methodConfig = new MethodConfig();
-            methodConfig.setName("sayName");
-            methodConfig.setTimeout(1000);
-            serviceConfig.setMethods(Arrays.asList(methodConfig));
-
-            DubboBootstrap.getInstance()
-                    .application("demo-app")
-                    .service(serviceConfig)
-                    .initialize();
-
-            Map<String, String> params = new LinkedHashMap<>();
-            params.put("a", "1");
-            params.put("b", "2");
-
-            Assertions.assertEquals(1234, methodConfig.getTimeout());
-            Assertions.assertEquals(true, methodConfig.getSticky());
-            Assertions.assertEquals(params, methodConfig.getParameters());
-            Assertions.assertEquals("demo", serviceConfig.getGroup());
-        } finally {
-        }
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setInterface(interfaceName);
+        serviceConfig.setRef(new DemoServiceImpl());
+        MethodConfig methodConfig = new MethodConfig();
+        methodConfig.setName("sayName");
+        methodConfig.setTimeout(1000);
+        serviceConfig.setMethods(Arrays.asList(methodConfig));
+
+        DubboBootstrap.getInstance()
+            .application("demo-app")
+            .service(serviceConfig)
+            .initialize();
+
+        Map<String, String> params = new LinkedHashMap<>();
+        params.put("a", "1");
+        params.put("b", "2");
+
+        Assertions.assertEquals(1234, methodConfig.getTimeout());
+        Assertions.assertEquals(true, methodConfig.getSticky());
+        Assertions.assertEquals(params, methodConfig.getParameters());
+        Assertions.assertEquals("demo", serviceConfig.getGroup());
+
+    }
+
+    @Test
+    public void testAddMethodConfigOfService() {
+
+        String interfaceName = DemoService.class.getName();
+        SysProps.setProperty("dubbo.service."+ interfaceName 
+".sayName.timeout", "1234");
+        SysProps.setProperty("dubbo.service."+ interfaceName 
+".sayName.sticky", "true");
+        SysProps.setProperty("dubbo.service."+ interfaceName 
+".sayName.parameters", "[{a:1},{b:2}]");
+        SysProps.setProperty("dubbo.service."+ interfaceName 
+".sayName.0.callback", "true");
+        SysProps.setProperty("dubbo.service."+ interfaceName +".group", 
"demo");
+        SysProps.setProperty("dubbo.service."+ interfaceName +".echo", 
"non-method-config");
+        SysProps.setProperty("dubbo.registry.address", "N/A");
+
+        ServiceConfig serviceConfig = new ServiceConfig();
+        serviceConfig.setInterface(interfaceName);
+        serviceConfig.setRef(new DemoServiceImpl());
+
+        Assertions.assertEquals(null, serviceConfig.getMethods());
+
+        DubboBootstrap.getInstance()
+            .application("demo-app")
+            .service(serviceConfig)
+            .initialize();
+
+        List<MethodConfig> methodConfigs = serviceConfig.getMethods();
+        Assertions.assertEquals(1, methodConfigs.size());
+        MethodConfig methodConfig = methodConfigs.get(0);
+
+        List<ArgumentConfig> arguments = methodConfig.getArguments();
+        Assertions.assertEquals(1, arguments.size());
+        ArgumentConfig argumentConfig = arguments.get(0);
+
+        Map<String, String> params = new LinkedHashMap<>();
+        params.put("a", "1");
+        params.put("b", "2");
+
+        Assertions.assertEquals("demo", serviceConfig.getGroup());
+        Assertions.assertEquals(params, methodConfig.getParameters());
+        Assertions.assertEquals(1234, methodConfig.getTimeout());
+        Assertions.assertEquals(true, methodConfig.getSticky());
+        Assertions.assertEquals(0, argumentConfig.getIndex());
+        Assertions.assertEquals(true, argumentConfig.isCallback());
 
     }
 

Reply via email to