Use special Configuration for Configs (#4522)

This commit is contained in:
ken.lj 2019-07-11 14:18:31 +08:00 committed by cvictory
parent 5bbc1df8d3
commit 5d82371e8a
4 changed files with 128 additions and 11 deletions

View File

@ -37,14 +37,14 @@ public abstract class AbstractPrefixConfiguration implements Configuration {
@Override
public Object getProperty(String key, Object defaultValue) {
Object value = null;
if (StringUtils.isNotEmpty(prefix) && StringUtils.isNotEmpty(id)) {
value = getInternalProperty(prefix + id + "." + key);
}
if (value == null && StringUtils.isNotEmpty(prefix)) {
value = getInternalProperty(prefix + key);
}
if (value == null) {
if (StringUtils.isNotEmpty(prefix)) {
if (StringUtils.isNotEmpty(id)) {
value = getInternalProperty(prefix + id + "." + key);
}
if (value == null) {
value = getInternalProperty(prefix + key);
}
} else {
value = getInternalProperty(key);
}
return value != null ? value : defaultValue;

View File

@ -18,8 +18,8 @@ package org.apache.dubbo.config;
import org.apache.dubbo.common.URL;
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.config.InmemoryConfiguration;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
@ -29,6 +29,7 @@ import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.MethodUtils;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.context.ConfigConfigurationAdapter;
import org.apache.dubbo.config.support.Parameter;
import org.apache.dubbo.rpc.model.ConsumerMethodModel;
@ -548,8 +549,7 @@ public abstract class AbstractConfig implements Serializable {
public void refresh() {
try {
CompositeConfiguration compositeConfiguration = Environment.getInstance().getConfiguration(getPrefix(), getId());
InmemoryConfiguration config = new InmemoryConfiguration(getPrefix(), getId());
config.addProperties(getMetaData());
Configuration config = new ConfigConfigurationAdapter(this);
if (Environment.getInstance().isConfigCenterFirst()) {
// The sequence would be: SystemConfiguration -> AppExternalConfiguration -> ExternalConfiguration -> AbstractConfig -> PropertiesConfiguration
compositeConfiguration.addConfiguration(4, config);

View File

@ -0,0 +1,40 @@
/*
* 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.context;
import org.apache.dubbo.common.config.Configuration;
import org.apache.dubbo.config.AbstractConfig;
import java.util.Map;
/**
* This class receives an {@link AbstractConfig} and exposes its attributes through {@link Configuration}
*/
public class ConfigConfigurationAdapter implements Configuration {
private Map<String, String> metaData;
public ConfigConfigurationAdapter(AbstractConfig config) {
this.metaData = config.getMetaData();
}
@Override
public Object getInternalProperty(String key) {
return metaData.get(key);
}
}

View File

@ -29,6 +29,7 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@ -449,6 +450,37 @@ public class AbstractConfigTest {
}
}
@Test
public void testOnlyPrefixedKeyTakeEffect() {
try {
OverrideConfig overrideConfig = new OverrideConfig();
overrideConfig.setNotConflictKey("value-from-config");
Map<String, String> external = new HashMap<>();
external.put("notConflictKey", "value-from-external");
try {
Map<String, String> map = new HashMap<>();
map.put("notConflictKey", "value-from-env");
map.put("dubbo.override.notConflictKey2", "value-from-env");
setOsEnv(map);
} catch (Exception e) {
// ignore
e.printStackTrace();
}
Environment.getInstance().setExternalConfigMap(external);
overrideConfig.refresh();
Assertions.assertEquals("value-from-config", overrideConfig.getNotConflictKey());
Assertions.assertEquals("value-from-env", overrideConfig.getNotConflictKey2());
} finally {
Environment.getInstance().clearExternalConfigs();
}
}
@Test
public void tetMetaData() {
OverrideConfig overrideConfig = new OverrideConfig();
@ -518,6 +550,8 @@ public class AbstractConfigTest {
public String key;
public String useKeyAsProperty;
public String escape;
public String notConflictKey;
public String notConflictKey2;
public String getAddress() {
return address;
@ -570,6 +604,22 @@ public class AbstractConfigTest {
public void setEscape(String escape) {
this.escape = escape;
}
public String getNotConflictKey() {
return notConflictKey;
}
public void setNotConflictKey(String notConflictKey) {
this.notConflictKey = notConflictKey;
}
public String getNotConflictKey2() {
return notConflictKey2;
}
public void setNotConflictKey2(String notConflictKey2) {
this.notConflictKey2 = notConflictKey2;
}
}
private static class PropertiesConfig extends AbstractConfig {
@ -807,4 +857,31 @@ public class AbstractConfigTest {
this.configFields = configFields;
}
}
protected static void setOsEnv(Map<String, String> newenv) throws Exception {
try {
Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
theEnvironmentField.setAccessible(true);
Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);
env.putAll(newenv);
Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
theCaseInsensitiveEnvironmentField.setAccessible(true);
Map<String, String> cienv = (Map<String, String>) theCaseInsensitiveEnvironmentField.get(null);
cienv.putAll(newenv);
} catch (NoSuchFieldException e) {
Class[] classes = Collections.class.getDeclaredClasses();
Map<String, String> env = System.getenv();
for (Class cl : classes) {
if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Object obj = field.get(env);
Map<String, String> map = (Map<String, String>) obj;
map.clear();
map.putAll(newenv);
}
}
}
}
}