Skip to content

Commit e490ede

Browse files
chickenljseedeed
authored andcommitted
Refactor, configuration override does not work properly. (apache#5709)
1 parent 084fa12 commit e490ede

File tree

11 files changed

+134
-173
lines changed

11 files changed

+134
-173
lines changed

dubbo-common/src/main/java/org/apache/dubbo/common/config/AbstractPrefixConfiguration.java

Lines changed: 0 additions & 52 deletions
This file was deleted.

dubbo-common/src/main/java/org/apache/dubbo/common/config/CompositeConfiguration.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,41 @@
1818

1919
import org.apache.dubbo.common.logger.Logger;
2020
import org.apache.dubbo.common.logger.LoggerFactory;
21+
import org.apache.dubbo.common.utils.StringUtils;
2122

2223
import java.util.Arrays;
2324
import java.util.LinkedList;
2425
import java.util.List;
2526

2627
/**
27-
*
28+
* This is an abstraction specially customized for the sequence Dubbo retrieves properties.
2829
*/
2930
public class CompositeConfiguration implements Configuration {
3031
private Logger logger = LoggerFactory.getLogger(CompositeConfiguration.class);
3132

33+
private String id;
34+
private String prefix;
35+
3236
/**
3337
* List holding all the configuration
3438
*/
3539
private List<Configuration> configList = new LinkedList<Configuration>();
3640

3741
public CompositeConfiguration() {
42+
this(null, null);
43+
}
3844

45+
public CompositeConfiguration(String prefix, String id) {
46+
if (StringUtils.isNotEmpty(prefix) && !prefix.endsWith(".")) {
47+
this.prefix = prefix + ".";
48+
} else {
49+
this.prefix = prefix;
50+
}
51+
this.id = id;
3952
}
4053

4154
public CompositeConfiguration(Configuration... configurations) {
55+
this();
4256
if (configurations != null && configurations.length > 0) {
4357
Arrays.stream(configurations).filter(config -> !configList.contains(config)).forEach(configList::add);
4458
}
@@ -83,4 +97,20 @@ public Object getInternalProperty(String key) {
8397
public boolean containsKey(String key) {
8498
return configList.stream().anyMatch(c -> c.containsKey(key));
8599
}
100+
101+
@Override
102+
public Object getProperty(String key, Object defaultValue) {
103+
Object value = null;
104+
if (StringUtils.isNotEmpty(prefix)) {
105+
if (StringUtils.isNotEmpty(id)) {
106+
value = getInternalProperty(prefix + id + "." + key);
107+
}
108+
if (value == null) {
109+
value = getInternalProperty(prefix + key);
110+
}
111+
} else {
112+
value = getInternalProperty(key);
113+
}
114+
return value != null ? value : defaultValue;
115+
}
86116
}

dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java

Lines changed: 75 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
package org.apache.dubbo.common.config;
1818

1919
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
20-
import org.apache.dubbo.common.constants.CommonConstants;
2120
import org.apache.dubbo.common.context.FrameworkExt;
2221
import org.apache.dubbo.common.context.LifecycleAdapter;
2322
import org.apache.dubbo.common.extension.DisableInject;
24-
import org.apache.dubbo.common.utils.StringUtils;
23+
import org.apache.dubbo.config.AbstractConfig;
2524
import org.apache.dubbo.config.ConfigCenterConfig;
25+
import org.apache.dubbo.config.context.ConfigConfigurationAdapter;
2626
import org.apache.dubbo.config.context.ConfigManager;
2727
import org.apache.dubbo.rpc.model.ApplicationModel;
2828

@@ -31,15 +31,19 @@
3131
import java.util.Map;
3232
import java.util.Optional;
3333
import java.util.concurrent.ConcurrentHashMap;
34+
import java.util.concurrent.ConcurrentMap;
3435

3536
public class Environment extends LifecycleAdapter implements FrameworkExt {
3637
public static final String NAME = "environment";
3738

38-
private Map<String, PropertiesConfiguration> propertiesConfigs = new ConcurrentHashMap<>();
39-
private Map<String, SystemConfiguration> systemConfigs = new ConcurrentHashMap<>();
40-
private Map<String, EnvironmentConfiguration> environmentConfigs = new ConcurrentHashMap<>();
41-
private Map<String, InmemoryConfiguration> externalConfigs = new ConcurrentHashMap<>();
42-
private Map<String, InmemoryConfiguration> appExternalConfigs = new ConcurrentHashMap<>();
39+
private final PropertiesConfiguration propertiesConfiguration;
40+
private final SystemConfiguration systemConfiguration;
41+
private final EnvironmentConfiguration environmentConfiguration;
42+
private final InmemoryConfiguration externalConfiguration;
43+
private final InmemoryConfiguration appExternalConfiguration;
44+
45+
private final ConcurrentMap<AbstractConfig, CompositeConfiguration> prefixedConfigurations = new ConcurrentHashMap<>();
46+
private CompositeConfiguration globalConfiguration;
4347

4448
private Map<String, String> externalConfigurationMap = new HashMap<>();
4549
private Map<String, String> appExternalConfigurationMap = new HashMap<>();
@@ -48,6 +52,14 @@ public class Environment extends LifecycleAdapter implements FrameworkExt {
4852

4953
private DynamicConfiguration dynamicConfiguration;
5054

55+
public Environment() {
56+
this.propertiesConfiguration = new PropertiesConfiguration();
57+
this.systemConfiguration = new SystemConfiguration();
58+
this.environmentConfiguration = new EnvironmentConfiguration();
59+
this.externalConfiguration = new InmemoryConfiguration();
60+
this.appExternalConfiguration = new InmemoryConfiguration();
61+
}
62+
5163
@Override
5264
public void initialize() throws IllegalStateException {
5365
ConfigManager configManager = ApplicationModel.getConfigManager();
@@ -58,34 +70,9 @@ public void initialize() throws IllegalStateException {
5870
this.setAppExternalConfigMap(config.getAppExternalConfiguration());
5971
}
6072
});
61-
}
6273

63-
public PropertiesConfiguration getPropertiesConfig(String prefix, String id) {
64-
return propertiesConfigs.computeIfAbsent(toKey(prefix, id), k -> new PropertiesConfiguration(prefix, id));
65-
}
66-
67-
public SystemConfiguration getSystemConfig(String prefix, String id) {
68-
return systemConfigs.computeIfAbsent(toKey(prefix, id), k -> new SystemConfiguration(prefix, id));
69-
}
70-
71-
public InmemoryConfiguration getExternalConfig(String prefix, String id) {
72-
return externalConfigs.computeIfAbsent(toKey(prefix, id), k -> {
73-
InmemoryConfiguration configuration = new InmemoryConfiguration(prefix, id);
74-
configuration.setProperties(externalConfigurationMap);
75-
return configuration;
76-
});
77-
}
78-
79-
public InmemoryConfiguration getAppExternalConfig(String prefix, String id) {
80-
return appExternalConfigs.computeIfAbsent(toKey(prefix, id), k -> {
81-
InmemoryConfiguration configuration = new InmemoryConfiguration(prefix, id);
82-
configuration.setProperties(appExternalConfigurationMap);
83-
return configuration;
84-
});
85-
}
86-
87-
public EnvironmentConfiguration getEnvironmentConfig(String prefix, String id) {
88-
return environmentConfigs.computeIfAbsent(toKey(prefix, id), k -> new EnvironmentConfiguration(prefix, id));
74+
this.externalConfiguration.setProperties(externalConfigurationMap);
75+
this.appExternalConfiguration.setProperties(appExternalConfigurationMap);
8976
}
9077

9178
@DisableInject
@@ -119,46 +106,65 @@ public void updateAppExternalConfigurationMap(Map<String, String> externalMap) {
119106
}
120107

121108
/**
122-
* Create new instance for each call, since it will be called only at startup, I think there's no big deal of the potential cost.
123-
* Otherwise, if use cache, we should make sure each Config has a unique id which is difficult to guarantee because is on the user's side,
124-
* especially when it comes to ServiceConfig and ReferenceConfig.
109+
* At start-up, Dubbo is driven by various configuration, such as Application, Registry, Protocol, etc.
110+
* All configurations will be converged into a data bus - URL, and then drive the subsequent process.
111+
* <p>
112+
* At present, there are many configuration sources, including AbstractConfig (API, XML, annotation), - D, config center, etc.
113+
* This method helps us to filter out the most priority values from various configuration sources.
125114
*
126-
* @param prefix
127-
* @param id
115+
* @param config
128116
* @return
129117
*/
130-
public CompositeConfiguration getConfiguration(String prefix, String id) {
131-
CompositeConfiguration compositeConfiguration = new CompositeConfiguration();
132-
// Config center has the highest priority
133-
compositeConfiguration.addConfiguration(this.getSystemConfig(prefix, id));
134-
compositeConfiguration.addConfiguration(this.getEnvironmentConfig(prefix, id));
135-
compositeConfiguration.addConfiguration(this.getAppExternalConfig(prefix, id));
136-
compositeConfiguration.addConfiguration(this.getExternalConfig(prefix, id));
137-
compositeConfiguration.addConfiguration(this.getPropertiesConfig(prefix, id));
138-
return compositeConfiguration;
118+
public synchronized CompositeConfiguration getPrefixedConfiguration(AbstractConfig config) {
119+
// CompositeConfiguration prefixedConfiguration =
120+
// prefixedConfigurations.putIfAbsent(config, new CompositeConfiguration(config.getPrefix(), config.getId()));
121+
// if (prefixedConfiguration != null) {
122+
// return prefixedConfiguration;
123+
// }
124+
// prefixedConfiguration = prefixedConfigurations.get(config);
125+
CompositeConfiguration prefixedConfiguration = new CompositeConfiguration(config.getPrefix(), config.getId());
126+
Configuration configuration = new ConfigConfigurationAdapter(config);
127+
if (this.isConfigCenterFirst()) {
128+
// The sequence would be: SystemConfiguration -> AppExternalConfiguration -> ExternalConfiguration -> AbstractConfig -> PropertiesConfiguration
129+
// Config center has the highest priority
130+
prefixedConfiguration.addConfiguration(systemConfiguration);
131+
prefixedConfiguration.addConfiguration(environmentConfiguration);
132+
prefixedConfiguration.addConfiguration(appExternalConfiguration);
133+
prefixedConfiguration.addConfiguration(externalConfiguration);
134+
prefixedConfiguration.addConfiguration(configuration);
135+
prefixedConfiguration.addConfiguration(propertiesConfiguration);
136+
} else {
137+
// The sequence would be: SystemConfiguration -> AbstractConfig -> AppExternalConfiguration -> ExternalConfiguration -> PropertiesConfiguration
138+
// Config center has the highest priority
139+
prefixedConfiguration.addConfiguration(systemConfiguration);
140+
prefixedConfiguration.addConfiguration(environmentConfiguration);
141+
prefixedConfiguration.addConfiguration(configuration);
142+
prefixedConfiguration.addConfiguration(appExternalConfiguration);
143+
prefixedConfiguration.addConfiguration(externalConfiguration);
144+
prefixedConfiguration.addConfiguration(propertiesConfiguration);
145+
}
146+
return prefixedConfiguration;
139147
}
140148

149+
/**
150+
* There are two ways to get configuration during exposure / reference or at runtime:
151+
* 1. URL, The value in the URL is relatively fixed. we can get value directly.
152+
* 2. The configuration exposed in this method is convenient for us to query the latest values from multiple
153+
* prioritized sources, it also guarantees that configs changed dynamically can take effect on the fly.
154+
*/
141155
public Configuration getConfiguration() {
142-
return getConfiguration(null, null);
143-
}
144-
145-
private static String toKey(String prefix, String id) {
146-
StringBuilder sb = new StringBuilder();
147-
if (StringUtils.isNotEmpty(prefix)) {
148-
sb.append(prefix);
149-
}
150-
if (StringUtils.isNotEmpty(id)) {
151-
sb.append(id);
152-
}
153-
154-
if (sb.length() > 0 && sb.charAt(sb.length() - 1) != '.') {
155-
sb.append(".");
156-
}
157-
158-
if (sb.length() > 0) {
159-
return sb.toString();
156+
if (globalConfiguration == null) {
157+
globalConfiguration = new CompositeConfiguration();
158+
if (dynamicConfiguration != null) {
159+
globalConfiguration.addConfiguration(dynamicConfiguration);
160+
}
161+
globalConfiguration.addConfiguration(systemConfiguration);
162+
globalConfiguration.addConfiguration(environmentConfiguration);
163+
globalConfiguration.addConfiguration(appExternalConfiguration);
164+
globalConfiguration.addConfiguration(externalConfiguration);
165+
globalConfiguration.addConfiguration(propertiesConfiguration);
160166
}
161-
return CommonConstants.DUBBO;
167+
return globalConfiguration;
162168
}
163169

164170
public boolean isConfigCenterFirst() {
@@ -187,13 +193,13 @@ public void destroy() throws IllegalStateException {
187193

188194
// For test
189195
public void clearExternalConfigs() {
190-
this.externalConfigs.clear();
196+
this.externalConfiguration.clear();
191197
this.externalConfigurationMap.clear();
192198
}
193199

194200
// For test
195201
public void clearAppExternalConfigs() {
196-
this.appExternalConfigs.clear();
202+
this.appExternalConfiguration.clear();
197203
this.appExternalConfigurationMap.clear();
198204
}
199205
}

dubbo-common/src/main/java/org/apache/dubbo/common/config/EnvironmentConfiguration.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,7 @@
2121
/**
2222
* Configuration from system environment
2323
*/
24-
public class EnvironmentConfiguration extends AbstractPrefixConfiguration {
25-
26-
public EnvironmentConfiguration(String prefix, String id) {
27-
super(prefix, id);
28-
}
29-
30-
public EnvironmentConfiguration() {
31-
this(null, null);
32-
}
24+
public class EnvironmentConfiguration implements Configuration {
3325

3426
@Override
3527
public Object getInternalProperty(String key) {

dubbo-common/src/main/java/org/apache/dubbo/common/config/InmemoryConfiguration.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,11 @@
2222
/**
2323
* In-memory configuration
2424
*/
25-
public class InmemoryConfiguration extends AbstractPrefixConfiguration {
25+
public class InmemoryConfiguration implements Configuration {
2626

2727
// stores the configuration key-value pairs
2828
private Map<String, String> store = new LinkedHashMap<>();
2929

30-
public InmemoryConfiguration(String prefix, String id) {
31-
super(prefix, id);
32-
}
33-
34-
public InmemoryConfiguration() {
35-
this(null, null);
36-
}
37-
3830
@Override
3931
public Object getInternalProperty(String key) {
4032
return store.get(key);
@@ -64,4 +56,9 @@ public void setProperties(Map<String, String> properties) {
6456
this.store = properties;
6557
}
6658
}
59+
60+
// for unit test
61+
public void clear() {
62+
this.store.clear();
63+
}
6764
}

dubbo-common/src/main/java/org/apache/dubbo/common/config/PropertiesConfiguration.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,9 @@
2727
/**
2828
* Configuration from system properties and dubbo.properties
2929
*/
30-
public class PropertiesConfiguration extends AbstractPrefixConfiguration {
31-
32-
public PropertiesConfiguration(String prefix, String id) {
33-
super(prefix, id);
30+
public class PropertiesConfiguration implements Configuration {
3431

32+
public PropertiesConfiguration() {
3533
ExtensionLoader<OrderedPropertiesProvider> propertiesProviderExtensionLoader = ExtensionLoader.getExtensionLoader(OrderedPropertiesProvider.class);
3634
Set<String> propertiesProviderNames = propertiesProviderExtensionLoader.getSupportedExtensions();
3735
if (propertiesProviderNames == null || propertiesProviderNames.isEmpty()) {
@@ -59,10 +57,6 @@ public PropertiesConfiguration(String prefix, String id) {
5957
ConfigUtils.setProperties(properties);
6058
}
6159

62-
public PropertiesConfiguration() {
63-
this(null, null);
64-
}
65-
6660
@Override
6761
public Object getInternalProperty(String key) {
6862
return ConfigUtils.getProperty(key);

0 commit comments

Comments
 (0)