parent
3cb9ac6564
commit
d0454fdbef
|
|
@ -13,7 +13,6 @@ env:
|
|||
spring-boot.version:1.5.22.RELEASE;
|
||||
spring-boot.version:2.4.1;
|
||||
'
|
||||
DUBBO_SPRING_BOOT_REF: '3.0.x'
|
||||
|
||||
jobs:
|
||||
build-source:
|
||||
|
|
@ -40,7 +39,7 @@ jobs:
|
|||
- name: "Build Dubbo with Maven"
|
||||
run: |
|
||||
cd ./dubbo
|
||||
./mvnw --batch-mode -U -e --no-transfer-progress clean source:jar install -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true
|
||||
./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress clean source:jar install -Pjacoco,rat,checkstyle -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -Dmaven.test.skip=true -Dmaven.test.skip.exec=true
|
||||
- name: "Calculate Dubbo Version"
|
||||
id: dubbo-version
|
||||
run: |
|
||||
|
|
@ -73,13 +72,13 @@ jobs:
|
|||
- name: "Test with Maven with Integration Tests"
|
||||
timeout-minutes: 40
|
||||
if: ${{ startsWith( matrix.os, 'ubuntu') }}
|
||||
run: ./mvnw --batch-mode -U -e --no-transfer-progress clean test verify -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress clean test verify -Pjacoco -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true
|
||||
- name: "Test with Maven without Integration Tests"
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
timeout-minutes: 50
|
||||
if: ${{ startsWith( matrix.os, 'windows') }}
|
||||
run: ./mvnw --batch-mode -U -e --no-transfer-progress clean test verify -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"rat.skip=false" -D"maven.javadoc.skip=true"
|
||||
run: ./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress clean test verify -Pjacoco -D"http.keepAlive=false" -D"maven.wagon.http.pool=false" -D"maven.wagon.httpconnectionManager.ttlSeconds=120" -D"maven.wagon.http.retryHandler.count=5" -DskipTests=false -DskipIntegrationTests=true -D"checkstyle.skip=false" -D"rat.skip=false" -D"maven.javadoc.skip=true"
|
||||
- name: "Pack rat file if failure"
|
||||
if: failure()
|
||||
run: 7z a ${{ github.workspace }}/rat.zip *rat.txt -r
|
||||
|
|
|
|||
|
|
@ -21,20 +21,21 @@ import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
|
|||
|
||||
public class DefaultGovernanceRuleRepositoryImpl implements GovernanceRuleRepository {
|
||||
|
||||
private DynamicConfiguration dynamicConfiguration = DynamicConfiguration.getDynamicConfiguration();
|
||||
|
||||
@Override
|
||||
public void addListener(String key, String group, ConfigurationListener listener) {
|
||||
DynamicConfiguration dynamicConfiguration = DynamicConfiguration.getDynamicConfiguration();
|
||||
dynamicConfiguration.addListener(key, group, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(String key, String group, ConfigurationListener listener) {
|
||||
DynamicConfiguration dynamicConfiguration = DynamicConfiguration.getDynamicConfiguration();
|
||||
dynamicConfiguration.removeListener(key, group, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule(String key, String group, long timeout) throws IllegalStateException {
|
||||
DynamicConfiguration dynamicConfiguration = DynamicConfiguration.getDynamicConfiguration();
|
||||
return dynamicConfiguration.getConfig(key, group, timeout);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,11 @@ public @interface Reference {
|
|||
|
||||
String[] parameters() default {};
|
||||
|
||||
/**
|
||||
* Application associated name
|
||||
* @deprecated Do not set it and use the global Application Config
|
||||
*/
|
||||
@Deprecated
|
||||
String application() default "";
|
||||
|
||||
String module() default "";
|
||||
|
|
|
|||
|
|
@ -113,6 +113,11 @@ public @interface Service {
|
|||
|
||||
String[] parameters() default {};
|
||||
|
||||
/**
|
||||
* Application associated name
|
||||
* @deprecated Do not set it and use the global Application Config
|
||||
*/
|
||||
@Deprecated
|
||||
String application() default "";
|
||||
|
||||
String module() default "";
|
||||
|
|
|
|||
|
|
@ -72,6 +72,16 @@ public final class Version {
|
|||
return VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare versions
|
||||
* @return the value {@code 0} if {@code version1 == version2};
|
||||
* a value less than {@code 0} if {@code version1 < version2}; and
|
||||
* a value greater than {@code 0} if {@code version1 > version2}
|
||||
*/
|
||||
public static int compare(String version1, String version2) {
|
||||
return Integer.compare (getIntVersion(version1), getIntVersion(version2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the framework release version number to decide if it's 2.7.0 or higher
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package org.apache.dubbo.common.config;
|
|||
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
|
|
@ -30,9 +29,6 @@ import java.util.List;
|
|||
public class CompositeConfiguration implements Configuration {
|
||||
private Logger logger = LoggerFactory.getLogger(CompositeConfiguration.class);
|
||||
|
||||
private String id;
|
||||
private String prefix;
|
||||
|
||||
/**
|
||||
* List holding all the configuration
|
||||
*/
|
||||
|
|
@ -42,16 +38,6 @@ public class CompositeConfiguration implements Configuration {
|
|||
private boolean dynamicIncluded;
|
||||
|
||||
public CompositeConfiguration() {
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
public CompositeConfiguration(String prefix, String id) {
|
||||
if (StringUtils.isNotEmpty(prefix) && !prefix.endsWith(".")) {
|
||||
this.prefix = prefix + ".";
|
||||
} else {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public CompositeConfiguration(Configuration... configurations) {
|
||||
|
|
@ -87,42 +73,17 @@ public class CompositeConfiguration implements Configuration {
|
|||
|
||||
@Override
|
||||
public Object getInternalProperty(String key) {
|
||||
Configuration firstMatchingConfiguration = null;
|
||||
for (Configuration config : configList) {
|
||||
try {
|
||||
if (config.containsKey(key)) {
|
||||
firstMatchingConfiguration = config;
|
||||
break;
|
||||
Object value = config.getProperty(key);
|
||||
if (!ConfigurationUtils.isEmptyValue(value)) {
|
||||
return value;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Error when trying to get value for key " + key + " from " + config + ", will continue to try the next one.");
|
||||
}
|
||||
}
|
||||
if (firstMatchingConfiguration != null) {
|
||||
return firstMatchingConfiguration.getProperty(key);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(String key) {
|
||||
return configList.stream().anyMatch(c -> c.containsKey(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String key, Object defaultValue) {
|
||||
Object 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ package org.apache.dubbo.common.config;
|
|||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import static org.apache.dubbo.common.config.ConfigurationUtils.isEmptyValue;
|
||||
|
||||
/**
|
||||
* Configuration interface, to fetch the value for the specified key.
|
||||
*/
|
||||
|
|
@ -133,7 +135,7 @@ public interface Configuration {
|
|||
* key, {@code false} otherwise
|
||||
*/
|
||||
default boolean containsKey(String key) {
|
||||
return getProperty(key) != null;
|
||||
return !isEmptyValue(getProperty(key));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,13 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_SERVER_SHUTDOWN_TIMEOUT;
|
||||
|
|
@ -137,4 +141,97 @@ public class ConfigurationUtils {
|
|||
return map;
|
||||
}
|
||||
|
||||
public static boolean isEmptyValue(Object value) {
|
||||
return value == null ||
|
||||
value instanceof String && StringUtils.isBlank((String) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search props and extract sub properties.
|
||||
* <pre>
|
||||
* # properties
|
||||
* dubbo.protocol.name=dubbo
|
||||
* dubbo.protocol.port=1234
|
||||
*
|
||||
* # extract protocol props
|
||||
* Map props = getSubProperties("dubbo.protocol.");
|
||||
*
|
||||
* # result
|
||||
* props: {"name": "dubbo", "port" : "1234"}
|
||||
*
|
||||
* </pre>
|
||||
* @param configMaps
|
||||
* @param prefix
|
||||
* @param <V>
|
||||
* @return
|
||||
*/
|
||||
public static <V extends Object> Map<String, V> getSubProperties(Collection<Map<String, V>> configMaps, String prefix) {
|
||||
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());
|
||||
// convert camelCase/snake_case to kebab-case
|
||||
k = StringUtils.convertToSplitName(k, "-");
|
||||
map.putIfAbsent(k, val);
|
||||
}
|
||||
});
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static <V extends Object> boolean hasSubProperties(Collection<Map<String, V>> configMaps, String prefix) {
|
||||
if (!prefix.endsWith(".")) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search props and extract config ids
|
||||
* <pre>
|
||||
* # properties
|
||||
* dubbo.registries.registry1.address=xxx
|
||||
* dubbo.registries.registry2.port=xxx
|
||||
*
|
||||
* # extract ids
|
||||
* Set configIds = getSubIds("dubbo.registries.")
|
||||
*
|
||||
* # result
|
||||
* configIds: ["registry1", "registry2"]
|
||||
* </pre>
|
||||
*
|
||||
* @param configMaps
|
||||
* @param prefix
|
||||
* @return
|
||||
*/
|
||||
public static <V extends Object> Set<String> getSubIds(Collection<Map<String, V>> configMaps, String prefix) {
|
||||
Set<String> ids = new LinkedHashSet<>();
|
||||
for (Map<String, V> configMap : configMaps) {
|
||||
configMap.forEach((key, val) -> {
|
||||
if (StringUtils.startsWithIgnoreCase(key, prefix) && !ConfigurationUtils.isEmptyValue(val)) {
|
||||
String k = key.substring(prefix.length());
|
||||
int endIndex = k.indexOf(".");
|
||||
if (endIndex > 0) {
|
||||
String id = k.substring(0, endIndex);
|
||||
ids.add(id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,62 +25,60 @@ import org.apache.dubbo.common.logger.Logger;
|
|||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.ConfigCenterConfig;
|
||||
import org.apache.dubbo.config.context.ConfigConfigurationAdapter;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class Environment extends LifecycleAdapter implements FrameworkExt {
|
||||
private static final Logger logger = LoggerFactory.getLogger(Environment.class);
|
||||
|
||||
public static final String NAME = "environment";
|
||||
|
||||
private final PropertiesConfiguration propertiesConfiguration;
|
||||
private final SystemConfiguration systemConfiguration;
|
||||
private final EnvironmentConfiguration environmentConfiguration;
|
||||
private final InmemoryConfiguration externalConfiguration;
|
||||
private final InmemoryConfiguration appExternalConfiguration;
|
||||
// dubbo properties in classpath
|
||||
private PropertiesConfiguration propertiesConfiguration;
|
||||
|
||||
// java system props (-D)
|
||||
private SystemConfiguration systemConfiguration;
|
||||
|
||||
// java system environment
|
||||
private EnvironmentConfiguration environmentConfiguration;
|
||||
|
||||
// external config, such as config-center global/default config
|
||||
private InmemoryConfiguration externalConfiguration;
|
||||
|
||||
// external app config, such as config-center app config
|
||||
private InmemoryConfiguration appExternalConfiguration;
|
||||
|
||||
// local app config , such as Spring Environment/PropertySources/application.properties
|
||||
private InmemoryConfiguration appConfiguration;
|
||||
|
||||
private CompositeConfiguration globalConfiguration;
|
||||
private CompositeConfiguration dynamicGlobalConfiguration;
|
||||
|
||||
|
||||
private Map<String, String> externalConfigurationMap = new HashMap<>();
|
||||
private Map<String, String> appExternalConfigurationMap = new HashMap<>();
|
||||
|
||||
private boolean configCenterFirst = true;
|
||||
|
||||
private DynamicConfiguration dynamicConfiguration;
|
||||
private String localMigrationRule;
|
||||
|
||||
private AtomicBoolean initialized = new AtomicBoolean(false);
|
||||
|
||||
public Environment() {
|
||||
this.propertiesConfiguration = new PropertiesConfiguration();
|
||||
this.systemConfiguration = new SystemConfiguration();
|
||||
this.environmentConfiguration = new EnvironmentConfiguration();
|
||||
this.externalConfiguration = new InmemoryConfiguration();
|
||||
this.appExternalConfiguration = new InmemoryConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() throws IllegalStateException {
|
||||
ConfigManager configManager = ApplicationModel.getConfigManager();
|
||||
Optional<Collection<ConfigCenterConfig>> defaultConfigs = configManager.getDefaultConfigCenter();
|
||||
defaultConfigs.ifPresent(configs -> {
|
||||
for (ConfigCenterConfig config : configs) {
|
||||
this.setExternalConfigMap(config.getExternalConfiguration());
|
||||
this.setAppExternalConfigMap(config.getAppExternalConfiguration());
|
||||
}
|
||||
});
|
||||
if (initialized.compareAndSet(false, true)) {
|
||||
this.propertiesConfiguration = new PropertiesConfiguration();
|
||||
this.systemConfiguration = new SystemConfiguration();
|
||||
this.environmentConfiguration = new EnvironmentConfiguration();
|
||||
this.externalConfiguration = new InmemoryConfiguration("ExternalConfig");
|
||||
this.appExternalConfiguration = new InmemoryConfiguration("AppExternalConfig");
|
||||
this.appConfiguration = new InmemoryConfiguration("AppConfig");
|
||||
|
||||
this.externalConfiguration.setProperties(externalConfigurationMap);
|
||||
this.appExternalConfiguration.setProperties(appExternalConfigurationMap);
|
||||
|
||||
loadMigrationRule();
|
||||
loadMigrationRule();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadMigrationRule() {
|
||||
|
|
@ -97,31 +95,50 @@ public class Environment extends LifecycleAdapter implements FrameworkExt {
|
|||
@DisableInject
|
||||
public void setExternalConfigMap(Map<String, String> externalConfiguration) {
|
||||
if (externalConfiguration != null) {
|
||||
this.externalConfigurationMap = externalConfiguration;
|
||||
this.externalConfiguration.setProperties(externalConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
@DisableInject
|
||||
public void setAppExternalConfigMap(Map<String, String> appExternalConfiguration) {
|
||||
if (appExternalConfiguration != null) {
|
||||
this.appExternalConfigurationMap = appExternalConfiguration;
|
||||
this.appExternalConfiguration.setProperties(appExternalConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getExternalConfigurationMap() {
|
||||
return externalConfigurationMap;
|
||||
@DisableInject
|
||||
public void setAppConfigMap(Map<String, String> appConfiguration) {
|
||||
if (appConfiguration != null) {
|
||||
this.appConfiguration.setProperties(appConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getAppExternalConfigurationMap() {
|
||||
return appExternalConfigurationMap;
|
||||
public Map<String, String> getExternalConfigMap() {
|
||||
return externalConfiguration.getProperties();
|
||||
}
|
||||
|
||||
public void updateExternalConfigurationMap(Map<String, String> externalMap) {
|
||||
this.externalConfigurationMap.putAll(externalMap);
|
||||
public Map<String, String> getAppExternalConfigMap() {
|
||||
return appExternalConfiguration.getProperties();
|
||||
}
|
||||
|
||||
public void updateAppExternalConfigurationMap(Map<String, String> externalMap) {
|
||||
this.appExternalConfigurationMap.putAll(externalMap);
|
||||
public Map<String, String> getAppConfigMap() {
|
||||
return appConfiguration.getProperties();
|
||||
}
|
||||
|
||||
public void updateExternalConfigMap(Map<String, String> externalMap) {
|
||||
this.externalConfiguration.addProperties(externalMap);
|
||||
}
|
||||
|
||||
public void updateAppExternalConfigMap(Map<String, String> externalMap) {
|
||||
this.appExternalConfiguration.addProperties(externalMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge target map properties into app configuration
|
||||
* @param map
|
||||
*/
|
||||
public void updateAppConfigMap(Map<String, String> map) {
|
||||
this.appConfiguration.addProperties(map);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -132,31 +149,23 @@ public class Environment extends LifecycleAdapter implements FrameworkExt {
|
|||
* This method helps us to filter out the most priority values from various configuration sources.
|
||||
*
|
||||
* @param config
|
||||
* @param prefix
|
||||
* @return
|
||||
*/
|
||||
public synchronized CompositeConfiguration getPrefixedConfiguration(AbstractConfig config) {
|
||||
CompositeConfiguration prefixedConfiguration = new CompositeConfiguration(config.getPrefix(), config.getId());
|
||||
Configuration configuration = new ConfigConfigurationAdapter(config);
|
||||
if (this.isConfigCenterFirst()) {
|
||||
// The sequence would be: SystemConfiguration -> AppExternalConfiguration -> ExternalConfiguration -> AbstractConfig -> PropertiesConfiguration
|
||||
// Config center has the highest priority
|
||||
prefixedConfiguration.addConfiguration(systemConfiguration);
|
||||
prefixedConfiguration.addConfiguration(environmentConfiguration);
|
||||
prefixedConfiguration.addConfiguration(appExternalConfiguration);
|
||||
prefixedConfiguration.addConfiguration(externalConfiguration);
|
||||
prefixedConfiguration.addConfiguration(configuration);
|
||||
prefixedConfiguration.addConfiguration(propertiesConfiguration);
|
||||
} else {
|
||||
// The sequence would be: SystemConfiguration -> AbstractConfig -> AppExternalConfiguration -> ExternalConfiguration -> PropertiesConfiguration
|
||||
// Config center has the highest priority
|
||||
prefixedConfiguration.addConfiguration(systemConfiguration);
|
||||
prefixedConfiguration.addConfiguration(environmentConfiguration);
|
||||
prefixedConfiguration.addConfiguration(configuration);
|
||||
prefixedConfiguration.addConfiguration(appExternalConfiguration);
|
||||
prefixedConfiguration.addConfiguration(externalConfiguration);
|
||||
prefixedConfiguration.addConfiguration(propertiesConfiguration);
|
||||
}
|
||||
return prefixedConfiguration;
|
||||
public Configuration getPrefixedConfiguration(AbstractConfig config, String prefix) {
|
||||
|
||||
// The sequence would be: SystemConfiguration -> AppExternalConfiguration -> ExternalConfiguration -> AppConfiguration -> AbstractConfig -> PropertiesConfiguration
|
||||
Configuration instanceConfiguration = new ConfigConfigurationAdapter(config, prefix);
|
||||
CompositeConfiguration compositeConfiguration = new CompositeConfiguration();
|
||||
compositeConfiguration.addConfiguration(systemConfiguration);
|
||||
compositeConfiguration.addConfiguration(environmentConfiguration);
|
||||
compositeConfiguration.addConfiguration(appExternalConfiguration);
|
||||
compositeConfiguration.addConfiguration(externalConfiguration);
|
||||
compositeConfiguration.addConfiguration(appConfiguration);
|
||||
compositeConfiguration.addConfiguration(instanceConfiguration);
|
||||
compositeConfiguration.addConfiguration(propertiesConfiguration);
|
||||
|
||||
return new PrefixedConfiguration(compositeConfiguration, prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -165,18 +174,50 @@ public class Environment extends LifecycleAdapter implements FrameworkExt {
|
|||
* 2. The configuration exposed in this method is convenient for us to query the latest values from multiple
|
||||
* prioritized sources, it also guarantees that configs changed dynamically can take effect on the fly.
|
||||
*/
|
||||
public Configuration getConfiguration() {
|
||||
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);
|
||||
}
|
||||
return globalConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get configuration map list for target instance
|
||||
* @param config
|
||||
* @param prefix
|
||||
* @return
|
||||
*/
|
||||
public List<Map<String, String>> getConfigurationMaps(AbstractConfig config, String prefix) {
|
||||
// The sequence would be: SystemConfiguration -> AppExternalConfiguration -> ExternalConfiguration -> AppConfiguration -> AbstractConfig -> PropertiesConfiguration
|
||||
|
||||
List<Map<String, String>> maps = new ArrayList<>();
|
||||
maps.add(systemConfiguration.getProperties());
|
||||
maps.add(environmentConfiguration.getProperties());
|
||||
maps.add(appExternalConfiguration.getProperties());
|
||||
maps.add(externalConfiguration.getProperties());
|
||||
maps.add(appConfiguration.getProperties());
|
||||
if (config != null) {
|
||||
ConfigConfigurationAdapter configurationAdapter = new ConfigConfigurationAdapter(config, prefix);
|
||||
maps.add(configurationAdapter.getProperties());
|
||||
}
|
||||
maps.add(propertiesConfiguration.getProperties());
|
||||
return maps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get global configuration as map list
|
||||
* @return
|
||||
*/
|
||||
public List<Map<String, String>> getConfigurationMaps() {
|
||||
return getConfigurationMaps(null, null);
|
||||
}
|
||||
|
||||
public Configuration getDynamicGlobalConfiguration() {
|
||||
if (dynamicGlobalConfiguration == null) {
|
||||
if (dynamicConfiguration == null) {
|
||||
|
|
@ -192,15 +233,6 @@ public class Environment extends LifecycleAdapter implements FrameworkExt {
|
|||
return dynamicGlobalConfiguration;
|
||||
}
|
||||
|
||||
public boolean isConfigCenterFirst() {
|
||||
return configCenterFirst;
|
||||
}
|
||||
|
||||
@DisableInject
|
||||
public void setConfigCenterFirst(boolean configCenterFirst) {
|
||||
this.configCenterFirst = configCenterFirst;
|
||||
}
|
||||
|
||||
public Optional<DynamicConfiguration> getDynamicConfiguration() {
|
||||
return Optional.ofNullable(dynamicConfiguration);
|
||||
}
|
||||
|
|
@ -212,13 +244,31 @@ public class Environment extends LifecycleAdapter implements FrameworkExt {
|
|||
|
||||
@Override
|
||||
public void destroy() throws IllegalStateException {
|
||||
clearExternalConfigs();
|
||||
clearAppExternalConfigs();
|
||||
initialized.set(false);
|
||||
systemConfiguration = null;
|
||||
propertiesConfiguration = null;
|
||||
environmentConfiguration = null;
|
||||
externalConfiguration = null;
|
||||
appExternalConfiguration = null;
|
||||
appConfiguration = null;
|
||||
globalConfiguration = null;
|
||||
dynamicConfiguration = null;
|
||||
dynamicGlobalConfiguration = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset environment.
|
||||
* For test only.
|
||||
*/
|
||||
public void reset() {
|
||||
destroy();
|
||||
initialize();
|
||||
}
|
||||
|
||||
public String resolvePlaceholders(String str) {
|
||||
return ConfigUtils.replaceProperty(str, getConfiguration());
|
||||
}
|
||||
|
||||
public PropertiesConfiguration getPropertiesConfiguration() {
|
||||
return propertiesConfiguration;
|
||||
}
|
||||
|
|
@ -239,19 +289,12 @@ public class Environment extends LifecycleAdapter implements FrameworkExt {
|
|||
return appExternalConfiguration;
|
||||
}
|
||||
|
||||
public InmemoryConfiguration getAppConfiguration() {
|
||||
return appConfiguration;
|
||||
}
|
||||
|
||||
public String getLocalMigrationRule() {
|
||||
return localMigrationRule;
|
||||
}
|
||||
|
||||
// For test
|
||||
public void clearExternalConfigs() {
|
||||
this.externalConfiguration.clear();
|
||||
this.externalConfigurationMap.clear();
|
||||
}
|
||||
|
||||
// For test
|
||||
public void clearAppExternalConfigs() {
|
||||
this.appExternalConfiguration.clear();
|
||||
this.appExternalConfigurationMap.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ package org.apache.dubbo.common.config;
|
|||
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Configuration from system environment
|
||||
*/
|
||||
|
|
@ -32,4 +34,7 @@ public class EnvironmentConfiguration implements Configuration {
|
|||
return value;
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return System.getenv();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,22 @@ import java.util.Map;
|
|||
*/
|
||||
public class InmemoryConfiguration implements Configuration {
|
||||
|
||||
private String name;
|
||||
|
||||
// stores the configuration key-value pairs
|
||||
private Map<String, String> store = new LinkedHashMap<>();
|
||||
|
||||
public InmemoryConfiguration() {
|
||||
}
|
||||
|
||||
public InmemoryConfiguration(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public InmemoryConfiguration(Map<String, String> properties) {
|
||||
this.setProperties(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getInternalProperty(String key) {
|
||||
return store.get(key);
|
||||
|
|
@ -57,8 +70,8 @@ public class InmemoryConfiguration implements Configuration {
|
|||
}
|
||||
}
|
||||
|
||||
// for unit test
|
||||
public void clear() {
|
||||
this.store.clear();
|
||||
public Map<String, String> getProperties() {
|
||||
return store;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.common.config;
|
||||
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
||||
public class PrefixedConfiguration implements Configuration {
|
||||
|
||||
private String prefix;
|
||||
|
||||
private Configuration origin;
|
||||
|
||||
public PrefixedConfiguration(Configuration origin, String prefix) {
|
||||
this.origin = origin;
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getInternalProperty(String key) {
|
||||
if (StringUtils.isBlank(prefix)) {
|
||||
return origin.getInternalProperty(key);
|
||||
}
|
||||
|
||||
Object value = origin.getInternalProperty(prefix + "." + key);
|
||||
if (!ConfigurationUtils.isEmptyValue(value)) {
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.common.utils.ConfigUtils;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
|
|
@ -30,6 +31,7 @@ import java.util.Set;
|
|||
public class PropertiesConfiguration implements Configuration {
|
||||
|
||||
public PropertiesConfiguration() {
|
||||
|
||||
ExtensionLoader<OrderedPropertiesProvider> propertiesProviderExtensionLoader = ExtensionLoader.getExtensionLoader(OrderedPropertiesProvider.class);
|
||||
Set<String> propertiesProviderNames = propertiesProviderExtensionLoader.getSupportedExtensions();
|
||||
if (propertiesProviderNames == null || propertiesProviderNames.isEmpty()) {
|
||||
|
|
@ -54,11 +56,14 @@ public class PropertiesConfiguration implements Configuration {
|
|||
properties.putAll(orderedPropertiesProvider.initProperties());
|
||||
}
|
||||
|
||||
ConfigUtils.setProperties(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getInternalProperty(String key) {
|
||||
return ConfigUtils.getProperty(key);
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return (Map) ConfigUtils.getProperties();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
package org.apache.dubbo.common.config;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* FIXME: is this really necessary? PropertiesConfiguration should have already covered this:
|
||||
*
|
||||
|
|
@ -30,4 +32,7 @@ public class SystemConfiguration implements Configuration {
|
|||
return System.getProperty(key);
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return (Map) System.getProperties();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,6 +205,13 @@ public class ExtensionLoader<T> {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
// TODO Improve extension loader, clear static refer extension instance.
|
||||
// Some extension instances may be referenced by static fields, if clear EXTENSION_INSTANCES may cause inconsistent.
|
||||
// e.g. org.apache.dubbo.registry.client.metadata.MetadataUtils.localMetadataService
|
||||
// EXTENSION_INSTANCES.clear();
|
||||
|
||||
EXTENSION_LOADERS.clear();
|
||||
}
|
||||
|
||||
private static ClassLoader findClassLoader() {
|
||||
|
|
|
|||
|
|
@ -226,5 +226,14 @@ public class DefaultExecutorRepository implements ExecutorRepository {
|
|||
});
|
||||
}
|
||||
});
|
||||
|
||||
// TODO shutdown all executor services
|
||||
// for (ScheduledExecutorService executorService : scheduledExecutors.listItems()) {
|
||||
// executorService.shutdown();
|
||||
// }
|
||||
//
|
||||
// for (ExecutorService executorService : executorServiceRing.listItems()) {
|
||||
// executorService.shutdown();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.utils;
|
||||
|
||||
import org.apache.dubbo.common.config.Configuration;
|
||||
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;
|
||||
|
|
@ -128,6 +130,10 @@ public class ConfigUtils {
|
|||
}
|
||||
|
||||
public static String replaceProperty(String expression, Map<String, String> params) {
|
||||
return replaceProperty(expression, new InmemoryConfiguration(params));
|
||||
}
|
||||
|
||||
public static String replaceProperty(String expression, Configuration configuration) {
|
||||
if (expression == null || expression.length() == 0 || expression.indexOf('$') < 0) {
|
||||
return expression;
|
||||
}
|
||||
|
|
@ -136,11 +142,13 @@ public class ConfigUtils {
|
|||
while (matcher.find()) {
|
||||
String key = matcher.group(1);
|
||||
String value = System.getProperty(key);
|
||||
if (value == null && params != null) {
|
||||
value = params.get(key);
|
||||
if (value == null && configuration != null) {
|
||||
Object val = configuration.getProperty(key);
|
||||
value = (val != null) ? val.toString() : null;
|
||||
}
|
||||
if (value == null) {
|
||||
value = "";
|
||||
// maybe not placeholders, use origin express
|
||||
value = matcher.group();
|
||||
}
|
||||
matcher.appendReplacement(sb, Matcher.quoteReplacement(value));
|
||||
}
|
||||
|
|
@ -148,7 +156,13 @@ public class ConfigUtils {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dubbo properties.
|
||||
* It is not recommended to use this method to modify dubbo properties.
|
||||
* @return
|
||||
*/
|
||||
public static Properties getProperties() {
|
||||
//TODO remove global instance PROPERTIES from ConfigUtils
|
||||
if (PROPERTIES == null) {
|
||||
synchronized (ConfigUtils.class) {
|
||||
if (PROPERTIES == null) {
|
||||
|
|
@ -166,10 +180,18 @@ public class ConfigUtils {
|
|||
return PROPERTIES;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be called before Dubbo starting.
|
||||
* It is not recommended to use this method to modify dubbo properties.
|
||||
*/
|
||||
public static void setProperties(Properties properties) {
|
||||
PROPERTIES = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be called before Dubbo starting.
|
||||
* It is not recommended to use this method to modify dubbo properties.
|
||||
*/
|
||||
public static void addProperties(Properties properties) {
|
||||
if (properties != null) {
|
||||
getProperties().putAll(properties);
|
||||
|
|
@ -186,7 +208,10 @@ public class ConfigUtils {
|
|||
if (value != null && value.length() > 0) {
|
||||
return value;
|
||||
}
|
||||
Properties properties = getProperties();
|
||||
return getProperty(getProperties(), key, defaultValue);
|
||||
}
|
||||
|
||||
public static String getProperty(Properties properties, String key, String defaultValue) {
|
||||
return replaceProperty(properties.getProperty(key, defaultValue), (Map) properties);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import javassist.NotFoundException;
|
|||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.MethodDescriptor;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
|
|
@ -44,6 +45,7 @@ import java.util.LinkedHashSet;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
|
@ -1306,6 +1308,25 @@ public final class ReflectUtils {
|
|||
return propertyValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check target bean class whether has specify method
|
||||
* @param beanClass
|
||||
* @param methodName
|
||||
* @return
|
||||
*/
|
||||
public static boolean hasMethod(Class<?> beanClass, String methodName) {
|
||||
try {
|
||||
BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
|
||||
Optional<MethodDescriptor> descriptor = Stream.of(beanInfo.getMethodDescriptors())
|
||||
.filter(methodDescriptor -> methodName.equals(methodDescriptor.getName()))
|
||||
.findFirst();
|
||||
return descriptor.isPresent();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the types of the specified values
|
||||
*
|
||||
|
|
@ -1347,4 +1368,26 @@ public final class ReflectUtils {
|
|||
method.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all field names of target type
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public static Set<String> getAllFieldNames(Class<?> type) {
|
||||
|
||||
Set<String> fieldNames = new HashSet<>();
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
fieldNames.add(field.getName());
|
||||
}
|
||||
|
||||
Set<Class<?>> allSuperClasses = ClassUtils.getAllSuperClasses(type);
|
||||
for (Class<?> aClass : allSuperClasses) {
|
||||
for (Field field : aClass.getDeclaredFields()) {
|
||||
fieldNames.add(field.getName());
|
||||
}
|
||||
}
|
||||
return fieldNames;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -425,6 +425,15 @@ public final class StringUtils {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the cs String whether contains non whitespace characters.
|
||||
* @param cs
|
||||
* @return
|
||||
*/
|
||||
public static boolean hasText(CharSequence cs) {
|
||||
return !isBlank(cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* is empty string.
|
||||
*
|
||||
|
|
@ -894,6 +903,15 @@ public final class StringUtils {
|
|||
if (isEmpty(camelName)) {
|
||||
return camelName;
|
||||
}
|
||||
if (!isWord(camelName)) {
|
||||
// convert Ab-Cd-Ef to ab-cd-ef
|
||||
if (isSplitCase(camelName, split.charAt(0))) {
|
||||
return camelName.toLowerCase();
|
||||
}
|
||||
// not camel case
|
||||
return camelName;
|
||||
}
|
||||
|
||||
StringBuilder buf = null;
|
||||
for (int i = 0; i < camelName.length(); i++) {
|
||||
char ch = camelName.charAt(i);
|
||||
|
|
@ -912,7 +930,64 @@ public final class StringUtils {
|
|||
buf.append(ch);
|
||||
}
|
||||
}
|
||||
return buf == null ? camelName : buf.toString();
|
||||
return buf == null ? camelName.toLowerCase() : buf.toString().toLowerCase();
|
||||
}
|
||||
|
||||
private static boolean isSplitCase(String str, char separator) {
|
||||
if (str == null) {
|
||||
return false;
|
||||
}
|
||||
return str.chars().allMatch(ch -> (ch == separator) || isWord((char)ch) );
|
||||
}
|
||||
|
||||
private static boolean isWord(String str) {
|
||||
if (str == null) {
|
||||
return false;
|
||||
}
|
||||
return str.chars().allMatch(ch -> isWord((char)ch));
|
||||
}
|
||||
|
||||
private static boolean isWord(char ch) {
|
||||
if ((ch >= 'A' && ch <= 'Z') ||
|
||||
(ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= '0' && ch <= '9')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert snake_case or SNAKE_CASE to kebab-case.
|
||||
* <p>
|
||||
* NOTE: Return itself if it's not a snake case.
|
||||
* @param snakeName
|
||||
* @param split
|
||||
* @return
|
||||
*/
|
||||
public static String snakeToSplitName(String snakeName, String split) {
|
||||
String lowerCase = snakeName.toLowerCase();
|
||||
if (isSnakeCase(snakeName)) {
|
||||
return replace(lowerCase, "_", split);
|
||||
}
|
||||
return snakeName;
|
||||
}
|
||||
|
||||
protected static boolean isSnakeCase(String str) {
|
||||
return str.contains("_") || str.equals(str.toLowerCase()) || str.equals(str.toUpperCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert camelCase or snake_case/SNAKE_CASE to kebab-case
|
||||
* @param str
|
||||
* @param split
|
||||
* @return
|
||||
*/
|
||||
public static String convertToSplitName(String str, String split) {
|
||||
if (isSnakeCase(str)) {
|
||||
return snakeToSplitName(str, split);
|
||||
} else {
|
||||
return camelToSplitName(str, split);
|
||||
}
|
||||
}
|
||||
|
||||
public static String toArgumentString(Object[] args) {
|
||||
|
|
@ -1051,11 +1126,14 @@ public final class StringUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Decode parameters string to map
|
||||
* @param rawParameters format like '[{a:b},{c:d}]'
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, String> parseParameters(String rawParameters) {
|
||||
|
||||
if (StringUtils.isBlank(rawParameters)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Matcher matcher = PARAMETERS_PATTERN.matcher(rawParameters);
|
||||
if (!matcher.matches()) {
|
||||
return Collections.emptyMap();
|
||||
|
|
@ -1074,6 +1152,32 @@ public final class StringUtils {
|
|||
return parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode parameters map to string, like '[{a:b},{c:d}]'
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
public static String encodeParameters(Map<String, String> params) {
|
||||
if (params == null || params.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
params.forEach((key,value) -> {
|
||||
// {key:value},
|
||||
if (hasText(value)) {
|
||||
sb.append("{").append(key).append(":").append(value).append("},");
|
||||
}
|
||||
});
|
||||
// delete last separator ','
|
||||
if (sb.charAt(sb.length() - 1) == ',') {
|
||||
sb.deleteCharAt(sb.length()-1);
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static int decodeHexNibble(final char c) {
|
||||
// Character.digit() is not used here, as it addresses a larger
|
||||
// set of characters (both ASCII and full-width latin letters).
|
||||
|
|
@ -1106,4 +1210,18 @@ public final class StringUtils {
|
|||
String another = arrayToDelimitedString(others, COMMA_SEPARATOR);
|
||||
return isEmpty(another) ? one : one + COMMA_SEPARATOR + another;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test str whether starts with the prefix ignore case.
|
||||
* @param str
|
||||
* @param prefix
|
||||
* @return
|
||||
*/
|
||||
public static boolean startsWithIgnoreCase(String str, String prefix) {
|
||||
if (str == null || prefix == null || str.length() < prefix.length()) {
|
||||
return false;
|
||||
}
|
||||
// return str.substring(0, prefix.length()).equalsIgnoreCase(prefix);
|
||||
return str.regionMatches(true, 0, prefix, 0, prefix.length());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,9 @@
|
|||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.config.CompositeConfiguration;
|
||||
import org.apache.dubbo.common.config.ConfigurationUtils;
|
||||
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.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
|
@ -33,16 +34,25 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
|
|||
import org.apache.dubbo.rpc.model.AsyncMethodInfo;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.MethodDescriptor;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
|
@ -59,31 +69,19 @@ public abstract class AbstractConfig implements Serializable {
|
|||
private static final long serialVersionUID = 4267533505537413570L;
|
||||
|
||||
/**
|
||||
* The legacy properties container
|
||||
* The field names cache of config class
|
||||
*/
|
||||
private static final Map<String, String> LEGACY_PROPERTIES = new HashMap<String, String>();
|
||||
private static final Map<Class, Set<String>> fieldNamesCache = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* The suffix container
|
||||
*/
|
||||
private static final String[] SUFFIXES = new String[]{"Config", "Bean", "ConfigBase"};
|
||||
|
||||
static {
|
||||
LEGACY_PROPERTIES.put("dubbo.protocol.name", "dubbo.service.protocol");
|
||||
LEGACY_PROPERTIES.put("dubbo.protocol.host", "dubbo.service.server.host");
|
||||
LEGACY_PROPERTIES.put("dubbo.protocol.port", "dubbo.service.server.port");
|
||||
LEGACY_PROPERTIES.put("dubbo.protocol.threads", "dubbo.service.max.thread.pool.size");
|
||||
LEGACY_PROPERTIES.put("dubbo.consumer.timeout", "dubbo.service.invoke.timeout");
|
||||
LEGACY_PROPERTIES.put("dubbo.consumer.retries", "dubbo.service.max.retry.providers");
|
||||
LEGACY_PROPERTIES.put("dubbo.consumer.check", "dubbo.service.allow.no.provider");
|
||||
LEGACY_PROPERTIES.put("dubbo.service.url", "dubbo.service.address");
|
||||
}
|
||||
|
||||
/**
|
||||
* The config id
|
||||
*/
|
||||
protected String id;
|
||||
protected String prefix;
|
||||
private String id;
|
||||
|
||||
protected final AtomicBoolean refreshed = new AtomicBoolean(false);
|
||||
|
||||
|
|
@ -92,16 +90,6 @@ public abstract class AbstractConfig implements Serializable {
|
|||
*/
|
||||
protected Boolean isDefault;
|
||||
|
||||
private static String convertLegacyValue(String key, String value) {
|
||||
if (value != null && value.length() > 0) {
|
||||
if ("dubbo.service.max.retry.providers".equals(key)) {
|
||||
return String.valueOf(Integer.parseInt(value) - 1);
|
||||
} else if ("dubbo.service.allow.no.provider".equals(key)) {
|
||||
return String.valueOf(!Boolean.parseBoolean(value));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static String getTagName(Class<?> cls) {
|
||||
String tag = cls.getSimpleName();
|
||||
|
|
@ -114,57 +102,25 @@ public abstract class AbstractConfig implements Serializable {
|
|||
return StringUtils.camelToSplitName(tag, "-");
|
||||
}
|
||||
|
||||
public static String getPluralTagName(Class<?> cls) {
|
||||
String tagName = getTagName(cls);
|
||||
if (tagName.endsWith("y")) {
|
||||
// e.g. registry -> registries
|
||||
return tagName.substring(0, tagName.length() - 1) + "ies";
|
||||
} else if (tagName.endsWith("s")) {
|
||||
// e.g. metrics -> metricses
|
||||
return tagName + "es";
|
||||
}
|
||||
return tagName + "s";
|
||||
}
|
||||
|
||||
public static void appendParameters(Map<String, String> parameters, Object config) {
|
||||
appendParameters(parameters, config, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void appendParameters(Map<String, String> parameters, Object config, String prefix) {
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
Method[] methods = config.getClass().getMethods();
|
||||
for (Method method : methods) {
|
||||
try {
|
||||
String name = method.getName();
|
||||
if (MethodUtils.isGetter(method)) {
|
||||
Parameter parameter = method.getAnnotation(Parameter.class);
|
||||
if (method.getReturnType() == Object.class || parameter != null && parameter.excluded()) {
|
||||
continue;
|
||||
}
|
||||
String key;
|
||||
if (parameter != null && parameter.key().length() > 0) {
|
||||
key = parameter.key();
|
||||
} else {
|
||||
key = calculatePropertyFromGetter(name);
|
||||
}
|
||||
Object value = method.invoke(config);
|
||||
String str = String.valueOf(value).trim();
|
||||
if (value != null && str.length() > 0) {
|
||||
if (parameter != null && parameter.escaped()) {
|
||||
str = URL.encode(str);
|
||||
}
|
||||
if (parameter != null && parameter.append()) {
|
||||
String pre = parameters.get(key);
|
||||
if (pre != null && pre.length() > 0) {
|
||||
str = pre + "," + str;
|
||||
}
|
||||
}
|
||||
if (prefix != null && prefix.length() > 0) {
|
||||
key = prefix + "." + key;
|
||||
}
|
||||
parameters.put(key, str);
|
||||
} else if (parameter != null && parameter.required()) {
|
||||
throw new IllegalStateException(config.getClass().getSimpleName() + "." + key + " == null");
|
||||
}
|
||||
} else if (isParametersGetter(method)) {
|
||||
Map<String, String> map = (Map<String, String>) method.invoke(config, new Object[0]);
|
||||
parameters.putAll(convert(map, prefix));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
appendParameters0(parameters, config, prefix, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -172,41 +128,83 @@ public abstract class AbstractConfig implements Serializable {
|
|||
* @param parameters
|
||||
* @param config
|
||||
*/
|
||||
@Deprecated
|
||||
protected static void appendAttributes(Map<String, Object> parameters, Object config) {
|
||||
appendAttributes(parameters, config, null);
|
||||
public static void appendAttributes(Map<String, String> parameters, Object config) {
|
||||
appendParameters0(parameters, config, null, false);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected static void appendAttributes(Map<String, Object> parameters, Object config, String prefix) {
|
||||
private static void appendParameters0(Map<String, String> parameters, Object config, String prefix, boolean asParameters) {
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
Method[] methods = config.getClass().getMethods();
|
||||
for (Method method : methods) {
|
||||
// If asParameters=false, it means as attributes, ignore @Parameter annotation except 'append' and 'attribute'
|
||||
|
||||
// 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.
|
||||
|
||||
BeanInfo beanInfo = getBeanInfo(config.getClass());
|
||||
for (MethodDescriptor methodDescriptor : beanInfo.getMethodDescriptors()) {
|
||||
Method method = methodDescriptor.getMethod();
|
||||
try {
|
||||
Parameter parameter = method.getAnnotation(Parameter.class);
|
||||
if (parameter == null || !parameter.attribute()) {
|
||||
continue;
|
||||
}
|
||||
String name = method.getName();
|
||||
if (MethodUtils.isGetter(method)) {
|
||||
String key;
|
||||
if (parameter.key().length() > 0) {
|
||||
key = parameter.key();
|
||||
} else {
|
||||
key = calculateAttributeFromGetter(name);
|
||||
if (method.getReturnType() == Object.class ) {
|
||||
continue;
|
||||
}
|
||||
String key = calculatePropertyFromGetter(name);
|
||||
Parameter parameter = method.getAnnotation(Parameter.class);
|
||||
if (asParameters) {
|
||||
if (parameter != null && parameter.excluded()) {
|
||||
continue;
|
||||
}
|
||||
if (parameter != null && parameter.key().length() > 0) {
|
||||
key = parameter.key();
|
||||
}
|
||||
} else { // as attributes
|
||||
// filter non attribute
|
||||
if (parameter != null && !parameter.attribute()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Object value = method.invoke(config);
|
||||
if (value != null) {
|
||||
String str = String.valueOf(value).trim();
|
||||
if (value != null && str.length() > 0) {
|
||||
if (asParameters && parameter != null && parameter.escaped()) {
|
||||
str = URL.encode(str);
|
||||
}
|
||||
if (parameter != null && parameter.append()) {
|
||||
String pre = parameters.get(key);
|
||||
if (pre != null && pre.length() > 0) {
|
||||
str = pre + "," + str;
|
||||
//Remove duplicate values
|
||||
Set<String> set = StringUtils.splitToSet(str, ',');
|
||||
str = StringUtils.join(set, ",");
|
||||
}
|
||||
}
|
||||
if (prefix != null && prefix.length() > 0) {
|
||||
key = prefix + "." + key;
|
||||
}
|
||||
parameters.put(key, value);
|
||||
parameters.put(key, str);
|
||||
} else if (asParameters && parameter != null && parameter.required()) {
|
||||
throw new IllegalStateException(config.getClass().getSimpleName() + "." + key + " == null");
|
||||
}
|
||||
} else if (isParametersGetter(method)) {
|
||||
Map<String, String> map = (Map<String, String>) method.invoke(config);
|
||||
map = convert(map, prefix);
|
||||
if (asParameters) {
|
||||
// put all parameters to url
|
||||
parameters.putAll(map);
|
||||
} else {
|
||||
// encode parameters to string for config overriding, see AbstractConfig#refresh()
|
||||
String key = calculatePropertyFromGetter(name);
|
||||
String encodeParameters = StringUtils.encodeParameters(map);
|
||||
if (encodeParameters != null) {
|
||||
parameters.put(key, encodeParameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e.getMessage(), e);
|
||||
throw new IllegalStateException("Append parameters failed: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -264,20 +262,9 @@ public abstract class AbstractConfig implements Serializable {
|
|||
}).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private static String extractPropertyName(Class<?> clazz, Method setter) throws Exception {
|
||||
String propertyName = setter.getName().substring("set".length());
|
||||
Method getter = null;
|
||||
try {
|
||||
getter = clazz.getMethod("get" + propertyName);
|
||||
} catch (NoSuchMethodException e) {
|
||||
getter = clazz.getMethod("is" + propertyName);
|
||||
}
|
||||
Parameter parameter = getter.getAnnotation(Parameter.class);
|
||||
if (parameter != null && StringUtils.isNotEmpty(parameter.key()) && parameter.useKeyAsProperty()) {
|
||||
propertyName = parameter.key();
|
||||
} else {
|
||||
propertyName = propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1);
|
||||
}
|
||||
private static String extractPropertyName(String setter) throws Exception {
|
||||
String propertyName = setter.substring("set".length());
|
||||
propertyName = propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1);
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
|
|
@ -348,14 +335,14 @@ public abstract class AbstractConfig implements Serializable {
|
|||
String value = entry.getValue();
|
||||
result.put(pre + key, value);
|
||||
// For compatibility, key like "registry-type" will has a duplicate key "registry.type"
|
||||
if (Arrays.binarySearch(Constants.DOT_COMPATIBLE_KEYS, key) != -1) {
|
||||
if (Arrays.binarySearch(Constants.DOT_COMPATIBLE_KEYS, key) >= 0) {
|
||||
result.put(pre + key.replace('-', '.'), value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = true)
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
|
@ -415,92 +402,130 @@ public abstract class AbstractConfig implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Should be called after Config was fully initialized.
|
||||
* // FIXME: this method should be completely replaced by appendParameters
|
||||
*
|
||||
* @return
|
||||
* @see AbstractConfig#appendParameters(Map, Object, String)
|
||||
* <p>
|
||||
* Notice! This method should include all properties in the returning map, treat @Parameter differently compared to appendParameters.
|
||||
* <b>The new instance of the AbstractConfig subclass should return empty metadata.</b>
|
||||
* The purpose is is to get the attributes set by the user instead of the default value when the {@link #refresh()} method handles attribute overrides.
|
||||
* </p>
|
||||
*
|
||||
* <p><b>The default value of the field should be set in the {@link #checkDefault()} method</b>,
|
||||
* which will be called at the end of {@link #refresh()}, so that it will not affect the behavior of attribute overrides.</p>
|
||||
*
|
||||
* <p></p>
|
||||
* Should be called after Config was fully initialized.
|
||||
* <p>
|
||||
* Notice! This method should include all properties in the returning map, treat @Parameter differently compared to appendParameters?
|
||||
* </p>
|
||||
* // FIXME: this method should be completely replaced by appendParameters?
|
||||
* // -- Url parameter may use key, but props override only use property name. So replace it with appendAttributes().
|
||||
*
|
||||
* @see AbstractConfig#checkDefault()
|
||||
* @see AbstractConfig#appendParameters(Map, Object, String)
|
||||
*/
|
||||
public Map<String, String> getMetaData() {
|
||||
Map<String, String> metaData = new HashMap<>();
|
||||
Method[] methods = this.getClass().getMethods();
|
||||
for (Method method : methods) {
|
||||
try {
|
||||
String name = method.getName();
|
||||
if (MethodUtils.isMetaMethod(method)) {
|
||||
String key;
|
||||
Parameter parameter = method.getAnnotation(Parameter.class);
|
||||
if (parameter != null && parameter.key().length() > 0 && parameter.useKeyAsProperty()) {
|
||||
key = parameter.key();
|
||||
} else {
|
||||
key = calculateAttributeFromGetter(name);
|
||||
}
|
||||
// treat url and configuration differently, the value should always present in configuration though it may not need to present in url.
|
||||
//if (method.getReturnType() == Object.class || parameter != null && parameter.excluded()) {
|
||||
if (method.getReturnType() == Object.class) {
|
||||
metaData.put(key, null);
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attributes annotated as deprecated should not override newly added replacement.
|
||||
*/
|
||||
if (MethodUtils.isDeprecated(method) && metaData.get(key) != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Object value = method.invoke(this);
|
||||
String str = String.valueOf(value).trim();
|
||||
if (value != null && str.length() > 0) {
|
||||
metaData.put(key, str);
|
||||
} else {
|
||||
metaData.put(key, null);
|
||||
}
|
||||
} else if (isParametersGetter(method)) {
|
||||
Map<String, String> map = (Map<String, String>) method.invoke(this, new Object[0]);
|
||||
metaData.putAll(convert(map, ""));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
appendAttributes(metaData, this);
|
||||
return metaData;
|
||||
}
|
||||
|
||||
@Parameter(excluded = true)
|
||||
public String getPrefix() {
|
||||
return StringUtils.isNotEmpty(prefix) ? prefix : (CommonConstants.DUBBO + "." + getTagName(this.getClass()));
|
||||
protected static BeanInfo getBeanInfo(Class cls) {
|
||||
BeanInfo beanInfo = null;
|
||||
try {
|
||||
beanInfo = Introspector.getBeanInfo(cls);
|
||||
} catch (IntrospectionException e) {
|
||||
throw new IllegalStateException(e.getMessage(), e);
|
||||
}
|
||||
return beanInfo;
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
private static boolean isWritableProperty(BeanInfo beanInfo, String key) {
|
||||
for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
|
||||
if (key.equals(propertyDescriptor.getName())) {
|
||||
return propertyDescriptor.getWriteMethod() != null;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public List<String> getPrefixes() {
|
||||
List<String> prefixes = new ArrayList<>();
|
||||
if (StringUtils.hasText(this.getId())) {
|
||||
// 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)) {
|
||||
String prefix = CommonConstants.DUBBO + "." + getPluralTagName(this.getClass()) + "." + name;
|
||||
if (!prefixes.contains(prefix)) {
|
||||
prefixes.add(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
// dubbo.{tag-name}
|
||||
prefixes.add(getTypePrefix(this.getClass()));
|
||||
return prefixes;
|
||||
}
|
||||
|
||||
public static String getTypePrefix(Class<? extends AbstractConfig> cls) {
|
||||
return CommonConstants.DUBBO + "." + getTagName(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dubbo config property override
|
||||
*/
|
||||
public void refresh() {
|
||||
refreshed.set(true);
|
||||
Environment env = ApplicationModel.getEnvironment();
|
||||
try {
|
||||
CompositeConfiguration compositeConfiguration = env.getPrefixedConfiguration(this);
|
||||
// check and init before do refresh
|
||||
preProcessRefresh();
|
||||
|
||||
Environment environment = ApplicationModel.getEnvironment();
|
||||
List<Map<String, String>> configurationMaps = environment.getConfigurationMaps();
|
||||
|
||||
// Search props starts with PREFIX in order
|
||||
String preferredPrefix = null;
|
||||
for (String prefix : getPrefixes()) {
|
||||
if (ConfigurationUtils.hasSubProperties(configurationMaps, prefix)) {
|
||||
preferredPrefix = prefix;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (preferredPrefix == null) {
|
||||
preferredPrefix = getPrefixes().get(0);
|
||||
}
|
||||
// Extract sub props (which key was starts with preferredPrefix)
|
||||
Collection<Map<String, String>> instanceConfigMaps = environment.getConfigurationMaps(this, preferredPrefix);
|
||||
Map<String, String> subProperties = ConfigurationUtils.getSubProperties(instanceConfigMaps, preferredPrefix);
|
||||
InmemoryConfiguration subPropsConfiguration = new InmemoryConfiguration(subProperties);
|
||||
|
||||
// loop methods, get override value and set the new value back to method
|
||||
Method[] methods = getClass().getMethods();
|
||||
for (Method method : methods) {
|
||||
if (MethodUtils.isSetter(method)) {
|
||||
String propertyName = extractPropertyName(method.getName());
|
||||
// convert camelCase/snake_case to kebab-case
|
||||
String kebabPropertyName = StringUtils.convertToSplitName(propertyName, "-");
|
||||
|
||||
try {
|
||||
String value = StringUtils.trim(compositeConfiguration.getString(extractPropertyName(getClass(), method)));
|
||||
String value = StringUtils.trim(subPropsConfiguration.getString(kebabPropertyName));
|
||||
// isTypeMatch() is called to avoid duplicate and incorrect update, for example, we have two 'setGeneric' methods in ReferenceConfig.
|
||||
if (StringUtils.isNotEmpty(value) && ClassUtils.isTypeMatch(method.getParameterTypes()[0], value)) {
|
||||
if (StringUtils.hasText(value) && ClassUtils.isTypeMatch(method.getParameterTypes()[0], value) &&
|
||||
!isIgnoredAttribute(getClass(), propertyName)) {
|
||||
value = environment.resolvePlaceholders(value);
|
||||
method.invoke(this, ClassUtils.convertPrimitive(method.getParameterTypes()[0], value));
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
} 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.");
|
||||
}
|
||||
} else if (isParametersSetter(method)) {
|
||||
String value = StringUtils.trim(compositeConfiguration.getString(extractPropertyName(getClass(), method)));
|
||||
if (StringUtils.isNotEmpty(value)) {
|
||||
String propertyName = extractPropertyName(method.getName());
|
||||
String value = StringUtils.trim(subPropsConfiguration.getString(propertyName));
|
||||
if (StringUtils.hasText(value)) {
|
||||
Map<String, String> map = invokeGetParameters(getClass(), this);
|
||||
map = map == null ? new HashMap<>() : map;
|
||||
map.putAll(convert(StringUtils.parseParameters(value), ""));
|
||||
|
|
@ -508,12 +533,75 @@ public abstract class AbstractConfig implements Serializable {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// process extra refresh of sub class, e.g. refresh method configs
|
||||
processExtraRefresh(preferredPrefix, subPropsConfiguration);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to override ", e);
|
||||
logger.error("Failed to override field value of config bean: "+this, e);
|
||||
throw new IllegalStateException("Failed to override field value of config bean: "+this, e);
|
||||
}
|
||||
|
||||
postProcessRefresh();
|
||||
}
|
||||
|
||||
@Parameter(excluded = true)
|
||||
private boolean isIgnoredAttribute(Class<? extends AbstractConfig> clazz, String propertyName) {
|
||||
Method getter = null;
|
||||
String capitalizePropertyName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
|
||||
try {
|
||||
getter = clazz.getMethod("get" + capitalizePropertyName);
|
||||
} catch (NoSuchMethodException e) {
|
||||
try {
|
||||
getter = clazz.getMethod("is" + capitalizePropertyName);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
if (getter == null) {
|
||||
// no getter method
|
||||
return true;
|
||||
}
|
||||
|
||||
Parameter parameter = getter.getAnnotation(Parameter.class);
|
||||
if (parameter != null && !parameter.attribute()) {
|
||||
// not an attribute
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void processExtraRefresh(String preferredPrefix, InmemoryConfiguration subPropsConfiguration) {
|
||||
// process extra refresh
|
||||
}
|
||||
|
||||
protected void preProcessRefresh() {
|
||||
// pre-process refresh
|
||||
}
|
||||
|
||||
protected void postProcessRefresh() {
|
||||
// post-process refresh
|
||||
checkDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and set default value for some fields.
|
||||
* <p>
|
||||
* This method will be called at the end of {@link #refresh()}, as a post-initializer.
|
||||
* </p>
|
||||
* <p>NOTE: </p>
|
||||
* <p>
|
||||
* To distinguish between user-set property values and default property values,
|
||||
* do not initialize default value at field declare statement. <b>If the field has a default value,
|
||||
* it should be set in the checkDefault() method</b>, which will be called at the end of {@link #refresh()},
|
||||
* so that it will not affect the behavior of attribute overrides.</p>
|
||||
*
|
||||
* @see AbstractConfig#getMetaData()
|
||||
* @see AbstractConfig#appendAttributes(Map, Object)
|
||||
*/
|
||||
protected void checkDefault() {
|
||||
}
|
||||
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public boolean isRefreshed() {
|
||||
return refreshed.get();
|
||||
}
|
||||
|
|
@ -521,6 +609,9 @@ public abstract class AbstractConfig implements Serializable {
|
|||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
|
||||
Set<String> fieldNames = getFieldNames(this.getClass());
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("<dubbo:");
|
||||
buf.append(getTagName(getClass()));
|
||||
|
|
@ -531,10 +622,14 @@ public abstract class AbstractConfig implements Serializable {
|
|||
String name = method.getName();
|
||||
String key = calculateAttributeFromGetter(name);
|
||||
|
||||
try {
|
||||
getClass().getDeclaredField(key);
|
||||
} catch (NoSuchFieldException e) {
|
||||
// ignore
|
||||
// Fixes #4992, endless recursive call when NetUtils method fails.
|
||||
if (!fieldNames.contains(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// filter non attribute
|
||||
Parameter parameter = method.getAnnotation(Parameter.class);
|
||||
if (parameter != null && !parameter.attribute()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -559,10 +654,14 @@ public abstract class AbstractConfig implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
private static Set<String> getFieldNames(Class<?> configClass) {
|
||||
return fieldNamesCache.computeIfAbsent(configClass, ReflectUtils::getAllFieldNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME check @Parameter(required=true) and any conditions that need to match.
|
||||
*/
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -570,26 +669,39 @@ public abstract class AbstractConfig implements Serializable {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || !(obj.getClass().getName().equals(this.getClass().getName()))) {
|
||||
if (obj == null || obj.getClass() != this.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Method[] methods = this.getClass().getMethods();
|
||||
for (Method method1 : methods) {
|
||||
if (MethodUtils.isGetter(method1)) {
|
||||
Parameter parameter = method1.getAnnotation(Parameter.class);
|
||||
if (parameter != null && parameter.excluded()) {
|
||||
BeanInfo beanInfo = getBeanInfo(this.getClass());
|
||||
for (MethodDescriptor methodDescriptor : beanInfo.getMethodDescriptors()) {
|
||||
Method method = methodDescriptor.getMethod();
|
||||
if (MethodUtils.isGetter(method)) {
|
||||
// filter non attribute
|
||||
Parameter parameter = method.getAnnotation(Parameter.class);
|
||||
if (parameter != null && !parameter.attribute()) {
|
||||
continue;
|
||||
}
|
||||
String propertyName = calculateAttributeFromGetter(method.getName());
|
||||
// ignore compare 'id' value
|
||||
if (Constants.ID.equals(propertyName)) {
|
||||
continue;
|
||||
}
|
||||
// filter non writable property
|
||||
if (!isWritableProperty(beanInfo, propertyName)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
Method method2 = obj.getClass().getMethod(method1.getName(), method1.getParameterTypes());
|
||||
Object value1 = method1.invoke(this, new Object[]{});
|
||||
Object value2 = method2.invoke(obj, new Object[]{});
|
||||
Object value1 = method.invoke(this);
|
||||
Object value2 = method.invoke(obj);
|
||||
if (!Objects.equals(value1, value2)) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
throw new IllegalStateException("compare config instances failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -621,7 +733,7 @@ public abstract class AbstractConfig implements Serializable {
|
|||
continue;
|
||||
}
|
||||
try {
|
||||
Object value = method.invoke(this, new Object[]{});
|
||||
Object value = method.invoke(this);
|
||||
hashCode = 31 * hashCode + value.hashCode();
|
||||
} catch (Exception ignored) {
|
||||
//ignored
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package org.apache.dubbo.config;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.Version;
|
||||
import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.common.config.InmemoryConfiguration;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
|
|
@ -193,7 +193,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
/**
|
||||
* Check whether the registry config is exists, and then conversion it to {@link RegistryConfig}
|
||||
*/
|
||||
public void checkRegistry() {
|
||||
protected void checkRegistry() {
|
||||
convertRegistryIdsToRegistries();
|
||||
|
||||
for (RegistryConfig registryConfig : registries) {
|
||||
|
|
@ -213,57 +213,29 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the remote service interface and the methods meet with Dubbo's requirements.it mainly check, if the
|
||||
* methods configured in the configuration file are included in the interface of remote service
|
||||
*
|
||||
* @param interfaceClass the interface of remote service
|
||||
* @param methods the methods configured
|
||||
*/
|
||||
public void checkInterfaceAndMethods(Class<?> interfaceClass, List<MethodConfig> methods) {
|
||||
// interface cannot be null
|
||||
Assert.notNull(interfaceClass, new IllegalStateException("interface not allow null!"));
|
||||
|
||||
// to verify interfaceClass is an interface
|
||||
if (!interfaceClass.isInterface()) {
|
||||
throw new IllegalStateException("The interface class " + interfaceClass + " is not a interface!");
|
||||
}
|
||||
// check if methods exist in the remote service interface
|
||||
if (CollectionUtils.isNotEmpty(methods)) {
|
||||
for (MethodConfig methodBean : methods) {
|
||||
methodBean.setService(interfaceClass.getName());
|
||||
methodBean.setServiceId(this.getId());
|
||||
methodBean.refresh();
|
||||
String methodName = methodBean.getName();
|
||||
if (StringUtils.isEmpty(methodName)) {
|
||||
throw new IllegalStateException("<dubbo:method> name attribute is required! Please check: " +
|
||||
"<dubbo:service interface=\"" + interfaceClass.getName() + "\" ... >" +
|
||||
"<dubbo:method name=\"\" ... /></<dubbo:reference>");
|
||||
}
|
||||
|
||||
boolean hasMethod = Arrays.stream(interfaceClass.getMethods()).anyMatch(method -> method.getName().equals(methodName));
|
||||
if (!hasMethod) {
|
||||
throw new IllegalStateException("The interface " + interfaceClass.getName()
|
||||
+ " not found method " + methodName);
|
||||
}
|
||||
@Override
|
||||
protected void processExtraRefresh(String preferredPrefix, InmemoryConfiguration subPropsConfiguration) {
|
||||
List<MethodConfig> methodConfigs = this.getMethods();
|
||||
if (methodConfigs != null && methodConfigs.size() > 0) {
|
||||
for (MethodConfig methodConfig : methodConfigs) {
|
||||
methodConfig.setParentPrefix(preferredPrefix);
|
||||
methodConfig.refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Legitimacy check of stub, note that: the local will deprecated, and replace with <code>stub</code>
|
||||
*
|
||||
* @param interfaceClass for provider side, it is the {@link Class} of the service that will be exported; for consumer
|
||||
* side, it is the {@link Class} of the remote service interface
|
||||
*/
|
||||
public void checkStubAndLocal(Class<?> interfaceClass) {
|
||||
protected void checkStubAndLocal(Class<?> interfaceClass) {
|
||||
verifyStubAndLocal(local, "Local", interfaceClass);
|
||||
verifyStubAndLocal(stub, "Stub", interfaceClass);
|
||||
}
|
||||
|
||||
public void verifyStubAndLocal(String className, String label, Class<?> interfaceClass){
|
||||
|
||||
private void verifyStubAndLocal(String className, String label, Class<?> interfaceClass){
|
||||
if (ConfigUtils.isNotEmpty(className)) {
|
||||
Class<?> localClass = ConfigUtils.isDefault(className) ?
|
||||
ReflectUtils.forName(interfaceClass.getName() + label) : ReflectUtils.forName(className);
|
||||
|
|
@ -292,10 +264,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
if (CollectionUtils.isEmpty(registries)) {
|
||||
List<RegistryConfig> registryConfigs = ApplicationModel.getConfigManager().getDefaultRegistries();
|
||||
if (registryConfigs.isEmpty()) {
|
||||
registryConfigs = new ArrayList<>();
|
||||
RegistryConfig registryConfig = new RegistryConfig();
|
||||
registryConfig.refresh();
|
||||
registryConfigs.add(registryConfig);
|
||||
throw new IllegalStateException("Default registry is not initialized");
|
||||
} else {
|
||||
registryConfigs = new ArrayList<>(registryConfigs);
|
||||
}
|
||||
|
|
@ -310,19 +279,10 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
if (globalRegistry.isPresent()) {
|
||||
tmpRegistries.add(globalRegistry.get());
|
||||
} else {
|
||||
RegistryConfig registryConfig = new RegistryConfig();
|
||||
registryConfig.setId(id);
|
||||
registryConfig.refresh();
|
||||
tmpRegistries.add(registryConfig);
|
||||
throw new IllegalStateException("Registry not found: " + id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (tmpRegistries.size() > ids.length) {
|
||||
throw new IllegalStateException("Too much registries found, the registries assigned to this service " +
|
||||
"are :" + registryIds + ", but got " + tmpRegistries.size() + " registries!");
|
||||
}
|
||||
|
||||
setRegistries(tmpRegistries);
|
||||
}
|
||||
|
||||
|
|
@ -332,7 +292,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
return CollectionUtils.isEmpty(registries) && StringUtils.isEmpty(registryIds);
|
||||
}
|
||||
|
||||
public void completeCompoundConfigs(AbstractInterfaceConfig interfaceConfig) {
|
||||
protected void completeCompoundConfigs(AbstractInterfaceConfig interfaceConfig) {
|
||||
if (interfaceConfig != null) {
|
||||
if (application == null) {
|
||||
setApplication(interfaceConfig.getApplication());
|
||||
|
|
@ -486,14 +446,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
public void setApplication(ApplicationConfig application) {
|
||||
this.application = application;
|
||||
if (application != null) {
|
||||
ConfigManager configManager = ApplicationModel.getConfigManager();
|
||||
// FIXME, revert this change after spring bean initialization process fixed.
|
||||
if (!configManager.getApplication().isPresent()
|
||||
|| !configManager.getApplication().get().getName().equalsIgnoreCase(application.getName())) {
|
||||
configManager.setApplication(application);
|
||||
} else {
|
||||
application.refresh();
|
||||
}
|
||||
ApplicationModel.getConfigManager().setApplication(application);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -508,11 +461,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
public void setModule(ModuleConfig module) {
|
||||
this.module = module;
|
||||
if (module != null) {
|
||||
ConfigManager configManager = ApplicationModel.getConfigManager();
|
||||
configManager.getModule().orElseGet(() -> {
|
||||
configManager.setModule(module);
|
||||
return module;
|
||||
});
|
||||
ApplicationModel.getConfigManager().setModule(module);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -574,11 +523,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
public void setMonitor(MonitorConfig monitor) {
|
||||
this.monitor = monitor;
|
||||
if (monitor != null) {
|
||||
ConfigManager configManager = ApplicationModel.getConfigManager();
|
||||
configManager.getMonitor().orElseGet(() -> {
|
||||
configManager.setMonitor(monitor);
|
||||
return monitor;
|
||||
});
|
||||
ApplicationModel.getConfigManager().setMonitor(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -684,15 +629,11 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
public void setMetrics(MetricsConfig metrics) {
|
||||
this.metrics = metrics;
|
||||
if (metrics != null) {
|
||||
ConfigManager configManager = ApplicationModel.getConfigManager();
|
||||
configManager.getMetrics().orElseGet(() -> {
|
||||
configManager.setMetrics(metrics);
|
||||
return metrics;
|
||||
});
|
||||
ApplicationModel.getConfigManager().setMetrics(metrics);
|
||||
}
|
||||
}
|
||||
|
||||
@Parameter(key = TAG_KEY, useKeyAsProperty = false)
|
||||
@Parameter(key = TAG_KEY)
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
|
@ -713,7 +654,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
return ApplicationModel.getConfigManager().getSsl().orElse(null);
|
||||
}
|
||||
|
||||
public void initServiceMetadata(AbstractInterfaceConfig interfaceConfig) {
|
||||
protected void initServiceMetadata(AbstractInterfaceConfig interfaceConfig) {
|
||||
serviceMetadata.setVersion(getVersion(interfaceConfig));
|
||||
serviceMetadata.setGroup(getGroup(interfaceConfig));
|
||||
serviceMetadata.setDefaultGroup(getGroup(interfaceConfig));
|
||||
|
|
@ -750,8 +691,5 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
|
||||
public void setInterface(String interfaceName) {
|
||||
this.interfaceName = interfaceName;
|
||||
// if (StringUtils.isEmpty(id)) {
|
||||
// id = interfaceName;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public abstract class AbstractReferenceConfig extends AbstractInterfaceConfig {
|
|||
|
||||
protected String reconnect;
|
||||
|
||||
protected Boolean sticky = false;
|
||||
protected Boolean sticky;
|
||||
|
||||
/**
|
||||
* Whether to support event in stub.
|
||||
|
|
@ -80,6 +80,14 @@ public abstract class AbstractReferenceConfig extends AbstractInterfaceConfig {
|
|||
|
||||
protected String router;
|
||||
|
||||
@Override
|
||||
protected void checkDefault() {
|
||||
super.checkDefault();
|
||||
if (sticky == null) {
|
||||
sticky = false;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean isCheck() {
|
||||
return check;
|
||||
}
|
||||
|
|
@ -97,7 +105,7 @@ public abstract class AbstractReferenceConfig extends AbstractInterfaceConfig {
|
|||
}
|
||||
|
||||
@Deprecated
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public Boolean isGeneric() {
|
||||
return this.generic != null ? ProtocolUtils.isGeneric(generic) : null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public abstract class AbstractServiceConfig extends AbstractInterfaceConfig {
|
|||
/**
|
||||
* whether the service is deprecated
|
||||
*/
|
||||
protected Boolean deprecated = false;
|
||||
protected Boolean deprecated; // false;
|
||||
|
||||
/**
|
||||
* The time delay register service (milliseconds)
|
||||
|
|
@ -75,7 +75,7 @@ public abstract class AbstractServiceConfig extends AbstractInterfaceConfig {
|
|||
* after the service registered,and it needs to be disabled manually; if you want to disable the service, you also need
|
||||
* manual processing
|
||||
*/
|
||||
protected Boolean dynamic = true;
|
||||
protected Boolean dynamic; // true;
|
||||
|
||||
/**
|
||||
* Whether to use token
|
||||
|
|
@ -117,6 +117,17 @@ public abstract class AbstractServiceConfig extends AbstractInterfaceConfig {
|
|||
*/
|
||||
private String serialization;
|
||||
|
||||
@Override
|
||||
protected void checkDefault() {
|
||||
super.checkDefault();
|
||||
if (deprecated == null) {
|
||||
deprecated = false;
|
||||
}
|
||||
if (dynamic == null) {
|
||||
dynamic = true;
|
||||
}
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,16 +191,30 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
setName(name);
|
||||
}
|
||||
|
||||
@Parameter(key = APPLICATION_KEY, required = true, useKeyAsProperty = false)
|
||||
@Override
|
||||
protected void checkDefault() {
|
||||
super.checkDefault();
|
||||
if (protocol == null) {
|
||||
protocol = DUBBO;
|
||||
}
|
||||
if (hostname == null) {
|
||||
try {
|
||||
hostname = InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
LOGGER.warn("Failed to get the hostname of current instance.", e);
|
||||
hostname = "UNKNOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Parameter(key = APPLICATION_KEY, required = true)
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
if (StringUtils.isEmpty(id)) {
|
||||
id = name;
|
||||
}
|
||||
//this.updateIdIfAbsent(name);
|
||||
}
|
||||
|
||||
@Parameter(key = "application.version")
|
||||
|
|
@ -420,19 +434,11 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
|
||||
@Parameter(excluded = true)
|
||||
public String getHostname() {
|
||||
if (hostname == null) {
|
||||
try {
|
||||
hostname = InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
LOGGER.warn("Failed to get the hostname of current instance.", e);
|
||||
hostname = "UNKNOWN";
|
||||
}
|
||||
}
|
||||
return hostname;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public boolean isValid() {
|
||||
return !StringUtils.isEmpty(name);
|
||||
}
|
||||
|
|
@ -491,7 +497,7 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
|
||||
@Parameter(excluded = true, key="application-protocol")
|
||||
public String getProtocol() {
|
||||
return protocol == null ? DUBBO : protocol;
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
|
|
@ -554,11 +560,14 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
Map<String, String> extraParameters = adapter.getExtraAttributes(inputParameters);
|
||||
if (CollectionUtils.isNotEmptyMap(extraParameters)) {
|
||||
extraParameters.forEach((key, value) -> {
|
||||
String prefix = this.getPrefix() + ".";
|
||||
if (key.startsWith(prefix)) {
|
||||
key = key.substring(prefix.length());
|
||||
for (String prefix : this.getPrefixes()) {
|
||||
prefix += ".";
|
||||
if (key.startsWith(prefix)) {
|
||||
key = key.substring(prefix.length());
|
||||
}
|
||||
parameters.put(key, value);
|
||||
break;
|
||||
}
|
||||
parameters.put(key, value);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,25 +52,28 @@ public class ConfigCenterConfig extends AbstractConfig {
|
|||
but it's real meaning depends on the actual Config Center you use.
|
||||
*/
|
||||
|
||||
private String namespace = CommonConstants.DUBBO;
|
||||
private String namespace; // CommonConstants.DUBBO;
|
||||
/* The group of the config center, generally it's used to identify an isolated space for a batch of config items,
|
||||
but it's real meaning depends on the actual Config Center you use.
|
||||
*/
|
||||
private String group = CommonConstants.DUBBO;
|
||||
private String group; // CommonConstants.DUBBO;
|
||||
private String username;
|
||||
private String password;
|
||||
private Long timeout = 3000L;
|
||||
private Long timeout; // 3000L;
|
||||
|
||||
// If the Config Center is given the highest priority, it will override all the other configurations
|
||||
private Boolean highestPriority = true;
|
||||
/**
|
||||
* If the Config Center is given the highest priority, it will override all the other configurations
|
||||
* @deprecated no longer used
|
||||
*/
|
||||
private Boolean highestPriority; // true;
|
||||
|
||||
// Decide the behaviour when initial connection try fails, 'true' means interrupt the whole process once fail.
|
||||
private Boolean check = true;
|
||||
private Boolean check; // true;
|
||||
|
||||
/* Used to specify the key that your properties file mapping to, most of the time you do not need to change this parameter.
|
||||
Notice that for Apollo, this parameter is meaningless, set the 'namespace' is enough.
|
||||
*/
|
||||
private String configFile = CommonConstants.DEFAULT_DUBBO_PROPERTIES;
|
||||
private String configFile; // CommonConstants.DEFAULT_DUBBO_PROPERTIES;
|
||||
|
||||
/* the .properties file under 'configFile' is global shared while .properties under this one is limited only to this application
|
||||
*/
|
||||
|
|
@ -91,6 +94,30 @@ public class ConfigCenterConfig extends AbstractConfig {
|
|||
public ConfigCenterConfig() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkDefault() {
|
||||
super.checkDefault();
|
||||
|
||||
if (namespace == null) {
|
||||
namespace = CommonConstants.DUBBO;
|
||||
}
|
||||
if (group == null) {
|
||||
group = CommonConstants.DUBBO;
|
||||
}
|
||||
if (timeout == null) {
|
||||
timeout = 3000L;
|
||||
}
|
||||
// if (highestPriority == null) {
|
||||
// highestPriority = true;
|
||||
// }
|
||||
if (check == null) {
|
||||
check = true;
|
||||
}
|
||||
if (configFile == null) {
|
||||
configFile = CommonConstants.DEFAULT_DUBBO_PROPERTIES;
|
||||
}
|
||||
}
|
||||
|
||||
public URL toUrl() {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
appendParameters(map, this);
|
||||
|
|
@ -145,7 +172,6 @@ public class ConfigCenterConfig extends AbstractConfig {
|
|||
URL url = URL.valueOf(address);
|
||||
setUsername(url.getUsername());
|
||||
setPassword(url.getPassword());
|
||||
updateIdIfAbsent(url.getProtocol());
|
||||
updateProtocolIfAbsent(url.getProtocol());
|
||||
updatePortIfAbsent(url.getPort());
|
||||
updateParameters(url.getParameters());
|
||||
|
|
@ -194,11 +220,13 @@ public class ConfigCenterConfig extends AbstractConfig {
|
|||
this.check = check;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Parameter(key = CONFIG_ENABLE_KEY)
|
||||
public Boolean isHighestPriority() {
|
||||
return highestPriority;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setHighestPriority(Boolean highestPriority) {
|
||||
this.highestPriority = highestPriority;
|
||||
}
|
||||
|
|
@ -254,7 +282,7 @@ public class ConfigCenterConfig extends AbstractConfig {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public boolean isValid() {
|
||||
if (StringUtils.isEmpty(address)) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -30,9 +30,13 @@ public interface Constants {
|
|||
|
||||
String LAYER_KEY = "layer";
|
||||
|
||||
// General
|
||||
|
||||
/**
|
||||
* General
|
||||
* Config id
|
||||
*/
|
||||
String ID = "id";
|
||||
|
||||
/**
|
||||
* Application name;
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ import org.apache.dubbo.config.support.Parameter;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROPERTIES_CHAR_SEPARATOR;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.isEmpty;
|
||||
|
||||
/**
|
||||
|
|
@ -36,11 +34,6 @@ import static org.apache.dubbo.common.utils.StringUtils.isEmpty;
|
|||
public class MetadataReportConfig extends AbstractConfig {
|
||||
|
||||
private static final long serialVersionUID = 55233L;
|
||||
/**
|
||||
* the value is : metadata-report
|
||||
*/
|
||||
private static final String PREFIX_TAG = StringUtils.camelToSplitName(
|
||||
MetadataReportConfig.class.getSimpleName().substring(0, MetadataReportConfig.class.getSimpleName().length() - 6), PROPERTIES_CHAR_SEPARATOR);
|
||||
|
||||
// Register center address
|
||||
private String address;
|
||||
|
|
@ -197,13 +190,7 @@ public class MetadataReportConfig extends AbstractConfig {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Parameter(excluded = true)
|
||||
public String getPrefix() {
|
||||
return StringUtils.isNotEmpty(prefix) ? prefix : (DUBBO + "." + PREFIX_TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public boolean isValid() {
|
||||
return StringUtils.isNotEmpty(address);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.annotation.Method;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
|
||||
|
|
@ -117,15 +115,17 @@ public class MethodConfig extends AbstractMethodConfig {
|
|||
private List<ArgumentConfig> arguments;
|
||||
|
||||
/**
|
||||
* TODO remove service and serviceId
|
||||
* These properties come from MethodConfig's parent Config module, they will neither be collected directly from xml or API nor be delivered to url
|
||||
*/
|
||||
private String service;
|
||||
private String serviceId;
|
||||
|
||||
@Parameter(excluded = true)
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
/**
|
||||
* The preferred prefix of parent
|
||||
*/
|
||||
private String parentPrefix;
|
||||
|
||||
|
||||
public MethodConfig() {
|
||||
}
|
||||
|
|
@ -191,6 +191,34 @@ public class MethodConfig extends AbstractMethodConfig {
|
|||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get method prefixes
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Parameter(excluded = true)
|
||||
public List<String> getPrefixes() {
|
||||
// parent prefix + method name
|
||||
if (parentPrefix != null) {
|
||||
List<String> prefixes = new ArrayList<>();
|
||||
prefixes.add(parentPrefix + "." +this.getName());
|
||||
return prefixes;
|
||||
} else {
|
||||
throw new IllegalStateException("The parent prefix of MethodConfig is null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIntoConfigManager() {
|
||||
// Don't add MethodConfig to ConfigManager
|
||||
// super.addIntoConfigManager();
|
||||
}
|
||||
|
||||
@Parameter(excluded = true)
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
// FIXME, add id strategy in ConfigManager
|
||||
|
|
@ -323,7 +351,7 @@ public class MethodConfig extends AbstractMethodConfig {
|
|||
this.isReturn = isReturn;
|
||||
}
|
||||
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public String getService() {
|
||||
return service;
|
||||
}
|
||||
|
|
@ -332,7 +360,7 @@ public class MethodConfig extends AbstractMethodConfig {
|
|||
this.service = service;
|
||||
}
|
||||
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public String getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
|
|
@ -341,16 +369,12 @@ public class MethodConfig extends AbstractMethodConfig {
|
|||
this.serviceId = serviceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* service and name must not be null.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Parameter(excluded = true)
|
||||
public String getPrefix() {
|
||||
return CommonConstants.DUBBO + "." + service
|
||||
+ (StringUtils.isEmpty(serviceId) ? "" : ("." + serviceId))
|
||||
+ "." + getName();
|
||||
public void setParentPrefix(String parentPrefix) {
|
||||
this.parentPrefix = parentPrefix;
|
||||
}
|
||||
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public String getParentPrefix() {
|
||||
return parentPrefix;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -76,9 +75,7 @@ public class ModuleConfig extends AbstractConfig {
|
|||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
if (StringUtils.isEmpty(id)) {
|
||||
id = name;
|
||||
}
|
||||
//this.updateIdIfAbsent(name);
|
||||
}
|
||||
|
||||
@Parameter(key = "module.version")
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ public class MonitorConfig extends AbstractConfig {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public boolean isValid() {
|
||||
return StringUtils.isNotEmpty(address) || RegistryConstants.REGISTRY_PROTOCOL.equals(protocol);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,8 @@ import org.apache.dubbo.config.support.Parameter;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY;
|
||||
import static org.apache.dubbo.config.Constants.PROTOCOLS_SUFFIX;
|
||||
|
||||
/**
|
||||
* ProtocolConfig
|
||||
|
|
@ -212,6 +211,29 @@ public class ProtocolConfig extends AbstractConfig {
|
|||
setPort(port);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkDefault() {
|
||||
super.checkDefault();
|
||||
if (name == null) {
|
||||
name = DUBBO_PROTOCOL;
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public List<String> getPrefixes() {
|
||||
// List<String> prefixes = new ArrayList<>();
|
||||
// if (StringUtils.hasText(this.getId())) {
|
||||
// // dubbo.protocols.{protocol-id}
|
||||
// prefixes.add(CommonConstants.DUBBO + "." + getPluralTagName(this.getClass()) + "." + this.getId());
|
||||
// } else if (StringUtils.hasText(this.getName()) && !StringUtils.isEquals(this.getId(), this.getName())) {
|
||||
// // dubbo.protocols.{protocol-name}
|
||||
// prefixes.add(CommonConstants.DUBBO + "." + getPluralTagName(this.getClass()) + "." + this.getName());
|
||||
// }
|
||||
// // dubbo.protocol
|
||||
// prefixes.add(getTypePrefix());
|
||||
// return prefixes;
|
||||
// }
|
||||
|
||||
@Parameter(excluded = true)
|
||||
public String getName() {
|
||||
return name;
|
||||
|
|
@ -219,7 +241,7 @@ public class ProtocolConfig extends AbstractConfig {
|
|||
|
||||
public final void setName(String name) {
|
||||
this.name = name;
|
||||
this.updateIdIfAbsent(name);
|
||||
//this.updateIdIfAbsent(name);
|
||||
}
|
||||
|
||||
@Parameter(excluded = true)
|
||||
|
|
@ -524,19 +546,7 @@ public class ProtocolConfig extends AbstractConfig {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
if (StringUtils.isEmpty(this.getName())) {
|
||||
this.setName(DUBBO_VERSION_KEY);
|
||||
}
|
||||
super.refresh();
|
||||
if (StringUtils.isNotEmpty(this.getId())) {
|
||||
this.setPrefix(PROTOCOLS_SUFFIX);
|
||||
super.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public boolean isValid() {
|
||||
return StringUtils.isNotEmpty(name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ import org.apache.dubbo.rpc.support.ProtocolUtils;
|
|||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
|
||||
|
|
@ -81,6 +85,7 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
|
|||
}
|
||||
|
||||
public boolean shouldCheck() {
|
||||
checkDefault();
|
||||
Boolean shouldCheck = isCheck();
|
||||
if (shouldCheck == null && getConsumer() != null) {
|
||||
shouldCheck = getConsumer().isCheck();
|
||||
|
|
@ -93,6 +98,7 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
|
|||
}
|
||||
|
||||
public boolean shouldInit() {
|
||||
checkDefault();
|
||||
Boolean shouldInit = isInit();
|
||||
if (shouldInit == null && getConsumer() != null) {
|
||||
shouldInit = getConsumer().isInit();
|
||||
|
|
@ -104,14 +110,39 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
|
|||
return shouldInit;
|
||||
}
|
||||
|
||||
public void checkDefault() throws IllegalStateException {
|
||||
@Override
|
||||
protected void preProcessRefresh() {
|
||||
super.preProcessRefresh();
|
||||
if (consumer == null) {
|
||||
consumer = ApplicationModel.getConfigManager()
|
||||
.getDefaultConsumer()
|
||||
.orElse(new ConsumerConfig());
|
||||
.orElseThrow(() -> new IllegalArgumentException("Default consumer is not initialized"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public List<String> getPrefixes() {
|
||||
List<String> prefixes = new ArrayList<>();
|
||||
// dubbo.reference.{interface-name}
|
||||
prefixes.add(DUBBO + ".reference." + interfaceName);
|
||||
return prefixes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMetaData() {
|
||||
Map<String, String> metaData = new HashMap<>();
|
||||
ConsumerConfig consumer = this.getConsumer();
|
||||
// consumer should be inited at preProcessRefresh()
|
||||
if (isRefreshed() && consumer == null) {
|
||||
throw new IllegalStateException("Consumer is not initialized");
|
||||
}
|
||||
// use consumer attributes as default value
|
||||
appendAttributes(metaData, consumer);
|
||||
appendAttributes(metaData, this);
|
||||
return metaData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get actual interface class of this reference.
|
||||
* The actual service type of remote provider.
|
||||
|
|
@ -220,13 +251,7 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
|
|||
return serviceMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Parameter(excluded = true)
|
||||
public String getPrefix() {
|
||||
return DUBBO + ".reference." + interfaceName;
|
||||
}
|
||||
|
||||
public void resolveFile() {
|
||||
protected void resolveFile() {
|
||||
String resolve = System.getProperty(interfaceName);
|
||||
String resolveFile = null;
|
||||
if (StringUtils.isEmpty(resolve)) {
|
||||
|
|
@ -268,13 +293,12 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
|
|||
setRegistryIds(consumer.getRegistryIds());
|
||||
}
|
||||
}
|
||||
|
||||
super.computeValidRegistryIds();
|
||||
}
|
||||
|
||||
@Parameter(excluded = true)
|
||||
public String getUniqueServiceName() {
|
||||
return URL.buildKey(interfaceName, getGroup(), getVersion());
|
||||
return interfaceName != null ? URL.buildKey(interfaceName, getGroup(), getVersion()) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PUBLI
|
|||
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PUBLISH_INTERFACE_KEY;
|
||||
import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
|
||||
import static org.apache.dubbo.common.utils.PojoUtils.updatePropertyIfAbsent;
|
||||
import static org.apache.dubbo.config.Constants.REGISTRIES_SUFFIX;
|
||||
|
||||
/**
|
||||
* RegistryConfig
|
||||
|
|
@ -208,6 +207,7 @@ public class RegistryConfig extends AbstractConfig {
|
|||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
// protocol as id is inappropriate, registries's protocol may be duplicated
|
||||
// this.updateIdIfAbsent(protocol);
|
||||
}
|
||||
|
||||
|
|
@ -228,11 +228,6 @@ public class RegistryConfig extends AbstractConfig {
|
|||
updatePropertyIfAbsent(this::getProtocol, this::setProtocol, url.getProtocol());
|
||||
updatePropertyIfAbsent(this::getPort, this::setPort, url.getPort());
|
||||
|
||||
// setUsername(url.getUsername());
|
||||
// setPassword(url.getPassword());
|
||||
// updateIdIfAbsent(url.getProtocol());
|
||||
// updateProtocolIfAbsent(url.getProtocol());
|
||||
// updatePortIfAbsent(url.getPort());
|
||||
Map<String, String> params = url.getParameters();
|
||||
if (CollectionUtils.isNotEmptyMap(params)) {
|
||||
params.remove(BACKUP_KEY);
|
||||
|
|
@ -529,16 +524,7 @@ public class RegistryConfig extends AbstractConfig {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
super.refresh();
|
||||
if (StringUtils.isNotEmpty(this.getId())) {
|
||||
this.setPrefix(REGISTRIES_SUFFIX);
|
||||
super.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public boolean isValid() {
|
||||
// empty protocol will default to 'dubbo'
|
||||
return !StringUtils.isEmpty(address);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,12 @@ import org.apache.dubbo.rpc.support.ProtocolUtils;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
|
||||
|
|
@ -166,7 +170,7 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
return (delay == null && provider != null) ? provider.getDelay() : delay;
|
||||
}
|
||||
|
||||
public void checkRef() {
|
||||
protected void checkRef() {
|
||||
// reference should not be null, and is the implementation of the given interface
|
||||
if (ref == null) {
|
||||
throw new IllegalStateException("ref not allow null!");
|
||||
|
|
@ -190,23 +194,37 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
return ref.getClass();
|
||||
}
|
||||
|
||||
public void checkDefault() throws IllegalStateException {
|
||||
@Override
|
||||
protected void preProcessRefresh() {
|
||||
super.preProcessRefresh();
|
||||
convertProviderIdToProvider();
|
||||
if (provider == null) {
|
||||
provider = ApplicationModel.getConfigManager()
|
||||
.getDefaultProvider()
|
||||
.orElse(new ProviderConfig());
|
||||
.orElseThrow(() -> new IllegalArgumentException("Default provider is not initialized"));
|
||||
}
|
||||
}
|
||||
|
||||
public void checkProtocol() {
|
||||
@Override
|
||||
public Map<String, String> getMetaData() {
|
||||
Map<String, String> metaData = new HashMap<>();
|
||||
ProviderConfig provider = this.getProvider();
|
||||
// provider should be inited at preProcessRefresh()
|
||||
if (isRefreshed() && provider == null) {
|
||||
throw new IllegalStateException("Provider is not initialized");
|
||||
}
|
||||
// use provider attributes as default value
|
||||
appendAttributes(metaData, provider);
|
||||
// Finally, put the service's attributes, overriding previous attributes
|
||||
appendAttributes(metaData, this);
|
||||
return metaData;
|
||||
}
|
||||
|
||||
protected void checkProtocol() {
|
||||
if (provider != null && notHasSelfProtocolProperty()) {
|
||||
setProtocols(provider.getProtocols());
|
||||
setProtocolIds(provider.getProtocolIds());
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(protocols) && provider != null) {
|
||||
setProtocols(provider.getProtocols());
|
||||
}
|
||||
convertProtocolIdsToProtocols();
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +232,7 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
return CollectionUtils.isEmpty(protocols) && StringUtils.isEmpty(protocolIds);
|
||||
}
|
||||
|
||||
public void completeCompoundConfigs() {
|
||||
protected void completeCompoundConfigs() {
|
||||
super.completeCompoundConfigs(provider);
|
||||
if (provider != null) {
|
||||
if (notHasSelfProtocolProperty()) {
|
||||
|
|
@ -227,39 +245,33 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
}
|
||||
}
|
||||
|
||||
private void convertProtocolIdsToProtocols() {
|
||||
protected void convertProviderIdToProvider() {
|
||||
if (provider == null && StringUtils.hasText(providerIds)) {
|
||||
provider = ApplicationModel.getConfigManager().getProvider(providerIds)
|
||||
.orElseThrow(() -> new IllegalStateException("Provider config not found: " + providerIds));
|
||||
}
|
||||
}
|
||||
|
||||
protected void convertProtocolIdsToProtocols() {
|
||||
if (StringUtils.isEmpty(protocolIds)) {
|
||||
if (CollectionUtils.isEmpty(protocols)) {
|
||||
List<ProtocolConfig> protocolConfigs = ApplicationModel.getConfigManager().getDefaultProtocols();
|
||||
if (protocolConfigs.isEmpty()) {
|
||||
protocolConfigs = new ArrayList<>(1);
|
||||
ProtocolConfig protocolConfig = new ProtocolConfig();
|
||||
protocolConfig.setDefault(true);
|
||||
protocolConfig.refresh();
|
||||
protocolConfigs.add(protocolConfig);
|
||||
ApplicationModel.getConfigManager().addProtocol(protocolConfig);
|
||||
throw new IllegalStateException("The default protocol has not been initialized.");
|
||||
}
|
||||
setProtocols(protocolConfigs);
|
||||
}
|
||||
} else {
|
||||
String[] arr = COMMA_SPLIT_PATTERN.split(protocolIds);
|
||||
String[] idsArray = COMMA_SPLIT_PATTERN.split(protocolIds);
|
||||
Set<String> idsSet = new LinkedHashSet<>(Arrays.asList(idsArray));
|
||||
List<ProtocolConfig> tmpProtocols = new ArrayList<>();
|
||||
Arrays.stream(arr).forEach(id -> {
|
||||
if (tmpProtocols.stream().noneMatch(prot -> prot.getId().equals(id))) {
|
||||
Optional<ProtocolConfig> globalProtocol = ApplicationModel.getConfigManager().getProtocol(id);
|
||||
if (globalProtocol.isPresent()) {
|
||||
tmpProtocols.add(globalProtocol.get());
|
||||
} else {
|
||||
ProtocolConfig protocolConfig = new ProtocolConfig();
|
||||
protocolConfig.setId(id);
|
||||
protocolConfig.refresh();
|
||||
tmpProtocols.add(protocolConfig);
|
||||
}
|
||||
for (String id : idsSet) {
|
||||
Optional<ProtocolConfig> globalProtocol = ApplicationModel.getConfigManager().getProtocol(id);
|
||||
if (globalProtocol.isPresent()) {
|
||||
tmpProtocols.add(globalProtocol.get());
|
||||
} else {
|
||||
throw new IllegalStateException("Protocol not found: "+id);
|
||||
}
|
||||
});
|
||||
if (tmpProtocols.size() > arr.length) {
|
||||
throw new IllegalStateException("Too much protocols found, the protocols comply to this service are :" + protocolIds + " but got " + protocols
|
||||
.size() + " registries!");
|
||||
}
|
||||
setProtocols(tmpProtocols);
|
||||
}
|
||||
|
|
@ -366,31 +378,34 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
return serviceMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Replace to getProtocols()
|
||||
*/
|
||||
@Deprecated
|
||||
public List<ProviderConfig> getProviders() {
|
||||
return convertProtocolToProvider(protocols);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Replace to setProtocols()
|
||||
*/
|
||||
@Deprecated
|
||||
public void setProviders(List<ProviderConfig> providers) {
|
||||
this.protocols = convertProviderToProtocol(providers);
|
||||
}
|
||||
// /**
|
||||
// * @deprecated Replace to getProtocols()
|
||||
// */
|
||||
// @Deprecated
|
||||
// public List<ProviderConfig> getProviders() {
|
||||
// return convertProtocolToProvider(protocols);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @deprecated Replace to setProtocols()
|
||||
// */
|
||||
// @Deprecated
|
||||
// public void setProviders(List<ProviderConfig> providers) {
|
||||
// this.protocols = convertProviderToProtocol(providers);
|
||||
// }
|
||||
|
||||
@Override
|
||||
@Parameter(excluded = true)
|
||||
public String getPrefix() {
|
||||
return DUBBO + ".service." + interfaceName;
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public List<String> getPrefixes() {
|
||||
List<String> prefixes = new ArrayList<>();
|
||||
// dubbo.service.{interface-name}
|
||||
prefixes.add(DUBBO + ".service." + interfaceName);
|
||||
return prefixes;
|
||||
}
|
||||
|
||||
@Parameter(excluded = true)
|
||||
public String getUniqueServiceName() {
|
||||
return URL.buildKey(interfaceName, getGroup(), getVersion());
|
||||
return interfaceName != null ? URL.buildKey(interfaceName, getGroup(), getVersion()) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -409,7 +424,6 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
setRegistries(provider.getRegistries());
|
||||
setRegistryIds(provider.getRegistryIds());
|
||||
}
|
||||
|
||||
super.computeValidRegistryIds();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -270,7 +270,9 @@ public @interface DubboReference {
|
|||
|
||||
/**
|
||||
* Application associated name
|
||||
* @deprecated Do not set it and use the global Application Config
|
||||
*/
|
||||
@Deprecated
|
||||
String application() default "";
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -236,7 +236,9 @@ public @interface DubboService {
|
|||
|
||||
/**
|
||||
* Application spring bean name
|
||||
* @deprecated Do not set it and use the global Application Config
|
||||
*/
|
||||
@Deprecated
|
||||
String application() default "";
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -234,7 +234,9 @@ public @interface Reference {
|
|||
|
||||
/**
|
||||
* Application associated name
|
||||
* @deprecated Do not set it and use the global Application Config
|
||||
*/
|
||||
@Deprecated
|
||||
String application() default "";
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -236,7 +236,9 @@ public @interface Service {
|
|||
|
||||
/**
|
||||
* Application spring bean name
|
||||
* @deprecated Do not set it and use the global Application Config
|
||||
*/
|
||||
@Deprecated
|
||||
String application() default "";
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,13 +30,15 @@ public class ConfigConfigurationAdapter implements Configuration {
|
|||
|
||||
private Map<String, String> metaData;
|
||||
|
||||
public ConfigConfigurationAdapter(AbstractConfig config) {
|
||||
Map<String, String> configMetadata = config.getMetaData();
|
||||
metaData = new HashMap<>(configMetadata.size(), 1.0f);
|
||||
for (Map.Entry<String, String> entry : configMetadata.entrySet()) {
|
||||
String prefix = config.getPrefix().endsWith(".") ? config.getPrefix() : config.getPrefix() + ".";
|
||||
String id = StringUtils.isEmpty(config.getId()) ? "" : config.getId() + ".";
|
||||
metaData.put(prefix + id + entry.getKey(), entry.getValue());
|
||||
public ConfigConfigurationAdapter(AbstractConfig config, String prefix) {
|
||||
Map<String, String> configMetadata = config.getMetaData();
|
||||
if (StringUtils.hasText(prefix)) {
|
||||
metaData = new HashMap<>(configMetadata.size(), 1.0f);
|
||||
for (Map.Entry<String, String> entry : configMetadata.entrySet()) {
|
||||
metaData.put(prefix + "." + entry.getKey(), entry.getValue());
|
||||
}
|
||||
} else {
|
||||
metaData = configMetadata;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -45,4 +47,7 @@ public class ConfigConfigurationAdapter implements Configuration {
|
|||
return metaData.get(key);
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return metaData;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,14 +18,18 @@ package org.apache.dubbo.config.context;
|
|||
|
||||
import org.apache.dubbo.common.context.FrameworkExt;
|
||||
import org.apache.dubbo.common.context.LifecycleAdapter;
|
||||
import org.apache.dubbo.common.extension.DisableInject;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.ConcurrentHashSet;
|
||||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ConfigCenterConfig;
|
||||
import org.apache.dubbo.config.ConsumerConfig;
|
||||
import org.apache.dubbo.config.MetadataReportConfig;
|
||||
import org.apache.dubbo.config.MethodConfig;
|
||||
import org.apache.dubbo.config.MetricsConfig;
|
||||
import org.apache.dubbo.config.ModuleConfig;
|
||||
import org.apache.dubbo.config.MonitorConfig;
|
||||
|
|
@ -35,18 +39,16 @@ import org.apache.dubbo.config.ReferenceConfigBase;
|
|||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfigBase;
|
||||
import org.apache.dubbo.config.SslConfig;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
|
@ -54,27 +56,36 @@ import java.util.stream.Collectors;
|
|||
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.unmodifiableSet;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
|
||||
import static org.apache.dubbo.common.utils.ReflectUtils.getProperty;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
|
||||
import static org.apache.dubbo.config.AbstractConfig.getTagName;
|
||||
import static org.apache.dubbo.config.Constants.PROTOCOLS_SUFFIX;
|
||||
import static org.apache.dubbo.config.Constants.REGISTRIES_SUFFIX;
|
||||
|
||||
public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class);
|
||||
|
||||
public static final String NAME = "config";
|
||||
public static final String BEAN_NAME = "dubboConfigManager";
|
||||
private static final String CONFIG_NAME_READ_METHOD = "getName";
|
||||
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
final Map<String, Map<String, AbstractConfig>> configsCache = newMap();
|
||||
|
||||
private static Map<Class, AtomicInteger> configIdIndexes = new ConcurrentHashMap<>();
|
||||
|
||||
private static volatile boolean configWarnLogEnabled = false;
|
||||
private static Map<String, Boolean> warnLogStatus = new ConcurrentHashMap<>();
|
||||
|
||||
private static Set<Class<? extends AbstractConfig>> uniqueConfigTypes = new ConcurrentHashSet<>();
|
||||
|
||||
static {
|
||||
// init unique config types
|
||||
uniqueConfigTypes.add(ApplicationConfig.class);
|
||||
uniqueConfigTypes.add(ModuleConfig.class);
|
||||
uniqueConfigTypes.add(MonitorConfig.class);
|
||||
uniqueConfigTypes.add(MetricsConfig.class);
|
||||
uniqueConfigTypes.add(SslConfig.class);
|
||||
}
|
||||
|
||||
public ConfigManager() {
|
||||
try {
|
||||
|
|
@ -83,18 +94,24 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
configWarnLogEnabled = Boolean.parseBoolean(rawWarn);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("Illegal 'dubbo.application.config.warn'config, only boolean value is accepted.", e);
|
||||
logger.warn("Illegal 'dubbo.application.config.warn' config, only boolean value is accepted.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// ApplicationConfig correlative methods
|
||||
|
||||
/**
|
||||
* Set application config
|
||||
* @param application
|
||||
* @return current application config instance
|
||||
*/
|
||||
@DisableInject
|
||||
public void setApplication(ApplicationConfig application) {
|
||||
addConfig(application, true);
|
||||
}
|
||||
|
||||
public Optional<ApplicationConfig> getApplication() {
|
||||
return ofNullable(getConfig(getTagName(ApplicationConfig.class)));
|
||||
return ofNullable(getSingleConfig(getTagName(ApplicationConfig.class)));
|
||||
}
|
||||
|
||||
public ApplicationConfig getApplicationOrElseThrow() {
|
||||
|
|
@ -103,38 +120,42 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
|
||||
// MonitorConfig correlative methods
|
||||
|
||||
@DisableInject
|
||||
public void setMonitor(MonitorConfig monitor) {
|
||||
addConfig(monitor, true);
|
||||
}
|
||||
|
||||
public Optional<MonitorConfig> getMonitor() {
|
||||
return ofNullable(getConfig(getTagName(MonitorConfig.class)));
|
||||
return ofNullable(getSingleConfig(getTagName(MonitorConfig.class)));
|
||||
}
|
||||
|
||||
// ModuleConfig correlative methods
|
||||
|
||||
@DisableInject
|
||||
public void setModule(ModuleConfig module) {
|
||||
addConfig(module, true);
|
||||
}
|
||||
|
||||
public Optional<ModuleConfig> getModule() {
|
||||
return ofNullable(getConfig(getTagName(ModuleConfig.class)));
|
||||
return ofNullable(getSingleConfig(getTagName(ModuleConfig.class)));
|
||||
}
|
||||
|
||||
@DisableInject
|
||||
public void setMetrics(MetricsConfig metrics) {
|
||||
addConfig(metrics, true);
|
||||
}
|
||||
|
||||
public Optional<MetricsConfig> getMetrics() {
|
||||
return ofNullable(getConfig(getTagName(MetricsConfig.class)));
|
||||
return ofNullable(getSingleConfig(getTagName(MetricsConfig.class)));
|
||||
}
|
||||
|
||||
@DisableInject
|
||||
public void setSsl(SslConfig sslConfig) {
|
||||
addConfig(sslConfig, true);
|
||||
}
|
||||
|
||||
public Optional<SslConfig> getSsl() {
|
||||
return ofNullable(getConfig(getTagName(SslConfig.class)));
|
||||
return ofNullable(getSingleConfig(getTagName(SslConfig.class)));
|
||||
}
|
||||
|
||||
// ConfigCenterConfig correlative methods
|
||||
|
|
@ -155,8 +176,8 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
return Optional.ofNullable(defaults);
|
||||
}
|
||||
|
||||
public ConfigCenterConfig getConfigCenter(String id) {
|
||||
return getConfig(getTagName(ConfigCenterConfig.class), id);
|
||||
public Optional<ConfigCenterConfig> getConfigCenter(String id) {
|
||||
return getConfig(ConfigCenterConfig.class, id);
|
||||
}
|
||||
|
||||
public Collection<ConfigCenterConfig> getConfigCenters() {
|
||||
|
|
@ -196,7 +217,7 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
}
|
||||
|
||||
public Optional<ProviderConfig> getProvider(String id) {
|
||||
return ofNullable(getConfig(getTagName(ProviderConfig.class), id));
|
||||
return getConfig(ProviderConfig.class, id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -225,7 +246,7 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
}
|
||||
|
||||
public Optional<ConsumerConfig> getConsumer(String id) {
|
||||
return ofNullable(getConfig(getTagName(ConsumerConfig.class), id));
|
||||
return getConfig(ConsumerConfig.class, id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -255,28 +276,22 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
}
|
||||
}
|
||||
|
||||
public Optional<ProtocolConfig> getProtocol(String id) {
|
||||
return ofNullable(getConfig(getTagName(ProtocolConfig.class), id));
|
||||
public Optional<ProtocolConfig> getProtocol(String idOrName) {
|
||||
return getConfig(ProtocolConfig.class, idOrName);
|
||||
}
|
||||
|
||||
public List<ProtocolConfig> getDefaultProtocols() {
|
||||
return getDefaultConfigs(getConfigsMap(getTagName(ProtocolConfig.class)));
|
||||
return getDefaultConfigs(ProtocolConfig.class);
|
||||
}
|
||||
|
||||
public <C extends AbstractConfig> List<C> getDefaultConfigs(Class<C> cls) {
|
||||
return getDefaultConfigs(getConfigsMap(getTagName(cls)));
|
||||
}
|
||||
|
||||
public Collection<ProtocolConfig> getProtocols() {
|
||||
return getConfigs(getTagName(ProtocolConfig.class));
|
||||
}
|
||||
|
||||
public Set<String> getProtocolIds() {
|
||||
Set<String> protocolIds = new HashSet<>();
|
||||
protocolIds.addAll(getSubProperties(ApplicationModel.getEnvironment()
|
||||
.getExternalConfigurationMap(), PROTOCOLS_SUFFIX));
|
||||
protocolIds.addAll(getSubProperties(ApplicationModel.getEnvironment()
|
||||
.getAppExternalConfigurationMap(), PROTOCOLS_SUFFIX));
|
||||
|
||||
return unmodifiableSet(protocolIds);
|
||||
}
|
||||
|
||||
|
||||
// RegistryConfig correlative methods
|
||||
|
||||
|
|
@ -291,7 +306,21 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
}
|
||||
|
||||
public Optional<RegistryConfig> getRegistry(String id) {
|
||||
return ofNullable(getConfig(getTagName(RegistryConfig.class), id));
|
||||
return getConfig(RegistryConfig.class, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config instance by id or by name
|
||||
* @param cls Config type
|
||||
* @param idOrName the id or name of the config
|
||||
* @return
|
||||
*/
|
||||
public <T extends AbstractConfig> Optional<T> getConfig(Class<T> cls, String idOrName) {
|
||||
T config = getConfigById(getTagName(cls), idOrName);
|
||||
if (config == null ) {
|
||||
config = getConfigByName(cls, idOrName);
|
||||
}
|
||||
return ofNullable(config);
|
||||
}
|
||||
|
||||
public List<RegistryConfig> getDefaultRegistries() {
|
||||
|
|
@ -302,16 +331,6 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
return getConfigs(getTagName(RegistryConfig.class));
|
||||
}
|
||||
|
||||
public Set<String> getRegistryIds() {
|
||||
Set<String> registryIds = new HashSet<>();
|
||||
registryIds.addAll(getSubProperties(ApplicationModel.getEnvironment().getExternalConfigurationMap(),
|
||||
REGISTRIES_SUFFIX));
|
||||
registryIds.addAll(getSubProperties(ApplicationModel.getEnvironment().getAppExternalConfigurationMap(),
|
||||
REGISTRIES_SUFFIX));
|
||||
|
||||
return unmodifiableSet(registryIds);
|
||||
}
|
||||
|
||||
// ServiceConfig correlative methods
|
||||
|
||||
public void addService(ServiceConfigBase<?> serviceConfig) {
|
||||
|
|
@ -327,7 +346,7 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
}
|
||||
|
||||
public <T> ServiceConfigBase<T> getService(String id) {
|
||||
return getConfig(getTagName(ServiceConfigBase.class), id);
|
||||
return getConfig(ServiceConfigBase.class, id).orElse(null);
|
||||
}
|
||||
|
||||
// ReferenceConfig correlative methods
|
||||
|
|
@ -345,14 +364,7 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
}
|
||||
|
||||
public <T> ReferenceConfigBase<T> getReference(String id) {
|
||||
return getConfig(getTagName(ReferenceConfigBase.class), id);
|
||||
}
|
||||
|
||||
protected static Set<String> getSubProperties(Map<String, String> properties, String prefix) {
|
||||
return properties.keySet().stream().filter(k -> k.contains(prefix)).map(k -> {
|
||||
k = k.substring(prefix.length());
|
||||
return k.substring(0, k.indexOf("."));
|
||||
}).collect(Collectors.toSet());
|
||||
return getConfig(ReferenceConfigBase.class, id).orElse(null);
|
||||
}
|
||||
|
||||
public void refreshAll() {
|
||||
|
|
@ -361,11 +373,15 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
getApplication().ifPresent(ApplicationConfig::refresh);
|
||||
getMonitor().ifPresent(MonitorConfig::refresh);
|
||||
getModule().ifPresent(ModuleConfig::refresh);
|
||||
getMetrics().ifPresent(MetricsConfig::refresh);
|
||||
getSsl().ifPresent(SslConfig::refresh);
|
||||
|
||||
getProtocols().forEach(ProtocolConfig::refresh);
|
||||
getRegistries().forEach(RegistryConfig::refresh);
|
||||
getProviders().forEach(ProviderConfig::refresh);
|
||||
getConsumers().forEach(ConsumerConfig::refresh);
|
||||
getConfigCenters().forEach(ConfigCenterConfig::refresh);
|
||||
getMetadataConfigs().forEach(MetadataReportConfig::refresh);
|
||||
});
|
||||
|
||||
}
|
||||
|
|
@ -382,12 +398,15 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
|
||||
Map<String, AbstractConfig> configs = configsCache.get(getTagName(config.getClass()));
|
||||
if (CollectionUtils.isNotEmptyMap(configs)) {
|
||||
configs.remove(getId(config));
|
||||
configs.values().removeIf(c -> config == c);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
write(this.configsCache::clear);
|
||||
write(() -> {
|
||||
this.configsCache.clear();
|
||||
configIdIndexes.clear();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -405,35 +424,97 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
* @param config the dubbo {@link AbstractConfig config}
|
||||
*/
|
||||
public void addConfig(AbstractConfig config) {
|
||||
addConfig(config, false);
|
||||
}
|
||||
|
||||
protected void addConfig(AbstractConfig config, boolean unique) {
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
write(() -> {
|
||||
addConfig(config, isUniqueConfig(config));
|
||||
}
|
||||
|
||||
private boolean isUniqueConfig(AbstractConfig config) {
|
||||
return uniqueConfigTypes.contains(config.getClass());
|
||||
}
|
||||
|
||||
protected <T extends AbstractConfig> T addConfig(AbstractConfig config, boolean unique) {
|
||||
if (config == null) {
|
||||
return null;
|
||||
}
|
||||
// ignore MethodConfig
|
||||
if (config instanceof MethodConfig) {
|
||||
return null;
|
||||
}
|
||||
return (T) write(() -> {
|
||||
Map<String, AbstractConfig> configsMap = configsCache.computeIfAbsent(getTagName(config.getClass()), type -> newMap());
|
||||
addIfAbsent(config, configsMap, unique);
|
||||
return addIfAbsent(config, configsMap, unique);
|
||||
});
|
||||
}
|
||||
|
||||
protected <C extends AbstractConfig> Map<String, C> getConfigsMap(String configType) {
|
||||
public <C extends AbstractConfig> Map<String, C> getConfigsMap(Class<C> cls) {
|
||||
return getConfigsMap(getTagName(cls));
|
||||
}
|
||||
|
||||
private <C extends AbstractConfig> Map<String, C> getConfigsMap(String configType) {
|
||||
return (Map<String, C>) read(() -> configsCache.getOrDefault(configType, emptyMap()));
|
||||
}
|
||||
|
||||
protected <C extends AbstractConfig> Collection<C> getConfigs(String configType) {
|
||||
private <C extends AbstractConfig> Collection<C> getConfigs(String configType) {
|
||||
return (Collection<C>) read(() -> getConfigsMap(configType).values());
|
||||
}
|
||||
|
||||
protected <C extends AbstractConfig> C getConfig(String configType, String id) {
|
||||
public <C extends AbstractConfig> Collection<C> getConfigs(Class<C> configType) {
|
||||
return (Collection<C>) read(() -> getConfigsMap(getTagName(configType)).values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config by id
|
||||
* @param configType
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
private <C extends AbstractConfig> C getConfigById(String configType, String id) {
|
||||
return read(() -> {
|
||||
Map<String, C> configsMap = (Map) configsCache.getOrDefault(configType, emptyMap());
|
||||
return configsMap.get(id);
|
||||
});
|
||||
}
|
||||
|
||||
protected <C extends AbstractConfig> C getConfig(String configType) throws IllegalStateException {
|
||||
/**
|
||||
* Get config by name if existed
|
||||
* @param cls
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
private <C extends AbstractConfig> C getConfigByName(Class<? extends C> cls, String name) {
|
||||
return read(() -> {
|
||||
String configType = getTagName(cls);
|
||||
Map<String, C> configsMap = (Map) configsCache.getOrDefault(configType, emptyMap());
|
||||
if (configsMap.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
// try find config by name
|
||||
if (ReflectUtils.hasMethod(cls, CONFIG_NAME_READ_METHOD)) {
|
||||
List<C> list = configsMap.values().stream()
|
||||
.filter(cfg -> name.equals(getConfigName(cfg)))
|
||||
.collect(Collectors.toList());
|
||||
if (list.size() > 1) {
|
||||
throw new IllegalStateException("Found more than one config by name: " + name +
|
||||
", instances: " + list + ". Please remove redundant configs or get config by id.");
|
||||
} else if (list.size() == 1) {
|
||||
return list.get(0);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private <C extends AbstractConfig> String getConfigName(C config) {
|
||||
try {
|
||||
return (String) ReflectUtils.getProperty(config, CONFIG_NAME_READ_METHOD);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected <C extends AbstractConfig> C getSingleConfig(String configType) throws IllegalStateException {
|
||||
return read(() -> {
|
||||
Map<String, C> configsMap = (Map) configsCache.getOrDefault(configType, emptyMap());
|
||||
int size = configsMap.size();
|
||||
|
|
@ -441,22 +522,8 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
// throw new IllegalStateException("No such " + configType.getName() + " is found");
|
||||
return null;
|
||||
} else if (size > 1) {
|
||||
AtomicReference<C> defaultConfig = new AtomicReference<>();
|
||||
configsMap.forEach((str, config) -> {
|
||||
if (Boolean.TRUE.equals(config.isDefault())) {
|
||||
defaultConfig.compareAndSet(null, config);
|
||||
}
|
||||
});
|
||||
|
||||
if (defaultConfig.get() != null) {
|
||||
return defaultConfig.get();
|
||||
}
|
||||
|
||||
|
||||
if (configWarnLogEnabled && warnLogStatus.get(configType) == null) {
|
||||
logger.warn("Expected single matching of " + configType + ", but found " + size + " instances, will randomly pick the first one.");
|
||||
warnLogStatus.put(configType, true);
|
||||
}
|
||||
throw new IllegalStateException("Expected single instance of " + configType + ", but found " + size +
|
||||
" instances, please remove redundant configs. instances: "+configsMap.values());
|
||||
}
|
||||
|
||||
return configsMap.values().iterator().next();
|
||||
|
|
@ -501,23 +568,52 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
}
|
||||
|
||||
private static void checkDuplicate(AbstractConfig oldOne, AbstractConfig newOne) throws IllegalStateException {
|
||||
if (oldOne != null && !oldOne.equals(newOne)) {
|
||||
if (!isEquals(oldOne, newOne)) {
|
||||
String configName = oldOne.getClass().getSimpleName();
|
||||
if (configWarnLogEnabled) {
|
||||
logger.warn("Duplicate Config found for " + configName + ", only one unique " + configName + " is allowed for one application.");
|
||||
throw new IllegalStateException("Duplicate Configs found for " + configName + ", only one unique " + configName +
|
||||
" is allowed for one application. old: "+oldOne+", new: "+newOne);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isEquals(AbstractConfig oldOne, AbstractConfig newOne) {
|
||||
if (oldOne == newOne) {
|
||||
return true;
|
||||
}
|
||||
if (oldOne == null || newOne == null) {
|
||||
return false;
|
||||
}
|
||||
if (oldOne.getClass() != newOne.getClass()) {
|
||||
return false;
|
||||
}
|
||||
// make both are refreshed or none is refreshed
|
||||
if (oldOne.isRefreshed() || newOne.isRefreshed()) {
|
||||
if (!oldOne.isRefreshed()) {
|
||||
oldOne.refresh();
|
||||
}
|
||||
if (!newOne.isRefreshed()) {
|
||||
newOne.refresh();
|
||||
}
|
||||
}
|
||||
return oldOne.equals(newOne);
|
||||
}
|
||||
|
||||
private static Map newMap() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
static <C extends AbstractConfig> void addIfAbsent(C config, Map<String, C> configsMap, boolean unique)
|
||||
/**
|
||||
* Add config
|
||||
* @param config
|
||||
* @param configsMap
|
||||
* @param unique
|
||||
* @return the existing equivalent config or the new adding config
|
||||
* @throws IllegalStateException
|
||||
*/
|
||||
static <C extends AbstractConfig> C addIfAbsent(C config, Map<String, C> configsMap, boolean unique)
|
||||
throws IllegalStateException {
|
||||
|
||||
if (config == null || configsMap == null) {
|
||||
return;
|
||||
return config;
|
||||
}
|
||||
|
||||
if (unique) { // check duplicate
|
||||
|
|
@ -526,39 +622,84 @@ public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
|
|||
});
|
||||
}
|
||||
|
||||
// find by value
|
||||
// TODO Is there a problem with ignoring duplicate but different ReferenceConfig instances?
|
||||
Optional<C> prevConfig = configsMap.values().stream()
|
||||
.filter(val -> isEquals(val, config))
|
||||
.findFirst();
|
||||
if (prevConfig.isPresent()) {
|
||||
if (prevConfig.get() == config) {
|
||||
// the new one is same as existing one
|
||||
return prevConfig.get();
|
||||
}
|
||||
if (unique) {
|
||||
// unique config just need single instance, use prev equivalent instance is ok
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Ignore duplicated config: " + config);
|
||||
}
|
||||
return prevConfig.get();
|
||||
}
|
||||
|
||||
// throw new IllegalStateException("An equivalent config instance already exists, please remove the redundant configuration. " +
|
||||
// "prev: " + prevConfig.get() + ", new: " + config);
|
||||
// logger.warn("An equivalent config instance already exists, ignore the new instance. prev: " + prevConfig.get() +
|
||||
// ", new: " + config);
|
||||
// return;
|
||||
}
|
||||
|
||||
String key = getId(config);
|
||||
if (key == null) {
|
||||
// generate key for non-default config compatible with API usages
|
||||
key = generateConfigId(config);
|
||||
}
|
||||
|
||||
C existedConfig = configsMap.get(key);
|
||||
|
||||
if (existedConfig != null && !config.equals(existedConfig)) {
|
||||
if (configWarnLogEnabled) {
|
||||
//TODO throw exception
|
||||
if (logger.isWarnEnabled()) {
|
||||
String type = config.getClass().getSimpleName();
|
||||
logger.warn(String.format("Duplicate %s found, there already has one default %s or more than two %ss have the same id, " +
|
||||
"you can try to give each %s a different id : %s", type, type, type, type, config));
|
||||
}
|
||||
}
|
||||
if (isEquals(existedConfig, config)) {
|
||||
String type = config.getClass().getSimpleName();
|
||||
throw new IllegalStateException(String.format("Duplicate %s found, there already has one default %s or more than two %ss have the same id, " +
|
||||
"you can try to give each %s a different id, key: %s, prev: %s, new: %s", type, type, type, type, key, existedConfig, config));
|
||||
} else {
|
||||
configsMap.put(key, config);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
public static <C extends AbstractConfig> String generateConfigId(C config) {
|
||||
int idx = configIdIndexes.computeIfAbsent(config.getClass(), clazz -> new AtomicInteger(0)).incrementAndGet();
|
||||
return config.getClass().getSimpleName() + "#" + idx;
|
||||
}
|
||||
|
||||
static <C extends AbstractConfig> String getId(C config) {
|
||||
String id = config.getId();
|
||||
return isNotEmpty(id) ? id : isDefaultConfig(config) ?
|
||||
config.getClass().getSimpleName() + "#" + DEFAULT_KEY : null;
|
||||
return isNotEmpty(id) ? id : null;
|
||||
}
|
||||
|
||||
static <C extends AbstractConfig> boolean isDefaultConfig(C config) {
|
||||
Boolean isDefault = getProperty(config, "isDefault");
|
||||
return isDefault == null || TRUE.equals(isDefault);
|
||||
static <C extends AbstractConfig> Boolean isDefaultConfig(C config) {
|
||||
// If no isDefault() method, it is considered that each can be used as default
|
||||
if (!ReflectUtils.hasMethod(config.getClass(), "isDefault")) {
|
||||
return true;
|
||||
}
|
||||
Boolean isDefault = ReflectUtils.getProperty(config, "isDefault");
|
||||
return isDefault;
|
||||
}
|
||||
|
||||
static <C extends AbstractConfig> List<C> getDefaultConfigs(Map<String, C> configsMap) {
|
||||
return configsMap.values()
|
||||
// find isDefault() == TRUE
|
||||
List<C> list = configsMap.values()
|
||||
.stream()
|
||||
.filter(ConfigManager::isDefaultConfig)
|
||||
.filter(c -> TRUE.equals(ConfigManager.isDefaultConfig(c)))
|
||||
.collect(Collectors.toList());
|
||||
if (list.size() > 0) {
|
||||
return list;
|
||||
}
|
||||
|
||||
// find isDefault() == null
|
||||
list = configsMap.values()
|
||||
.stream()
|
||||
.filter(c -> ConfigManager.isDefaultConfig(c) == null)
|
||||
.collect(Collectors.toList());
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,33 +30,34 @@ import java.lang.annotation.Target;
|
|||
@Target({ElementType.METHOD})
|
||||
public @interface Parameter {
|
||||
|
||||
/**
|
||||
* Specify the parameter key when append parameters to url
|
||||
*/
|
||||
String key() default "";
|
||||
|
||||
/**
|
||||
* If required=true, the value must not be empty when append to url
|
||||
*/
|
||||
boolean required() default false;
|
||||
|
||||
/**
|
||||
* If excluded=true, ignore it when append parameters to url
|
||||
*/
|
||||
boolean excluded() default false;
|
||||
|
||||
/**
|
||||
* if escaped=true, escape it when append parameters to url
|
||||
*/
|
||||
boolean escaped() default false;
|
||||
|
||||
boolean attribute() default false;
|
||||
|
||||
boolean append() default false;
|
||||
/**
|
||||
* If attribute=false, ignore it when processing refresh()/getMetadata()/equals()/toString()
|
||||
*/
|
||||
boolean attribute() default true;
|
||||
|
||||
/**
|
||||
* if {@link #key()} is specified, it will be used as the key for the annotated property when generating url.
|
||||
* by default, this key will also be used to retrieve the config value:
|
||||
* <pre>
|
||||
* {@code
|
||||
* class ExampleConfig {
|
||||
* // Dubbo will try to get "dubbo.example.alias_for_item=xxx" from .properties, if you want to use the original property
|
||||
* // "dubbo.example.item=xxx", you need to set useKeyAsProperty=false.
|
||||
* @Parameter(key = "alias_for_item")
|
||||
* public getItem();
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* </pre>
|
||||
* If append=true, append new value to exist value instead of overriding it.
|
||||
*/
|
||||
boolean useKeyAsProperty() default true;
|
||||
boolean append() default false;
|
||||
|
||||
}
|
||||
|
|
@ -127,7 +127,7 @@ public class ApplicationModel {
|
|||
public static void reset() {
|
||||
getServiceRepository().destroy();
|
||||
getConfigManager().destroy();
|
||||
getEnvironment().destroy();
|
||||
getEnvironment().reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,40 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.config;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class EnvironmentTest {
|
||||
|
||||
@Test
|
||||
public void testResolvePlaceholders1() {
|
||||
Environment environment = ApplicationModel.getEnvironment();
|
||||
|
||||
Map<String, String> externalMap = new LinkedHashMap<>();
|
||||
externalMap.put("zookeeper.address", "127.0.0.1");
|
||||
externalMap.put("zookeeper.port", "2181");
|
||||
environment.updateAppExternalConfigMap(externalMap);
|
||||
|
||||
Map<String, String> sysprops = new LinkedHashMap<>();
|
||||
sysprops.put("zookeeper.address", "192.168.10.1");
|
||||
System.getProperties().putAll(sysprops);
|
||||
|
||||
try {
|
||||
String s = environment.resolvePlaceholders("zookeeper://${zookeeper.address}:${zookeeper.port}");
|
||||
assertEquals("zookeeper://192.168.10.1:2181", s);
|
||||
} finally {
|
||||
for (String key : sysprops.keySet()) {
|
||||
System.clearProperty(key);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.common.config;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PrefixedConfigurationTest {
|
||||
|
||||
@Test
|
||||
public void testPrefixedConfiguration() {
|
||||
Map<String,String> props = new LinkedHashMap<>();
|
||||
props.put("dubbo.protocol.name", "dubbo");
|
||||
props.put("dubbo.protocol.port", "1234");
|
||||
props.put("dubbo.protocols.rest.port", "2345");
|
||||
InmemoryConfiguration inmemoryConfiguration = new InmemoryConfiguration();
|
||||
inmemoryConfiguration.addProperties(props);
|
||||
|
||||
// prefixed over InmemoryConfiguration
|
||||
PrefixedConfiguration prefixedConfiguration = new PrefixedConfiguration(inmemoryConfiguration, "dubbo.protocol");
|
||||
Assertions.assertEquals("dubbo", prefixedConfiguration.getProperty("name"));
|
||||
Assertions.assertEquals("1234", prefixedConfiguration.getProperty("port"));
|
||||
|
||||
prefixedConfiguration = new PrefixedConfiguration(inmemoryConfiguration, "dubbo.protocols.rest");
|
||||
Assertions.assertEquals("2345", prefixedConfiguration.getProperty("port"));
|
||||
|
||||
// prefixed over composite configuration
|
||||
CompositeConfiguration compositeConfiguration = new CompositeConfiguration();
|
||||
compositeConfiguration.addConfiguration(inmemoryConfiguration);
|
||||
prefixedConfiguration = new PrefixedConfiguration(compositeConfiguration, "dubbo.protocols.rest");
|
||||
Assertions.assertEquals("2345", prefixedConfiguration.getProperty("port"));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.utils;
|
||||
|
||||
import org.apache.dubbo.common.config.CompositeConfiguration;
|
||||
import org.apache.dubbo.common.config.InmemoryConfiguration;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.threadpool.ThreadPool;
|
||||
|
||||
|
|
@ -112,9 +114,31 @@ public class ConfigUtilsTest {
|
|||
@Test
|
||||
public void testReplaceProperty() throws Exception {
|
||||
String s = ConfigUtils.replaceProperty("1${a.b.c}2${a.b.c}3", Collections.singletonMap("a.b.c", "ABC"));
|
||||
assertEquals(s, "1ABC2ABC3");
|
||||
assertEquals( "1ABC2ABC3", s);
|
||||
s = ConfigUtils.replaceProperty("1${a.b.c}2${a.b.c}3", Collections.<String, String>emptyMap());
|
||||
assertEquals(s, "123");
|
||||
assertEquals("1${a.b.c}2${a.b.c}3", s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplaceProperty2() {
|
||||
|
||||
InmemoryConfiguration configuration1 = new InmemoryConfiguration();
|
||||
configuration1.getProperties().put("zookeeper.address", "127.0.0.1");
|
||||
|
||||
InmemoryConfiguration configuration2 = new InmemoryConfiguration();
|
||||
configuration2.getProperties().put("zookeeper.port", "2181");
|
||||
|
||||
CompositeConfiguration compositeConfiguration = new CompositeConfiguration();
|
||||
compositeConfiguration.addConfiguration(configuration1);
|
||||
compositeConfiguration.addConfiguration(configuration2);
|
||||
|
||||
String s = ConfigUtils.replaceProperty("zookeeper://${zookeeper.address}:${zookeeper.port}", compositeConfiguration);
|
||||
assertEquals("zookeeper://127.0.0.1:2181", s);
|
||||
|
||||
// should not replace inner class name
|
||||
String interfaceName = "dubbo.service.io.grpc.examples.helloworld.DubboGreeterGrpc$IGreeter";
|
||||
s = ConfigUtils.replaceProperty(interfaceName, compositeConfiguration);
|
||||
Assertions.assertEquals(interfaceName, s);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
|
@ -33,6 +34,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
|
|||
import static org.apache.dubbo.common.utils.CollectionUtils.ofSet;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.splitToList;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.splitToSet;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.startsWithIgnoreCase;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.toCommaDelimitedString;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
|
@ -337,8 +339,44 @@ public class StringUtilsTest {
|
|||
public void testCamelToSplitName() throws Exception {
|
||||
assertEquals("ab-cd-ef", StringUtils.camelToSplitName("abCdEf", "-"));
|
||||
assertEquals("ab-cd-ef", StringUtils.camelToSplitName("AbCdEf", "-"));
|
||||
assertEquals("ab-cd-ef", StringUtils.camelToSplitName("ab-cd-ef", "-"));
|
||||
assertEquals("abcdef", StringUtils.camelToSplitName("abcdef", "-"));
|
||||
//assertEquals("name", StringUtils.camelToSplitName("NAME", "-"));
|
||||
|
||||
assertEquals("ab-cd-ef", StringUtils.camelToSplitName("ab-cd-ef", "-"));
|
||||
assertEquals("ab-cd-ef", StringUtils.camelToSplitName("Ab-Cd-Ef", "-"));
|
||||
assertEquals("Ab_Cd_Ef", StringUtils.camelToSplitName("Ab_Cd_Ef", "-"));
|
||||
assertEquals("AB_CD_EF", StringUtils.camelToSplitName("AB_CD_EF", "-"));
|
||||
|
||||
assertEquals("ab.cd.ef", StringUtils.camelToSplitName("AbCdEf", "."));
|
||||
//assertEquals("ab.cd.ef", StringUtils.camelToSplitName("ab-cd-ef", "."));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSnakeCaseToSplitName() throws Exception {
|
||||
assertEquals("ab-cd-ef", StringUtils.snakeToSplitName("ab_Cd_Ef", "-"));
|
||||
assertEquals("ab-cd-ef", StringUtils.snakeToSplitName("Ab_Cd_Ef", "-"));
|
||||
assertEquals("ab-cd-ef", StringUtils.snakeToSplitName("ab_cd_ef", "-"));
|
||||
assertEquals("ab-cd-ef", StringUtils.snakeToSplitName("AB_CD_EF", "-"));
|
||||
assertEquals("abcdef", StringUtils.snakeToSplitName("abcdef", "-"));
|
||||
assertEquals("qosEnable", StringUtils.snakeToSplitName("qosEnable", "-"));
|
||||
assertEquals("name", StringUtils.snakeToSplitName("NAME", "-"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertToSplitName() {
|
||||
assertEquals("ab-cd-ef", StringUtils.convertToSplitName("ab_Cd_Ef", "-"));
|
||||
assertEquals("ab-cd-ef", StringUtils.convertToSplitName("Ab_Cd_Ef", "-"));
|
||||
assertEquals("ab-cd-ef", StringUtils.convertToSplitName("ab_cd_ef", "-"));
|
||||
assertEquals("ab-cd-ef", StringUtils.convertToSplitName("AB_CD_EF", "-"));
|
||||
assertEquals("abcdef", StringUtils.convertToSplitName("abcdef", "-"));
|
||||
assertEquals("qos-enable", StringUtils.convertToSplitName("qosEnable", "-"));
|
||||
assertEquals("name", StringUtils.convertToSplitName("NAME", "-"));
|
||||
|
||||
assertEquals("ab-cd-ef", StringUtils.convertToSplitName("abCdEf", "-"));
|
||||
assertEquals("ab-cd-ef", StringUtils.convertToSplitName("AbCdEf", "-"));
|
||||
|
||||
assertEquals("ab-cd-ef", StringUtils.convertToSplitName("ab-cd-ef", "-"));
|
||||
assertEquals("ab-cd-ef", StringUtils.convertToSplitName("Ab-Cd-Ef", "-"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -377,20 +415,59 @@ public class StringUtilsTest {
|
|||
assertEquals(2, legalMap.size());
|
||||
assertEquals("value2", legalMap.get("key2"));
|
||||
|
||||
String str = StringUtils.encodeParameters(legalMap);
|
||||
assertEqualsWithoutSpaces(legalStr, str);
|
||||
|
||||
String legalSpaceStr = "[{key1: value1}, {key2 :value2}]";
|
||||
Map<String, String> legalSpaceMap = StringUtils.parseParameters(legalSpaceStr);
|
||||
assertEquals(2, legalSpaceMap.size());
|
||||
assertEquals("value2", legalSpaceMap.get("key2"));
|
||||
|
||||
str = StringUtils.encodeParameters(legalSpaceMap);
|
||||
assertEqualsWithoutSpaces(legalSpaceStr, str);
|
||||
|
||||
String legalSpecialStr = "[{key-1: value*.1}, {key.2 :value*.-_2}]";
|
||||
Map<String, String> legalSpecialMap = StringUtils.parseParameters(legalSpecialStr);
|
||||
assertEquals(2, legalSpecialMap.size());
|
||||
assertEquals("value*.1", legalSpecialMap.get("key-1"));
|
||||
assertEquals("value*.-_2", legalSpecialMap.get("key.2"));
|
||||
|
||||
str = StringUtils.encodeParameters(legalSpecialMap);
|
||||
assertEqualsWithoutSpaces(legalSpecialStr, str);
|
||||
|
||||
String illegalStr = "[{key=value},{aa:bb}]";
|
||||
Map<String, String> illegalMap = StringUtils.parseParameters(illegalStr);
|
||||
assertEquals(0, illegalMap.size());
|
||||
|
||||
str = StringUtils.encodeParameters(illegalMap);
|
||||
assertEquals(null, str);
|
||||
|
||||
String emptyMapStr = "[]";
|
||||
Map<String, String> emptyMap = StringUtils.parseParameters(emptyMapStr);
|
||||
assertEquals(0, emptyMap.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeParameters() {
|
||||
Map<String, String> nullValueMap = new LinkedHashMap<>();
|
||||
nullValueMap.put("client", null);
|
||||
String str = StringUtils.encodeParameters(nullValueMap);
|
||||
assertEquals("[]", str);
|
||||
|
||||
Map<String, String> blankValueMap = new LinkedHashMap<>();
|
||||
blankValueMap.put("client", " ");
|
||||
str = StringUtils.encodeParameters(nullValueMap);
|
||||
assertEquals("[]", str);
|
||||
|
||||
blankValueMap = new LinkedHashMap<>();
|
||||
blankValueMap.put("client", "");
|
||||
str = StringUtils.encodeParameters(nullValueMap);
|
||||
assertEquals("[]", str);
|
||||
|
||||
}
|
||||
|
||||
private void assertEqualsWithoutSpaces(String expect, String actual) {
|
||||
assertEquals(expect.replaceAll(" ", ""), actual.replaceAll(" ", ""));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -418,4 +495,11 @@ public class StringUtilsTest {
|
|||
assertEquals("one,two,three", value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartsWithIgnoreCase() {
|
||||
assertTrue(startsWithIgnoreCase("dubbo.application.name", "dubbo.application."));
|
||||
assertTrue(startsWithIgnoreCase("dubbo.Application.name", "dubbo.application."));
|
||||
assertTrue(startsWithIgnoreCase("Dubbo.application.name", "dubbo.application."));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,19 @@ public class VersionTest {
|
|||
Assertions.assertEquals(Version.HIGHEST_PROTOCOL_VERSION, Version.getIntVersion("2.0.99"));
|
||||
Assertions.assertEquals(2070000, Version.getIntVersion("2.7.0.RC1"));
|
||||
Assertions.assertEquals(2070000, Version.getIntVersion("2.7.0-SNAPSHOT"));
|
||||
Assertions.assertEquals(3000000, Version.getIntVersion("3.0.0-SNAPSHOT"));
|
||||
Assertions.assertEquals(3010000, Version.getIntVersion("3.1.0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompare() {
|
||||
Assertions.assertEquals(0, Version.compare("3.0.0", "3.0.0"));
|
||||
Assertions.assertEquals(0, Version.compare("3.0.0-SNAPSHOT", "3.0.0"));
|
||||
Assertions.assertEquals(1, Version.compare("3.0.0.1", "3.0.0"));
|
||||
Assertions.assertEquals(1, Version.compare("3.1.0", "3.0.0"));
|
||||
Assertions.assertEquals(1, Version.compare("3.1.2.3", "3.0.0"));
|
||||
Assertions.assertEquals(-1, Version.compare("2.9.9.9", "3.0.0"));
|
||||
Assertions.assertEquals(-1, Version.compare("2.6.3.1", "3.0.0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
|
|||
import static org.apache.dubbo.rpc.model.ApplicationModel.getConfigManager;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
|
|
@ -74,12 +75,10 @@ public class ConfigManagerTest {
|
|||
// protocols
|
||||
assertTrue(configManager.getProtocols().isEmpty());
|
||||
assertTrue(configManager.getDefaultProtocols().isEmpty());
|
||||
assertTrue(configManager.getProtocolIds().isEmpty());
|
||||
|
||||
// registries
|
||||
assertTrue(configManager.getRegistries().isEmpty());
|
||||
assertTrue(configManager.getDefaultRegistries().isEmpty());
|
||||
assertTrue(configManager.getRegistryIds().isEmpty());
|
||||
|
||||
// services and references
|
||||
assertTrue(configManager.getServices().isEmpty());
|
||||
|
|
@ -139,7 +138,9 @@ public class ConfigManagerTest {
|
|||
assertEquals(config, configs.iterator().next());
|
||||
assertTrue(configManager.getDefaultProvider().isPresent());
|
||||
|
||||
config = new ProviderConfig();
|
||||
config.setId(DEFAULT_KEY);
|
||||
config.setQueues(10);
|
||||
configManager.addProvider(config);
|
||||
assertTrue(configManager.getDefaultProvider().isPresent());
|
||||
configs = configManager.getProviders();
|
||||
|
|
@ -156,7 +157,9 @@ public class ConfigManagerTest {
|
|||
assertEquals(config, configs.iterator().next());
|
||||
assertTrue(configManager.getDefaultConsumer().isPresent());
|
||||
|
||||
config = new ConsumerConfig();
|
||||
config.setId(DEFAULT_KEY);
|
||||
config.setThreads(10);
|
||||
configManager.addConsumer(config);
|
||||
assertTrue(configManager.getDefaultConsumer().isPresent());
|
||||
configs = configManager.getConsumers();
|
||||
|
|
@ -218,10 +221,10 @@ public class ConfigManagerTest {
|
|||
assertFalse(ConfigManager.isDefaultConfig(providerConfig));
|
||||
|
||||
ProviderConfig providerConfig1 = new ProviderConfig();
|
||||
assertTrue(ConfigManager.isDefaultConfig(providerConfig1));
|
||||
assertNull(ConfigManager.isDefaultConfig(providerConfig1));
|
||||
|
||||
ProviderConfig providerConfig3 = new ProviderConfig();
|
||||
providerConfig.setDefault(true);
|
||||
providerConfig3.setDefault(true);
|
||||
assertTrue(ConfigManager.isDefaultConfig(providerConfig3));
|
||||
|
||||
ProtocolConfig protocolConfig = new ProtocolConfig();
|
||||
|
|
|
|||
|
|
@ -35,14 +35,14 @@ public class ConfigTest {
|
|||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
// In IDE env, make sure adding the following argument to VM options
|
||||
System.setProperty("java.net.preferIPv4Stack", "true");
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -117,14 +117,14 @@ public class MethodConfigTest {
|
|||
assertEquals(methodInfo.getOninvokeMethod(), Person.class.getMethod("setName", String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
//@Test
|
||||
public void testOnreturn() throws Exception {
|
||||
MethodConfig method = new MethodConfig();
|
||||
method.setOnreturn("on-return-object");
|
||||
assertThat(method.getOnreturn(), equalTo((Object) "on-return-object"));
|
||||
Map<String, Object> attribute = new HashMap<String, Object>();
|
||||
MethodConfig.appendAttributes(attribute, method);
|
||||
assertThat(attribute, hasEntry((Object) ON_RETURN_INSTANCE_KEY, (Object) "on-return-object"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
MethodConfig.appendAttributes(attributes, method);
|
||||
assertThat(attributes, hasEntry((Object) ON_RETURN_INSTANCE_KEY, (Object) "on-return-object"));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
MethodConfig.appendParameters(parameters, method);
|
||||
assertThat(parameters.size(), is(0));
|
||||
|
|
@ -135,22 +135,22 @@ public class MethodConfigTest {
|
|||
MethodConfig method = new MethodConfig();
|
||||
method.setOnreturnMethod("on-return-method");
|
||||
assertThat(method.getOnreturnMethod(), equalTo("on-return-method"));
|
||||
Map<String, Object> attribute = new HashMap<String, Object>();
|
||||
MethodConfig.appendAttributes(attribute, method);
|
||||
assertThat(attribute, hasEntry((Object) ON_RETURN_METHOD_KEY, (Object) "on-return-method"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
MethodConfig.appendAttributes(attributes, method);
|
||||
assertThat(attributes, hasEntry((Object) ON_RETURN_METHOD_KEY, (Object) "on-return-method"));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
MethodConfig.appendParameters(parameters, method);
|
||||
assertThat(parameters.size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
//@Test
|
||||
public void testOnthrow() throws Exception {
|
||||
MethodConfig method = new MethodConfig();
|
||||
method.setOnthrow("on-throw-object");
|
||||
assertThat(method.getOnthrow(), equalTo((Object) "on-throw-object"));
|
||||
Map<String, Object> attribute = new HashMap<String, Object>();
|
||||
MethodConfig.appendAttributes(attribute, method);
|
||||
assertThat(attribute, hasEntry((Object) ON_THROW_INSTANCE_KEY, (Object) "on-throw-object"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
MethodConfig.appendAttributes(attributes, method);
|
||||
assertThat(attributes, hasEntry((Object) ON_THROW_INSTANCE_KEY, (Object) "on-throw-object"));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
MethodConfig.appendParameters(parameters, method);
|
||||
assertThat(parameters.size(), is(0));
|
||||
|
|
@ -161,22 +161,22 @@ public class MethodConfigTest {
|
|||
MethodConfig method = new MethodConfig();
|
||||
method.setOnthrowMethod("on-throw-method");
|
||||
assertThat(method.getOnthrowMethod(), equalTo("on-throw-method"));
|
||||
Map<String, Object> attribute = new HashMap<String, Object>();
|
||||
MethodConfig.appendAttributes(attribute, method);
|
||||
assertThat(attribute, hasEntry((Object) ON_THROW_METHOD_KEY, (Object) "on-throw-method"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
MethodConfig.appendAttributes(attributes, method);
|
||||
assertThat(attributes, hasEntry((Object) ON_THROW_METHOD_KEY, (Object) "on-throw-method"));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
MethodConfig.appendParameters(parameters, method);
|
||||
assertThat(parameters.size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
//@Test
|
||||
public void testOninvoke() throws Exception {
|
||||
MethodConfig method = new MethodConfig();
|
||||
method.setOninvoke("on-invoke-object");
|
||||
assertThat(method.getOninvoke(), equalTo((Object) "on-invoke-object"));
|
||||
Map<String, Object> attribute = new HashMap<String, Object>();
|
||||
MethodConfig.appendAttributes(attribute, method);
|
||||
assertThat(attribute, hasEntry((Object) ON_INVOKE_INSTANCE_KEY, (Object) "on-invoke-object"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
MethodConfig.appendAttributes(attributes, method);
|
||||
assertThat(attributes, hasEntry((Object) ON_INVOKE_INSTANCE_KEY, (Object) "on-invoke-object"));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
MethodConfig.appendParameters(parameters, method);
|
||||
assertThat(parameters.size(), is(0));
|
||||
|
|
@ -187,9 +187,9 @@ public class MethodConfigTest {
|
|||
MethodConfig method = new MethodConfig();
|
||||
method.setOninvokeMethod("on-invoke-method");
|
||||
assertThat(method.getOninvokeMethod(), equalTo("on-invoke-method"));
|
||||
Map<String, Object> attribute = new HashMap<String, Object>();
|
||||
MethodConfig.appendAttributes(attribute, method);
|
||||
assertThat(attribute, hasEntry((Object) ON_INVOKE_METHOD_KEY, (Object) "on-invoke-method"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
MethodConfig.appendAttributes(attributes, method);
|
||||
assertThat(attributes, hasEntry((Object) ON_INVOKE_METHOD_KEY, (Object) "on-invoke-method"));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
MethodConfig.appendParameters(parameters, method);
|
||||
assertThat(parameters.size(), is(0));
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public class ModuleConfigTest {
|
|||
ModuleConfig module = new ModuleConfig();
|
||||
module.setName("module-name");
|
||||
assertThat(module.getName(), equalTo("module-name"));
|
||||
assertThat(module.getId(), equalTo("module-name"));
|
||||
assertThat(module.getId(), equalTo(null));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
ModuleConfig.appendParameters(parameters, module);
|
||||
assertThat(parameters, hasEntry("module", "module-name"));
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public class ProtocolConfigTest {
|
|||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
ProtocolConfig.appendParameters(parameters, protocol);
|
||||
assertThat(protocol.getName(), equalTo("name"));
|
||||
assertThat(protocol.getId(), equalTo("name"));
|
||||
assertThat(protocol.getId(), equalTo(null));
|
||||
assertThat(parameters.isEmpty(), is(true));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.service.DemoService;
|
||||
import org.apache.dubbo.service.DemoServiceImpl;
|
||||
|
||||
|
|
@ -38,12 +37,12 @@ public class ReferenceConfigTest {
|
|||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.apache.dubbo.generic;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
|
||||
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
|
||||
import org.apache.dubbo.metadata.definition.model.MethodDefinition;
|
||||
|
|
@ -36,6 +37,7 @@ import org.apache.dubbo.service.DemoServiceImpl;
|
|||
import com.alibaba.dubbo.config.ReferenceConfig;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -46,6 +48,11 @@ import java.util.Map;
|
|||
|
||||
public class GenericServiceTest {
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() {
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGeneric() {
|
||||
DemoService server = new DemoServiceImpl();
|
||||
|
|
@ -91,6 +98,10 @@ public class GenericServiceTest {
|
|||
|
||||
@Test
|
||||
public void testGenericCompatible() {
|
||||
DubboBootstrap.getInstance()
|
||||
.application("test-app")
|
||||
.initialize();
|
||||
|
||||
DemoService server = new DemoServiceImpl();
|
||||
ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
|
||||
Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
|
||||
|
|
@ -101,7 +112,7 @@ public class GenericServiceTest {
|
|||
ReferenceConfig<com.alibaba.dubbo.rpc.service.GenericService> oldReferenceConfig = new ReferenceConfig<>();
|
||||
oldReferenceConfig.setGeneric(true);
|
||||
oldReferenceConfig.setInterface(DemoService.class.getName());
|
||||
oldReferenceConfig.checkAndUpdateSubConfigs();
|
||||
oldReferenceConfig.refresh();
|
||||
Invoker invoker = protocol.refer(oldReferenceConfig.getInterfaceClass(), url);
|
||||
com.alibaba.dubbo.rpc.service.GenericService client = (com.alibaba.dubbo.rpc.service.GenericService) proxyFactory.getProxy(invoker, true);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
|
@ -25,8 +24,6 @@ import org.apache.dubbo.config.event.DubboShutdownHookRegisteredEvent;
|
|||
import org.apache.dubbo.config.event.DubboShutdownHookUnregisteredEvent;
|
||||
import org.apache.dubbo.event.Event;
|
||||
import org.apache.dubbo.event.EventDispatcher;
|
||||
import org.apache.dubbo.registry.support.AbstractRegistryFactory;
|
||||
import org.apache.dubbo.rpc.Protocol;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
|
|
@ -66,12 +63,14 @@ public class DubboShutdownHook extends Thread {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Run shutdown hook now.");
|
||||
}
|
||||
if (destroyed.compareAndSet(false, true)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Run shutdown hook now.");
|
||||
}
|
||||
|
||||
callback();
|
||||
doDestroy();
|
||||
callback();
|
||||
doDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -123,27 +122,4 @@ public class DubboShutdownHook extends Thread {
|
|||
return registered.get();
|
||||
}
|
||||
|
||||
public static void destroyAll() {
|
||||
if (destroyed.compareAndSet(false, true)) {
|
||||
AbstractRegistryFactory.destroyAll();
|
||||
destroyProtocols();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy all the protocols.
|
||||
*/
|
||||
public static void destroyProtocols() {
|
||||
ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class);
|
||||
for (String protocolName : loader.getLoadedExtensions()) {
|
||||
try {
|
||||
Protocol protocol = loader.getLoadedExtension(protocolName);
|
||||
if (protocol != null) {
|
||||
protocol.destroy();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger.warn(t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,21 +230,44 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
dispatch(new ReferenceConfigDestroyedEvent(this));
|
||||
}
|
||||
|
||||
public synchronized void init() {
|
||||
protected synchronized void init() {
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Using DubboBootstrap API will associate bootstrap when registering reference.
|
||||
// Loading by Spring context will associate bootstrap in afterPropertiesSet() method.
|
||||
// Initializing bootstrap here only for compatible with old API usages.
|
||||
if (bootstrap == null) {
|
||||
bootstrap = DubboBootstrap.getInstance();
|
||||
bootstrap.initialize();
|
||||
bootstrap.reference(this);
|
||||
}
|
||||
|
||||
checkAndUpdateSubConfigs();
|
||||
// check bootstrap state
|
||||
if (!bootstrap.isInitialized()) {
|
||||
throw new IllegalStateException("DubboBootstrap is not initialized");
|
||||
}
|
||||
|
||||
if (!this.isRefreshed()) {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
//init serivceMetadata
|
||||
initServiceMetadata(consumer);
|
||||
serviceMetadata.setServiceType(getActualInterface());
|
||||
// TODO, uncomment this line once service key is unified
|
||||
serviceMetadata.setServiceKey(URL.buildKey(interfaceName, group, version));
|
||||
|
||||
ServiceRepository repository = ApplicationModel.getServiceRepository();
|
||||
ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass);
|
||||
repository.registerConsumer(
|
||||
serviceMetadata.getServiceKey(),
|
||||
serviceDescriptor,
|
||||
this,
|
||||
null,
|
||||
serviceMetadata);
|
||||
|
||||
checkStubAndLocal(interfaceClass);
|
||||
ConfigValidationUtils.checkMock(interfaceClass, this);
|
||||
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put(SIDE_KEY, CONSUMER_SIDE);
|
||||
|
|
@ -453,20 +476,19 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
* This method should be called right after the creation of this class's instance, before any property in other config modules is used.
|
||||
* Check each config modules are created properly and override their properties if necessary.
|
||||
*/
|
||||
public void checkAndUpdateSubConfigs() {
|
||||
protected void checkAndUpdateSubConfigs() {
|
||||
if (StringUtils.isEmpty(interfaceName)) {
|
||||
throw new IllegalStateException("<dubbo:reference interface=\"\" /> interface not allow null!");
|
||||
}
|
||||
completeCompoundConfigs(consumer);
|
||||
|
||||
// get consumer's global configuration
|
||||
checkDefault();
|
||||
completeCompoundConfigs();
|
||||
|
||||
// init some null configuration.
|
||||
List<ConfigInitializer> configInitializers = ExtensionLoader.getExtensionLoader(ConfigInitializer.class)
|
||||
.getActivateExtension(URL.valueOf("configInitializer://"), (String[]) null);
|
||||
configInitializers.forEach(e -> e.initReferConfig(this));
|
||||
|
||||
this.refresh();
|
||||
if (getGeneric() == null && getConsumer() != null) {
|
||||
setGeneric(getConsumer().getGeneric());
|
||||
}
|
||||
|
|
@ -479,28 +501,31 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException(e.getMessage(), e);
|
||||
}
|
||||
checkInterfaceAndMethods(interfaceClass, getMethods());
|
||||
//checkInterfaceAndMethods(interfaceClass, getMethods());
|
||||
}
|
||||
|
||||
initServiceMetadata(consumer);
|
||||
serviceMetadata.setServiceType(getActualInterface());
|
||||
// TODO, uncomment this line once service key is unified
|
||||
serviceMetadata.setServiceKey(URL.buildKey(interfaceName, group, version));
|
||||
|
||||
ServiceRepository repository = ApplicationModel.getServiceRepository();
|
||||
ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass);
|
||||
repository.registerConsumer(
|
||||
serviceMetadata.getServiceKey(),
|
||||
serviceDescriptor,
|
||||
this,
|
||||
null,
|
||||
serviceMetadata);
|
||||
checkStubAndLocal(interfaceClass);
|
||||
ConfigValidationUtils.checkMock(interfaceClass, this);
|
||||
|
||||
resolveFile();
|
||||
ConfigValidationUtils.validateReferenceConfig(this);
|
||||
postProcessConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postProcessRefresh() {
|
||||
super.postProcessRefresh();
|
||||
checkAndUpdateSubConfigs();
|
||||
}
|
||||
|
||||
protected void completeCompoundConfigs() {
|
||||
super.completeCompoundConfigs(consumer);
|
||||
if (consumer != null) {
|
||||
if (StringUtils.isEmpty(registryIds)) {
|
||||
setRegistryIds(consumer.getRegistryIds());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Figure out should refer the service in the same JVM from configurations. The default behavior is true
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ import static org.apache.dubbo.rpc.cluster.Constants.EXPORT_KEY;
|
|||
|
||||
public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
||||
|
||||
public static final Logger logger = LoggerFactory.getLogger(ServiceConfig.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(ServiceConfig.class);
|
||||
|
||||
/**
|
||||
* A random port cache, the different protocols who has no port specified have different random port
|
||||
|
|
@ -151,12 +151,12 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
super(service);
|
||||
}
|
||||
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public boolean isExported() {
|
||||
return exported;
|
||||
}
|
||||
|
||||
@Parameter(excluded = true)
|
||||
@Parameter(excluded = true, attribute = false)
|
||||
public boolean isUnexported() {
|
||||
return unexported;
|
||||
}
|
||||
|
|
@ -189,13 +189,23 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
return;
|
||||
}
|
||||
|
||||
// Using DubboBootstrap API will associate bootstrap when registering service.
|
||||
// Loading by Spring context will associate bootstrap in afterPropertiesSet() method.
|
||||
// Initializing bootstrap here only for compatible with old API usages.
|
||||
if (bootstrap == null) {
|
||||
bootstrap = DubboBootstrap.getInstance();
|
||||
bootstrap.initialize();
|
||||
bootstrap.service(this);
|
||||
}
|
||||
|
||||
checkAndUpdateSubConfigs();
|
||||
// check bootstrap state
|
||||
if (!bootstrap.isInitialized()) {
|
||||
throw new IllegalStateException("DubboBootstrap is not initialized");
|
||||
}
|
||||
|
||||
if (!this.isRefreshed()) {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
initServiceMetadata(provider);
|
||||
serviceMetadata.setServiceType(getInterfaceClass());
|
||||
|
|
@ -225,10 +235,12 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
}
|
||||
|
||||
private void checkAndUpdateSubConfigs() {
|
||||
|
||||
// Use default configs defined explicitly with global scope
|
||||
completeCompoundConfigs();
|
||||
checkDefault();
|
||||
|
||||
checkProtocol();
|
||||
|
||||
// init some null configuration.
|
||||
List<ConfigInitializer> configInitializers = ExtensionLoader.getExtensionLoader(ConfigInitializer.class)
|
||||
.getActivateExtension(URL.valueOf("configInitializer://"), (String[]) null);
|
||||
|
|
@ -238,7 +250,6 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
if (!isOnlyInJvm()) {
|
||||
checkRegistry();
|
||||
}
|
||||
this.refresh();
|
||||
|
||||
if (StringUtils.isEmpty(interfaceName)) {
|
||||
throw new IllegalStateException("<dubbo:service interface=\"\" /> interface not allow null!");
|
||||
|
|
@ -256,7 +267,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException(e.getMessage(), e);
|
||||
}
|
||||
checkInterfaceAndMethods(interfaceClass, getMethods());
|
||||
//checkInterfaceAndMethods(interfaceClass, getMethods());
|
||||
checkRef();
|
||||
generic = Boolean.FALSE.toString();
|
||||
}
|
||||
|
|
@ -294,6 +305,11 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
postProcessConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postProcessRefresh() {
|
||||
super.postProcessRefresh();
|
||||
checkAndUpdateSubConfigs();
|
||||
}
|
||||
|
||||
protected synchronized void doExport() {
|
||||
if (unexported) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.apache.dubbo.common.config.Environment;
|
|||
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
|
||||
import org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory;
|
||||
import org.apache.dubbo.common.config.configcenter.wrapper.CompositeDynamicConfiguration;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
|
|
@ -30,7 +31,9 @@ import org.apache.dubbo.common.threadpool.concurrent.ScheduledCompletableFuture;
|
|||
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
|
||||
import org.apache.dubbo.common.utils.ArrayUtils;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ConfigCenterConfig;
|
||||
import org.apache.dubbo.config.ConsumerConfig;
|
||||
|
|
@ -42,6 +45,7 @@ import org.apache.dubbo.config.MonitorConfig;
|
|||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.ProviderConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfigBase;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.config.ServiceConfigBase;
|
||||
|
|
@ -70,13 +74,17 @@ import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
|
|||
import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
|
||||
import org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl;
|
||||
import org.apache.dubbo.registry.support.AbstractRegistryFactory;
|
||||
import org.apache.dubbo.rpc.Protocol;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
|
@ -95,6 +103,7 @@ import static java.util.concurrent.Executors.newSingleThreadExecutor;
|
|||
import static org.apache.dubbo.common.config.ConfigurationUtils.parseProperties;
|
||||
import static org.apache.dubbo.common.config.configcenter.DynamicConfiguration.getDynamicConfiguration;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_SPLIT_PATTERN;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
|
||||
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
|
||||
|
|
@ -183,6 +192,8 @@ public class DubboBootstrap {
|
|||
|
||||
private List<CompletableFuture<Object>> asyncReferringFutures = new ArrayList<>();
|
||||
|
||||
private static boolean ignoreConfigState;
|
||||
|
||||
/**
|
||||
* See {@link ApplicationModel} and {@link ExtensionLoader} for why DubboBootstrap is designed to be singleton.
|
||||
*/
|
||||
|
|
@ -199,19 +210,38 @@ public class DubboBootstrap {
|
|||
|
||||
/**
|
||||
* Try reset dubbo status for new instance.
|
||||
* For testing purposes only
|
||||
*
|
||||
* @deprecated For testing purposes only
|
||||
*/
|
||||
@Deprecated
|
||||
public static void reset() {
|
||||
if (instance != null) {
|
||||
instance.destroy();
|
||||
reset(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try reset dubbo status for new instance.
|
||||
*
|
||||
* @deprecated For testing purposes only
|
||||
*/
|
||||
@Deprecated
|
||||
public static void reset(boolean destroy) {
|
||||
ConfigUtils.setProperties(null);
|
||||
DubboBootstrap.ignoreConfigState = true;
|
||||
if (destroy) {
|
||||
if (instance != null) {
|
||||
instance.destroy();
|
||||
instance = null;
|
||||
}
|
||||
MetadataReportInstance.reset();
|
||||
AbstractRegistryFactory.reset();
|
||||
ExtensionLoader.destroyAll();
|
||||
//ExtensionLoader.resetExtensionLoader(GovernanceRuleRepository.class);
|
||||
} else {
|
||||
instance = null;
|
||||
}
|
||||
|
||||
ApplicationModel.reset();
|
||||
MetadataReportInstance.destroy();
|
||||
AbstractMetadataReportFactory.clear();
|
||||
ExtensionLoader.resetExtensionLoader(DynamicConfigurationFactory.class);
|
||||
ExtensionLoader.resetExtensionLoader(MetadataReportFactory.class);
|
||||
ExtensionLoader.destroyAll();
|
||||
ShutdownHookCallbacks.INSTANCE.clear();
|
||||
}
|
||||
|
||||
private DubboBootstrap() {
|
||||
|
|
@ -222,6 +252,10 @@ public class DubboBootstrap {
|
|||
ShutdownHookCallbacks.INSTANCE.addCallback(DubboBootstrap.this::destroy);
|
||||
}
|
||||
|
||||
public ConfigManager getConfigManager() {
|
||||
return configManager;
|
||||
}
|
||||
|
||||
public void unRegisterShutdownHook() {
|
||||
DubboShutdownHook.getDubboShutdownHook().unregister();
|
||||
}
|
||||
|
|
@ -378,6 +412,7 @@ public class DubboBootstrap {
|
|||
}
|
||||
|
||||
public DubboBootstrap service(ServiceConfig<?> serviceConfig) {
|
||||
serviceConfig.setBootstrap(this);
|
||||
configManager.addService(serviceConfig);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -402,6 +437,7 @@ public class DubboBootstrap {
|
|||
}
|
||||
|
||||
public DubboBootstrap reference(ReferenceConfig<?> referenceConfig) {
|
||||
referenceConfig.setBootstrap(this);
|
||||
configManager.addReference(referenceConfig);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -527,11 +563,10 @@ public class DubboBootstrap {
|
|||
}
|
||||
|
||||
ApplicationModel.initFrameworkExts();
|
||||
|
||||
|
||||
startConfigCenter();
|
||||
|
||||
loadRemoteConfigs();
|
||||
loadConfigsFromProps();
|
||||
|
||||
checkGlobalConfigs();
|
||||
|
||||
|
|
@ -546,73 +581,119 @@ public class DubboBootstrap {
|
|||
}
|
||||
|
||||
private void checkGlobalConfigs() {
|
||||
// check Application
|
||||
ConfigValidationUtils.validateApplicationConfig(getApplication());
|
||||
// check config types (ignore metadata-center)
|
||||
List<Class<? extends AbstractConfig>> multipleConfigTypes = Arrays.asList(
|
||||
ApplicationConfig.class,
|
||||
ProtocolConfig.class,
|
||||
RegistryConfig.class,
|
||||
MetadataReportConfig.class,
|
||||
ProviderConfig.class,
|
||||
ConsumerConfig.class,
|
||||
MonitorConfig.class,
|
||||
ModuleConfig.class,
|
||||
MetricsConfig.class,
|
||||
SslConfig.class);
|
||||
|
||||
// check Metadata
|
||||
Collection<MetadataReportConfig> metadatas = configManager.getMetadataConfigs();
|
||||
if (CollectionUtils.isEmpty(metadatas)) {
|
||||
MetadataReportConfig metadataReportConfig = new MetadataReportConfig();
|
||||
metadataReportConfig.refresh();
|
||||
if (metadataReportConfig.isValid()) {
|
||||
configManager.addMetadataReport(metadataReportConfig);
|
||||
metadatas = configManager.getMetadataConfigs();
|
||||
for (Class<? extends AbstractConfig> configType : multipleConfigTypes) {
|
||||
checkDefaultAndValidateConfigs(configType);
|
||||
}
|
||||
|
||||
// check port conflicts
|
||||
Map<Integer, ProtocolConfig> protocolPortMap = new LinkedHashMap<>();
|
||||
for (ProtocolConfig protocol : configManager.getProtocols()) {
|
||||
Integer port = protocol.getPort();
|
||||
if (port == null || port == -1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(metadatas)) {
|
||||
for (MetadataReportConfig metadataReportConfig : metadatas) {
|
||||
metadataReportConfig.refresh();
|
||||
ConfigValidationUtils.validateMetadataConfig(metadataReportConfig);
|
||||
ProtocolConfig prevProtocol = protocolPortMap.get(port);
|
||||
if (prevProtocol != null) {
|
||||
throw new IllegalStateException("Duplicated port used by protocol configs, port: " + port +
|
||||
", configs: " + Arrays.asList(prevProtocol, protocol));
|
||||
}
|
||||
protocolPortMap.put(port, protocol);
|
||||
}
|
||||
|
||||
// check Provider
|
||||
Collection<ProviderConfig> providers = configManager.getProviders();
|
||||
if (CollectionUtils.isEmpty(providers)) {
|
||||
configManager.getDefaultProvider().orElseGet(() -> {
|
||||
ProviderConfig providerConfig = new ProviderConfig();
|
||||
configManager.addProvider(providerConfig);
|
||||
providerConfig.refresh();
|
||||
return providerConfig;
|
||||
});
|
||||
// check reference and service
|
||||
for (ReferenceConfigBase<?> reference : configManager.getReferences()) {
|
||||
reference.refresh();
|
||||
}
|
||||
for (ProviderConfig providerConfig : configManager.getProviders()) {
|
||||
ConfigValidationUtils.validateProviderConfig(providerConfig);
|
||||
for (ServiceConfigBase service : configManager.getServices()) {
|
||||
service.refresh();
|
||||
}
|
||||
// check Consumer
|
||||
Collection<ConsumerConfig> consumers = configManager.getConsumers();
|
||||
if (CollectionUtils.isEmpty(consumers)) {
|
||||
configManager.getDefaultConsumer().orElseGet(() -> {
|
||||
ConsumerConfig consumerConfig = new ConsumerConfig();
|
||||
configManager.addConsumer(consumerConfig);
|
||||
consumerConfig.refresh();
|
||||
return consumerConfig;
|
||||
});
|
||||
}
|
||||
for (ConsumerConfig consumerConfig : configManager.getConsumers()) {
|
||||
ConfigValidationUtils.validateConsumerConfig(consumerConfig);
|
||||
}
|
||||
|
||||
private <T extends AbstractConfig> void checkDefaultAndValidateConfigs(Class<T> configType) {
|
||||
boolean needValid = (configType == MetadataReportConfig.class);
|
||||
try {
|
||||
if (shouldAddDefaultConfig(configType)) {
|
||||
T config = configType.newInstance();
|
||||
config.refresh();
|
||||
if (!needValid || config.isValid()) {
|
||||
configManager.addConfig(config);
|
||||
} else {
|
||||
logger.info("Ignore invalid config: " + config);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Add default config failed: " + configType.getSimpleName(), e);
|
||||
}
|
||||
|
||||
// check Monitor
|
||||
ConfigValidationUtils.validateMonitorConfig(getMonitor());
|
||||
// check Metrics
|
||||
ConfigValidationUtils.validateMetricsConfig(getMetrics());
|
||||
// check Module
|
||||
ConfigValidationUtils.validateModuleConfig(getModule());
|
||||
// check Ssl
|
||||
ConfigValidationUtils.validateSslConfig(getSsl());
|
||||
//validate configs
|
||||
Collection<T> configs = configManager.getConfigs(configType);
|
||||
for (T config : configs) {
|
||||
validateConfig(config);
|
||||
}
|
||||
|
||||
// check required default
|
||||
if (configType != MetadataReportConfig.class && configs.isEmpty()) {
|
||||
throw new IllegalStateException("Default config not found for " + configType.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends AbstractConfig> void validateConfig(T config) {
|
||||
if (config instanceof ProtocolConfig) {
|
||||
ConfigValidationUtils.validateProtocolConfig((ProtocolConfig) config);
|
||||
} else if (config instanceof RegistryConfig) {
|
||||
ConfigValidationUtils.validateRegistryConfig((RegistryConfig) config);
|
||||
} else if (config instanceof MetadataReportConfig) {
|
||||
ConfigValidationUtils.validateMetadataConfig((MetadataReportConfig) config);
|
||||
} else if (config instanceof ProviderConfig) {
|
||||
ConfigValidationUtils.validateProviderConfig((ProviderConfig) config);
|
||||
} else if (config instanceof ConsumerConfig) {
|
||||
ConfigValidationUtils.validateConsumerConfig((ConsumerConfig) config);
|
||||
} else if (config instanceof ApplicationConfig) {
|
||||
ConfigValidationUtils.validateApplicationConfig((ApplicationConfig) config);
|
||||
} else if (config instanceof MonitorConfig) {
|
||||
ConfigValidationUtils.validateMonitorConfig((MonitorConfig) config);
|
||||
} else if (config instanceof ModuleConfig) {
|
||||
ConfigValidationUtils.validateModuleConfig((ModuleConfig) config);
|
||||
} else if (config instanceof MetricsConfig) {
|
||||
ConfigValidationUtils.validateMetricsConfig((MetricsConfig) config);
|
||||
} else if (config instanceof SslConfig) {
|
||||
ConfigValidationUtils.validateSslConfig((SslConfig) config);
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends AbstractConfig> boolean shouldAddDefaultConfig(Class<T> clazz) {
|
||||
return configManager.getDefaultConfigs(clazz).isEmpty();
|
||||
}
|
||||
|
||||
private void startConfigCenter() {
|
||||
|
||||
// load application config
|
||||
loadConfigs(ApplicationConfig.class);
|
||||
|
||||
// load config centers
|
||||
loadConfigs(ConfigCenterConfig.class);
|
||||
|
||||
useRegistryAsConfigCenterIfNecessary();
|
||||
|
||||
Collection<ConfigCenterConfig> configCenters = configManager.getConfigCenters();
|
||||
|
||||
// check Config Center
|
||||
Collection<ConfigCenterConfig> configCenters = configManager.getConfigCenters();
|
||||
if (CollectionUtils.isEmpty(configCenters)) {
|
||||
ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
|
||||
configCenterConfig.refresh();
|
||||
ConfigValidationUtils.validateConfigCenterConfig(configCenterConfig);
|
||||
if (configCenterConfig.isValid()) {
|
||||
configManager.addConfigCenter(configCenterConfig);
|
||||
configCenters = configManager.getConfigCenters();
|
||||
|
|
@ -627,10 +708,16 @@ public class DubboBootstrap {
|
|||
if (CollectionUtils.isNotEmpty(configCenters)) {
|
||||
CompositeDynamicConfiguration compositeDynamicConfiguration = new CompositeDynamicConfiguration();
|
||||
for (ConfigCenterConfig configCenter : configCenters) {
|
||||
// Pass config from ConfigCenterBean to environment
|
||||
environment.updateExternalConfigMap(configCenter.getExternalConfiguration());
|
||||
environment.updateAppExternalConfigMap(configCenter.getAppExternalConfiguration());
|
||||
|
||||
// Fetch config from remote config center
|
||||
compositeDynamicConfiguration.addConfiguration(prepareEnvironment(configCenter));
|
||||
}
|
||||
environment.setDynamicConfiguration(compositeDynamicConfiguration);
|
||||
}
|
||||
|
||||
configManager.refreshAll();
|
||||
}
|
||||
|
||||
|
|
@ -674,12 +761,19 @@ public class DubboBootstrap {
|
|||
return;
|
||||
}
|
||||
|
||||
configManager
|
||||
.getDefaultRegistries()
|
||||
.stream()
|
||||
.filter(this::isUsedRegistryAsConfigCenter)
|
||||
.map(this::registryAsConfigCenter)
|
||||
.forEach(configManager::addConfigCenter);
|
||||
// load registry
|
||||
loadConfigs(RegistryConfig.class);
|
||||
|
||||
List<RegistryConfig> defaultRegistries = configManager.getDefaultRegistries();
|
||||
if (defaultRegistries.size() > 0) {
|
||||
defaultRegistries
|
||||
.stream()
|
||||
.filter(this::isUsedRegistryAsConfigCenter)
|
||||
.map(this::registryAsConfigCenter)
|
||||
.forEach(configManager::addConfigCenter);
|
||||
|
||||
logger.info("use registry as config-center: " + configManager.getConfigCenters());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isUsedRegistryAsConfigCenter(RegistryConfig registryConfig) {
|
||||
|
|
@ -724,13 +818,16 @@ public class DubboBootstrap {
|
|||
return;
|
||||
}
|
||||
|
||||
configManager
|
||||
.getDefaultRegistries()
|
||||
.stream()
|
||||
.filter(this::isUsedRegistryAsMetadataCenter)
|
||||
.map(this::registryAsMetadataCenter)
|
||||
.forEach(configManager::addMetadataReport);
|
||||
List<RegistryConfig> defaultRegistries = configManager.getDefaultRegistries();
|
||||
if (defaultRegistries.size() > 0) {
|
||||
defaultRegistries
|
||||
.stream()
|
||||
.filter(this::isUsedRegistryAsMetadataCenter)
|
||||
.map(this::registryAsMetadataCenter)
|
||||
.forEach(configManager::addMetadataReport);
|
||||
|
||||
logger.info("use registry as metadata-center: " + configManager.getMetadataConfigs());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isUsedRegistryAsMetadataCenter(RegistryConfig registryConfig) {
|
||||
|
|
@ -831,40 +928,120 @@ public class DubboBootstrap {
|
|||
return metadataAddressBuilder.toString();
|
||||
}
|
||||
|
||||
private void loadRemoteConfigs() {
|
||||
// registry ids to registry configs
|
||||
List<RegistryConfig> tmpRegistries = new ArrayList<>();
|
||||
Set<String> registryIds = configManager.getRegistryIds();
|
||||
registryIds.forEach(id -> {
|
||||
if (tmpRegistries.stream().noneMatch(reg -> reg.getId().equals(id))) {
|
||||
tmpRegistries.add(configManager.getRegistry(id).orElseGet(() -> {
|
||||
RegistryConfig registryConfig = new RegistryConfig();
|
||||
registryConfig.setId(id);
|
||||
registryConfig.refresh();
|
||||
return registryConfig;
|
||||
}));
|
||||
}
|
||||
});
|
||||
private void loadConfigsFromProps() {
|
||||
|
||||
configManager.addRegistries(tmpRegistries);
|
||||
// application config has load before starting config center
|
||||
// load dubbo.applications.xxx
|
||||
loadConfigs(ApplicationConfig.class);
|
||||
|
||||
// protocol ids to protocol configs
|
||||
List<ProtocolConfig> tmpProtocols = new ArrayList<>();
|
||||
Set<String> protocolIds = configManager.getProtocolIds();
|
||||
protocolIds.forEach(id -> {
|
||||
if (tmpProtocols.stream().noneMatch(prot -> prot.getId().equals(id))) {
|
||||
tmpProtocols.add(configManager.getProtocol(id).orElseGet(() -> {
|
||||
ProtocolConfig protocolConfig = new ProtocolConfig();
|
||||
protocolConfig.setId(id);
|
||||
protocolConfig.refresh();
|
||||
return protocolConfig;
|
||||
}));
|
||||
}
|
||||
});
|
||||
// load dubbo.modules.xxx
|
||||
loadConfigs(ModuleConfig.class);
|
||||
|
||||
// load dubbo.monitors.xxx
|
||||
loadConfigs(MonitorConfig.class);
|
||||
|
||||
// load dubbo.metricses.xxx
|
||||
loadConfigs(MetricsConfig.class);
|
||||
|
||||
// load multiple config types:
|
||||
// load dubbo.protocols.xxx
|
||||
loadConfigs(ProtocolConfig.class);
|
||||
|
||||
// load dubbo.registries.xxx
|
||||
loadConfigs(RegistryConfig.class);
|
||||
|
||||
// load dubbo.providers.xxx
|
||||
loadConfigs(ProviderConfig.class);
|
||||
|
||||
// load dubbo.consumers.xxx
|
||||
loadConfigs(ConsumerConfig.class);
|
||||
|
||||
// load dubbo.metadata-report.xxx
|
||||
loadConfigs(MetadataReportConfig.class);
|
||||
|
||||
// config centers has bean loaded before starting config center
|
||||
//loadConfigs(ConfigCenterConfig.class);
|
||||
|
||||
configManager.addProtocols(tmpProtocols);
|
||||
}
|
||||
|
||||
private <T extends AbstractConfig> void loadConfigs(Class<T> cls) {
|
||||
// load multiple configs with id
|
||||
Set<String> configIds = this.getConfigIds(cls);
|
||||
configIds.forEach(id -> {
|
||||
if (!configManager.getConfig(cls, id).isPresent()) {
|
||||
T config = null;
|
||||
try {
|
||||
config = cls.newInstance();
|
||||
config.setId(id);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("create config instance failed, id: " + id + ", type:" + cls.getSimpleName());
|
||||
}
|
||||
|
||||
String key = null;
|
||||
boolean addDefaultNameConfig = false;
|
||||
try {
|
||||
// add default name config (same as id), e.g. dubbo.protocols.rest.port=1234
|
||||
key = DUBBO + "." + AbstractConfig.getPluralTagName(cls) + "." + id + ".name";
|
||||
if (ConfigUtils.getProperties().getProperty(key) == null) {
|
||||
ConfigUtils.getProperties().setProperty(key, id);
|
||||
addDefaultNameConfig = true;
|
||||
}
|
||||
|
||||
config.refresh();
|
||||
configManager.addConfig(config);
|
||||
} catch (Exception e) {
|
||||
logger.error("load config failed, id: " + id + ", type:" + cls.getSimpleName(), e);
|
||||
throw new IllegalStateException("load config failed, id: " + id + ", type:" + cls.getSimpleName());
|
||||
} finally {
|
||||
if (addDefaultNameConfig && key != null) {
|
||||
ConfigUtils.getProperties().remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// If none config of the type, try load single config
|
||||
if (configManager.getConfigs(cls).isEmpty()) {
|
||||
// load single config
|
||||
Environment env = ApplicationModel.getEnvironment();
|
||||
List<Map<String, String>> configurationMaps = env.getConfigurationMaps();
|
||||
if (ConfigurationUtils.hasSubProperties(configurationMaps, AbstractConfig.getTypePrefix(cls))) {
|
||||
T config = null;
|
||||
try {
|
||||
config = cls.newInstance();
|
||||
config.refresh();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("create default config instance failed, type:" + cls.getSimpleName());
|
||||
}
|
||||
|
||||
configManager.addConfig(config);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Search props and extract config ids of specify type.
|
||||
* <pre>
|
||||
* # properties
|
||||
* dubbo.registries.registry1.address=xxx
|
||||
* dubbo.registries.registry2.port=xxx
|
||||
*
|
||||
* # extract
|
||||
* Set configIds = getConfigIds(RegistryConfig.class)
|
||||
*
|
||||
* # result
|
||||
* configIds: ["registry1", "registry2"]
|
||||
* </pre>
|
||||
*
|
||||
* @param clazz config type
|
||||
* @return ids of specify config type
|
||||
*/
|
||||
private Set<String> getConfigIds(Class<? extends AbstractConfig> clazz) {
|
||||
String prefix = CommonConstants.DUBBO + "." + AbstractConfig.getPluralTagName(clazz) + ".";
|
||||
Environment environment = ApplicationModel.getEnvironment();
|
||||
return ConfigurationUtils.getSubIds(environment.getConfigurationMaps(), prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize {@link MetadataService} from {@link WritableMetadataService}'s extension
|
||||
|
|
@ -881,6 +1058,10 @@ public class DubboBootstrap {
|
|||
public DubboBootstrap start() {
|
||||
if (started.compareAndSet(false, true)) {
|
||||
startup.set(false);
|
||||
initialized.set(false);
|
||||
shutdown.set(false);
|
||||
awaited.set(false);
|
||||
|
||||
initialize();
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(NAME + " is starting...");
|
||||
|
|
@ -908,16 +1089,14 @@ public class DubboBootstrap {
|
|||
if (logger.isInfoEnabled()) {
|
||||
logger.info(NAME + " is ready.");
|
||||
}
|
||||
ExtensionLoader<DubboBootstrapStartStopListener> exts = getExtensionLoader(DubboBootstrapStartStopListener.class);
|
||||
exts.getSupportedExtensionInstances().forEach(ext -> ext.onStart(this));
|
||||
onStart();
|
||||
}).start();
|
||||
} else {
|
||||
startup.set(true);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(NAME + " is ready.");
|
||||
}
|
||||
ExtensionLoader<DubboBootstrapStartStopListener> exts = getExtensionLoader(DubboBootstrapStartStopListener.class);
|
||||
exts.getSupportedExtensionInstances().forEach(ext -> ext.onStart(this));
|
||||
onStart();
|
||||
}
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(NAME + " has started.");
|
||||
|
|
@ -1040,9 +1219,8 @@ public class DubboBootstrap {
|
|||
);
|
||||
}
|
||||
try {
|
||||
environment.setConfigCenterFirst(configCenter.isHighestPriority());
|
||||
environment.updateExternalConfigurationMap(parseProperties(configContent));
|
||||
environment.updateAppExternalConfigurationMap(parseProperties(appConfigContent));
|
||||
environment.updateExternalConfigMap(parseProperties(configContent));
|
||||
environment.updateAppExternalConfigMap(parseProperties(appConfigContent));
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Failed to parse configurations from Config Center.", e);
|
||||
}
|
||||
|
|
@ -1065,10 +1243,13 @@ public class DubboBootstrap {
|
|||
}
|
||||
|
||||
private void exportServices() {
|
||||
configManager.getServices().forEach(sc -> {
|
||||
for (ServiceConfigBase sc : configManager.getServices()) {
|
||||
// TODO, compatible with ServiceConfig.export()
|
||||
ServiceConfig serviceConfig = (ServiceConfig) sc;
|
||||
serviceConfig.setBootstrap(this);
|
||||
if (!serviceConfig.isRefreshed()) {
|
||||
serviceConfig.refresh();
|
||||
}
|
||||
|
||||
if (exportAsync) {
|
||||
ExecutorService executor = executorRepository.getServiceExporterExecutor();
|
||||
|
|
@ -1085,7 +1266,7 @@ public class DubboBootstrap {
|
|||
sc.export();
|
||||
exportedServices.add(sc);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void unexportServices() {
|
||||
|
|
@ -1112,6 +1293,9 @@ public class DubboBootstrap {
|
|||
// TODO, compatible with ReferenceConfig.refer()
|
||||
ReferenceConfig referenceConfig = (ReferenceConfig) rc;
|
||||
referenceConfig.setBootstrap(this);
|
||||
if (!referenceConfig.isRefreshed()) {
|
||||
referenceConfig.refresh();
|
||||
}
|
||||
|
||||
if (rc.shouldInit()) {
|
||||
if (referAsync) {
|
||||
|
|
@ -1212,32 +1396,58 @@ public class DubboBootstrap {
|
|||
if (destroyLock.tryLock()
|
||||
&& shutdown.compareAndSet(false, true)) {
|
||||
try {
|
||||
DubboShutdownHook.destroyAll();
|
||||
|
||||
if (started.compareAndSet(true, false)
|
||||
&& destroyed.compareAndSet(false, true)) {
|
||||
|
||||
unregisterServiceInstance();
|
||||
unexportMetadataService();
|
||||
unexportServices();
|
||||
unreferServices();
|
||||
if (destroyed.compareAndSet(false, true)) {
|
||||
if (started.compareAndSet(true, false)) {
|
||||
unregisterServiceInstance();
|
||||
unexportMetadataService();
|
||||
unexportServices();
|
||||
unreferServices();
|
||||
}
|
||||
|
||||
destroyRegistries();
|
||||
|
||||
destroyProtocols();
|
||||
destroyServiceDiscoveries();
|
||||
destroyExecutorRepository();
|
||||
destroyMetadataReports();
|
||||
|
||||
// check config
|
||||
checkConfigState();
|
||||
|
||||
clear();
|
||||
shutdown();
|
||||
release();
|
||||
ExtensionLoader<DubboBootstrapStartStopListener> exts = getExtensionLoader(DubboBootstrapStartStopListener.class);
|
||||
exts.getSupportedExtensionInstances().forEach(ext -> ext.onStop(this));
|
||||
|
||||
onStop();
|
||||
}
|
||||
|
||||
destroyDynamicConfigurations();
|
||||
ShutdownHookCallbacks.INSTANCE.clear();
|
||||
} finally {
|
||||
initialized.set(false);
|
||||
startup.set(false);
|
||||
destroyLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onStart() {
|
||||
ExtensionLoader<DubboBootstrapStartStopListener> exts = getExtensionLoader(DubboBootstrapStartStopListener.class);
|
||||
exts.getSupportedExtensionInstances().forEach(ext -> ext.onStart(this));
|
||||
}
|
||||
|
||||
private void onStop() {
|
||||
ExtensionLoader<DubboBootstrapStartStopListener> exts = getExtensionLoader(DubboBootstrapStartStopListener.class);
|
||||
exts.getSupportedExtensionInstances().forEach(ext -> ext.onStop(this));
|
||||
}
|
||||
|
||||
private void checkConfigState() {
|
||||
// config manager should not be cleared at this moment
|
||||
if (!ignoreConfigState && !configManager.getApplication().isPresent()) {
|
||||
logger.error("Dubbo config was cleaned prematurely");
|
||||
throw new IllegalStateException("Dubbo config was cleaned prematurely");
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyExecutorRepository() {
|
||||
ExtensionLoader.getExtensionLoader(ExecutorRepository.class).getDefaultExtension().destroyAll();
|
||||
}
|
||||
|
|
@ -1246,6 +1456,23 @@ public class DubboBootstrap {
|
|||
AbstractRegistryFactory.destroyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy all the protocols.
|
||||
*/
|
||||
private void destroyProtocols() {
|
||||
ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.class);
|
||||
for (String protocolName : loader.getLoadedExtensions()) {
|
||||
try {
|
||||
Protocol protocol = loader.getLoadedExtension(protocolName);
|
||||
if (protocol != null) {
|
||||
protocol.destroy();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger.warn(t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyServiceDiscoveries() {
|
||||
getServiceDiscoveries().forEach(serviceDiscovery -> {
|
||||
execute(serviceDiscovery::destroy);
|
||||
|
|
@ -1255,6 +1482,17 @@ public class DubboBootstrap {
|
|||
}
|
||||
}
|
||||
|
||||
private void destroyMetadataReports() {
|
||||
AbstractMetadataReportFactory.destroy();
|
||||
ExtensionLoader.resetExtensionLoader(MetadataReportFactory.class);
|
||||
}
|
||||
|
||||
private void destroyDynamicConfigurations() {
|
||||
// DynamicConfiguration may be cached somewhere, and maybe used during destroy
|
||||
// destroy them may cause some troubles, so just clear instances cache
|
||||
ExtensionLoader.resetExtensionLoader(DynamicConfigurationFactory.class);
|
||||
}
|
||||
|
||||
private void clear() {
|
||||
clearConfigs();
|
||||
clearApplicationModel();
|
||||
|
|
@ -1278,6 +1516,11 @@ public class DubboBootstrap {
|
|||
logger.info(NAME + " is about to shutdown...");
|
||||
}
|
||||
condition.signalAll();
|
||||
// sleep
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -1299,68 +1542,7 @@ public class DubboBootstrap {
|
|||
}
|
||||
|
||||
public ApplicationConfig getApplication() {
|
||||
ApplicationConfig application = configManager
|
||||
.getApplication()
|
||||
.orElseGet(() -> {
|
||||
ApplicationConfig applicationConfig = new ApplicationConfig();
|
||||
configManager.setApplication(applicationConfig);
|
||||
return applicationConfig;
|
||||
});
|
||||
|
||||
if (!application.isRefreshed()) {
|
||||
application.refresh();
|
||||
}
|
||||
return application;
|
||||
return configManager.getApplicationOrElseThrow();
|
||||
}
|
||||
|
||||
private MonitorConfig getMonitor() {
|
||||
MonitorConfig monitor = configManager
|
||||
.getMonitor()
|
||||
.orElseGet(() -> {
|
||||
MonitorConfig monitorConfig = new MonitorConfig();
|
||||
configManager.setMonitor(monitorConfig);
|
||||
return monitorConfig;
|
||||
});
|
||||
|
||||
monitor.refresh();
|
||||
return monitor;
|
||||
}
|
||||
|
||||
private MetricsConfig getMetrics() {
|
||||
MetricsConfig metrics = configManager
|
||||
.getMetrics()
|
||||
.orElseGet(() -> {
|
||||
MetricsConfig metricsConfig = new MetricsConfig();
|
||||
configManager.setMetrics(metricsConfig);
|
||||
return metricsConfig;
|
||||
});
|
||||
metrics.refresh();
|
||||
return metrics;
|
||||
}
|
||||
|
||||
private ModuleConfig getModule() {
|
||||
ModuleConfig module = configManager
|
||||
.getModule()
|
||||
.orElseGet(() -> {
|
||||
ModuleConfig moduleConfig = new ModuleConfig();
|
||||
configManager.setModule(moduleConfig);
|
||||
return moduleConfig;
|
||||
});
|
||||
|
||||
module.refresh();
|
||||
return module;
|
||||
}
|
||||
|
||||
private SslConfig getSsl() {
|
||||
SslConfig ssl = configManager
|
||||
.getSsl()
|
||||
.orElseGet(() -> {
|
||||
SslConfig sslConfig = new SslConfig();
|
||||
configManager.setSsl(sslConfig);
|
||||
return sslConfig;
|
||||
});
|
||||
|
||||
ssl.refresh();
|
||||
return ssl;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,18 +34,12 @@ public abstract class AbstractBuilder<C extends AbstractConfig, B extends Abstra
|
|||
* The config id
|
||||
*/
|
||||
protected String id;
|
||||
protected String prefix;
|
||||
|
||||
public B id(String id) {
|
||||
this.id = id;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
protected B prefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
protected abstract B getThis();
|
||||
|
||||
protected static Map<String, String> appendParameter(Map<String, String> parameters, String key, String value) {
|
||||
|
|
@ -68,9 +62,6 @@ public abstract class AbstractBuilder<C extends AbstractConfig, B extends Abstra
|
|||
if (!StringUtils.isEmpty(id)) {
|
||||
instance.setId(id);
|
||||
}
|
||||
if (!StringUtils.isEmpty(prefix)) {
|
||||
instance.setPrefix(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -17,13 +17,16 @@
|
|||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.api.Greeting;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
|
|
@ -31,8 +34,10 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
|
|
@ -42,6 +47,16 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
|
||||
public class AbstractConfigTest {
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() {
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
SysProps.clear();
|
||||
}
|
||||
|
||||
//FIXME
|
||||
/*@Test
|
||||
public void testAppendProperties1() throws Exception {
|
||||
|
|
@ -156,20 +171,21 @@ public class AbstractConfigTest {
|
|||
|
||||
@Test
|
||||
public void testAppendAttributes1() throws Exception {
|
||||
Map<String, Object> parameters = new HashMap<String, Object>();
|
||||
AbstractConfig.appendAttributes(parameters, new AttributeConfig('l', true, (byte) 0x01), "prefix");
|
||||
Assertions.assertEquals('l', parameters.get("prefix.let"));
|
||||
Assertions.assertEquals(true, parameters.get("prefix.activate"));
|
||||
Assertions.assertFalse(parameters.containsKey("prefix.flag"));
|
||||
}
|
||||
ParameterConfig config = new ParameterConfig(1, "hello/world", 30, "password");
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
AbstractConfig.appendParameters(parameters, config);
|
||||
|
||||
@Test
|
||||
public void testAppendAttributes2() throws Exception {
|
||||
Map<String, Object> parameters = new HashMap<String, Object>();
|
||||
AbstractConfig.appendAttributes(parameters, new AttributeConfig('l', true, (byte) 0x01));
|
||||
Assertions.assertEquals('l', parameters.get("let"));
|
||||
Assertions.assertEquals(true, parameters.get("activate"));
|
||||
Assertions.assertFalse(parameters.containsKey("flag"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
AbstractConfig.appendAttributes(attributes, config);
|
||||
|
||||
Assertions.assertEquals(null, parameters.get("secret"));
|
||||
Assertions.assertEquals(null, parameters.get("parameters"));
|
||||
// secret is excluded for url parameters, but keep for attributes
|
||||
Assertions.assertEquals(config.getSecret(), attributes.get("secret"));
|
||||
Assertions.assertEquals(config.getName(), attributes.get("name"));
|
||||
Assertions.assertEquals(""+config.getNumber(), attributes.get("number"));
|
||||
Assertions.assertEquals(""+config.getAge(), attributes.get("age"));
|
||||
Assertions.assertEquals(StringUtils.encodeParameters(config.getParameters()), attributes.get("parameters"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -313,14 +329,14 @@ public class AbstractConfigTest {
|
|||
external.put("dubbo.override.key", "external");
|
||||
// @Parameter(key="key2", useKeyAsProperty=true)
|
||||
external.put("dubbo.override.key2", "external");
|
||||
ApplicationModel.getEnvironment().setExternalConfigMap(external);
|
||||
ApplicationModel.getEnvironment().initialize();
|
||||
ApplicationModel.getEnvironment().setExternalConfigMap(external);
|
||||
|
||||
System.setProperty("dubbo.override.address", "system://127.0.0.1:2181");
|
||||
System.setProperty("dubbo.override.protocol", "system");
|
||||
SysProps.setProperty("dubbo.override.address", "system://127.0.0.1:2181");
|
||||
SysProps.setProperty("dubbo.override.protocol", "system");
|
||||
// this will not override, use 'key' instead, @Parameter(key="key1", useKeyAsProperty=false)
|
||||
System.setProperty("dubbo.override.key1", "system");
|
||||
System.setProperty("dubbo.override.key2", "system");
|
||||
SysProps.setProperty("dubbo.override.key1", "system");
|
||||
SysProps.setProperty("dubbo.override.key2", "system");
|
||||
|
||||
// Load configuration from system properties -> externalConfiguration -> RegistryConfig -> dubbo.properties
|
||||
overrideConfig.refresh();
|
||||
|
|
@ -329,13 +345,10 @@ public class AbstractConfigTest {
|
|||
Assertions.assertEquals("system", overrideConfig.getProtocol());
|
||||
Assertions.assertEquals("override-config://", overrideConfig.getEscape());
|
||||
Assertions.assertEquals("external", overrideConfig.getKey());
|
||||
Assertions.assertEquals("system", overrideConfig.getUseKeyAsProperty());
|
||||
Assertions.assertEquals("system", overrideConfig.getKey2());
|
||||
} finally {
|
||||
System.clearProperty("dubbo.override.address");
|
||||
System.clearProperty("dubbo.override.protocol");
|
||||
System.clearProperty("dubbo.override.key1");
|
||||
System.clearProperty("dubbo.override.key2");
|
||||
ApplicationModel.getEnvironment().clearExternalConfigs();
|
||||
SysProps.clear();
|
||||
ApplicationModel.getEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -348,9 +361,9 @@ public class AbstractConfigTest {
|
|||
overrideConfig.setEscape("override-config://");
|
||||
overrideConfig.setExclude("override-config");
|
||||
|
||||
System.setProperty("dubbo.override.address", "system://127.0.0.1:2181");
|
||||
System.setProperty("dubbo.override.protocol", "system");
|
||||
System.setProperty("dubbo.override.key", "system");
|
||||
SysProps.setProperty("dubbo.override.address", "system://127.0.0.1:2181");
|
||||
SysProps.setProperty("dubbo.override.protocol", "system");
|
||||
SysProps.setProperty("dubbo.override.key", "system");
|
||||
|
||||
overrideConfig.refresh();
|
||||
|
||||
|
|
@ -359,10 +372,8 @@ public class AbstractConfigTest {
|
|||
Assertions.assertEquals("override-config://", overrideConfig.getEscape());
|
||||
Assertions.assertEquals("system", overrideConfig.getKey());
|
||||
} finally {
|
||||
System.clearProperty("dubbo.override.address");
|
||||
System.clearProperty("dubbo.override.protocol");
|
||||
System.clearProperty("dubbo.override.key1");
|
||||
ApplicationModel.getEnvironment().clearExternalConfigs();
|
||||
SysProps.clear();
|
||||
ApplicationModel.getEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -386,7 +397,7 @@ public class AbstractConfigTest {
|
|||
Assertions.assertEquals("override-config://", overrideConfig.getEscape());
|
||||
//Assertions.assertEquals("properties", overrideConfig.getUseKeyAsProperty());
|
||||
} finally {
|
||||
ApplicationModel.getEnvironment().clearExternalConfigs();
|
||||
ApplicationModel.getEnvironment().destroy();
|
||||
ConfigUtils.setProperties(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -410,8 +421,8 @@ public class AbstractConfigTest {
|
|||
external.put("dubbo.override.key", "external");
|
||||
// @Parameter(key="key2", useKeyAsProperty=true)
|
||||
external.put("dubbo.override.key2", "external");
|
||||
ApplicationModel.getEnvironment().setExternalConfigMap(external);
|
||||
ApplicationModel.getEnvironment().initialize();
|
||||
ApplicationModel.getEnvironment().setExternalConfigMap(external);
|
||||
|
||||
overrideConfig.refresh();
|
||||
|
||||
|
|
@ -420,9 +431,9 @@ public class AbstractConfigTest {
|
|||
Assertions.assertEquals("external://", overrideConfig.getEscape());
|
||||
Assertions.assertEquals("external", overrideConfig.getExclude());
|
||||
Assertions.assertEquals("external", overrideConfig.getKey());
|
||||
Assertions.assertEquals("external", overrideConfig.getUseKeyAsProperty());
|
||||
Assertions.assertEquals("external", overrideConfig.getKey2());
|
||||
} finally {
|
||||
ApplicationModel.getEnvironment().clearExternalConfigs();
|
||||
ApplicationModel.getEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -437,16 +448,16 @@ public class AbstractConfigTest {
|
|||
overrideConfig.setExclude("override-config");
|
||||
|
||||
Map<String, String> external = new HashMap<>();
|
||||
external.put("dubbo.override.override-id.address", "external-override-id://127.0.0.1:2181");
|
||||
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.override.key", "external");
|
||||
external.put("dubbo.overrides.override-id.key", "external");
|
||||
// @Parameter(key="key2", useKeyAsProperty=true)
|
||||
external.put("dubbo.override.key2", "external");
|
||||
ApplicationModel.getEnvironment().setExternalConfigMap(external);
|
||||
external.put("dubbo.overrides.override-id.key2", "external");
|
||||
ApplicationModel.getEnvironment().initialize();
|
||||
ApplicationModel.getEnvironment().setExternalConfigMap(external);
|
||||
|
||||
ConfigCenterConfig configCenter = new ConfigCenterConfig();
|
||||
overrideConfig.setConfigCenter(configCenter);
|
||||
|
|
@ -457,9 +468,9 @@ public class AbstractConfigTest {
|
|||
Assertions.assertEquals("override-config", overrideConfig.getProtocol());
|
||||
Assertions.assertEquals("override-config://", overrideConfig.getEscape());
|
||||
Assertions.assertEquals("external", overrideConfig.getKey());
|
||||
Assertions.assertEquals("external", overrideConfig.getUseKeyAsProperty());
|
||||
Assertions.assertEquals("external", overrideConfig.getKey2());
|
||||
} finally {
|
||||
ApplicationModel.getEnvironment().clearExternalConfigs();
|
||||
ApplicationModel.getEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -475,8 +486,8 @@ public class AbstractConfigTest {
|
|||
|
||||
Map<String, String> external = new HashMap<>();
|
||||
external.put("dubbo.override.parameters", "[{key3:value3},{key4:value4},{key2:value5}]");
|
||||
ApplicationModel.getEnvironment().setExternalConfigMap(external);
|
||||
ApplicationModel.getEnvironment().initialize();
|
||||
ApplicationModel.getEnvironment().setExternalConfigMap(external);
|
||||
|
||||
ConfigCenterConfig configCenter = new ConfigCenterConfig();
|
||||
overrideConfig.setConfigCenter(configCenter);
|
||||
|
|
@ -488,14 +499,14 @@ public class AbstractConfigTest {
|
|||
Assertions.assertEquals("value3", overrideConfig.getParameters().get("key3"));
|
||||
Assertions.assertEquals("value4", overrideConfig.getParameters().get("key4"));
|
||||
|
||||
System.setProperty("dubbo.override.parameters", "[{key3:value6}]");
|
||||
SysProps.setProperty("dubbo.override.parameters", "[{key3:value6}]");
|
||||
overrideConfig.refresh();
|
||||
|
||||
Assertions.assertEquals("value6", overrideConfig.getParameters().get("key3"));
|
||||
Assertions.assertEquals("value4", overrideConfig.getParameters().get("key4"));
|
||||
} finally {
|
||||
System.clearProperty("dubbo.override.parameters");
|
||||
ApplicationModel.getEnvironment().clearExternalConfigs();
|
||||
SysProps.clear();
|
||||
ApplicationModel.getEnvironment().destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -525,7 +536,7 @@ public class AbstractConfigTest {
|
|||
Assertions.assertEquals("value-from-config", overrideConfig.getNotConflictKey());
|
||||
Assertions.assertEquals("value-from-env", overrideConfig.getNotConflictKey2());
|
||||
} finally {
|
||||
ApplicationModel.getEnvironment().clearExternalConfigs();
|
||||
ApplicationModel.getEnvironment().destroy();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -560,12 +571,12 @@ public class AbstractConfigTest {
|
|||
Assertions.assertEquals(application1, application2);
|
||||
|
||||
ProtocolConfig protocol1 = new ProtocolConfig();
|
||||
protocol1.setHost("127.0.0.1");// excluded
|
||||
protocol1.setName("dubbo");
|
||||
protocol1.setPort(1234);
|
||||
ProtocolConfig protocol2 = new ProtocolConfig();
|
||||
protocol2.setHost("127.0.0.2");// excluded
|
||||
protocol2.setName("dubbo");
|
||||
Assertions.assertEquals(protocol1, protocol2);
|
||||
protocol2.setPort(1235);
|
||||
Assertions.assertNotEquals(protocol1, protocol2);
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
|
@ -597,7 +608,7 @@ public class AbstractConfigTest {
|
|||
public String protocol;
|
||||
public String exclude;
|
||||
public String key;
|
||||
public String useKeyAsProperty;
|
||||
public String key2;
|
||||
public String escape;
|
||||
public String notConflictKey;
|
||||
public String notConflictKey2;
|
||||
|
|
@ -627,7 +638,7 @@ public class AbstractConfigTest {
|
|||
this.exclude = exclude;
|
||||
}
|
||||
|
||||
@Parameter(key = "key1", useKeyAsProperty = false)
|
||||
@Parameter(key = "key1")
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
|
@ -636,13 +647,13 @@ public class AbstractConfigTest {
|
|||
this.key = key;
|
||||
}
|
||||
|
||||
@Parameter(key = "key2", useKeyAsProperty = true)
|
||||
public String getUseKeyAsProperty() {
|
||||
return useKeyAsProperty;
|
||||
@Parameter(key = "mykey")
|
||||
public String getKey2() {
|
||||
return key2;
|
||||
}
|
||||
|
||||
public void setUseKeyAsProperty(String useKeyAsProperty) {
|
||||
this.useKeyAsProperty = useKeyAsProperty;
|
||||
public void setKey2(String key2) {
|
||||
this.key2 = key2;
|
||||
}
|
||||
|
||||
@Parameter(escaped = true)
|
||||
|
|
@ -686,7 +697,7 @@ public class AbstractConfigTest {
|
|||
}
|
||||
|
||||
PropertiesConfig(String id) {
|
||||
this.id = id;
|
||||
this.setId(id);
|
||||
}
|
||||
|
||||
public char getC() {
|
||||
|
|
@ -821,44 +832,6 @@ public class AbstractConfigTest {
|
|||
}
|
||||
}
|
||||
|
||||
private static class AttributeConfig {
|
||||
private char letter;
|
||||
private boolean activate;
|
||||
private byte flag;
|
||||
|
||||
public AttributeConfig(char letter, boolean activate, byte flag) {
|
||||
this.letter = letter;
|
||||
this.activate = activate;
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
@Parameter(attribute = true, key = "let")
|
||||
public char getLetter() {
|
||||
return letter;
|
||||
}
|
||||
|
||||
public void setLetter(char letter) {
|
||||
this.letter = letter;
|
||||
}
|
||||
|
||||
@Parameter(attribute = true)
|
||||
public boolean isActivate() {
|
||||
return activate;
|
||||
}
|
||||
|
||||
public void setActivate(boolean activate) {
|
||||
this.activate = activate;
|
||||
}
|
||||
|
||||
public byte getFlag() {
|
||||
return flag;
|
||||
}
|
||||
|
||||
public void setFlag(byte flag) {
|
||||
this.flag = flag;
|
||||
}
|
||||
}
|
||||
|
||||
private static class AnnotationConfig extends AbstractConfig {
|
||||
private Class interfaceClass;
|
||||
private String filter;
|
||||
|
|
@ -933,4 +906,24 @@ public class AbstractConfigTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMetaData() throws Exception {
|
||||
|
||||
// Expect empty metadata for new instance
|
||||
// Check and set default value of field in checkDefault() method
|
||||
|
||||
List<Class<? extends AbstractConfig>> configClasses = Arrays.asList(ApplicationConfig.class,
|
||||
ConsumerConfig.class, ProviderConfig.class, ReferenceConfig.class, ServiceConfig.class,
|
||||
ProtocolConfig.class, RegistryConfig.class, ConfigCenterConfig.class, MetadataReportConfig.class,
|
||||
ModuleConfig.class, SslConfig.class, MetricsConfig.class, MonitorConfig.class, MethodConfig.class);
|
||||
|
||||
for (Class<? extends AbstractConfig> configClass : configClasses) {
|
||||
AbstractConfig config = configClass.newInstance();
|
||||
Map<String, String> metaData = config.getMetaData();
|
||||
Assertions.assertEquals(0, metaData.size(), "Expect empty metadata for new instance but found: "+metaData +" of "+configClass.getSimpleName());
|
||||
System.out.println(configClass.getSimpleName()+" metadata is checked.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ 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.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
|
@ -42,85 +42,20 @@ public class AbstractInterfaceConfigTest {
|
|||
|
||||
@BeforeAll
|
||||
public static void setUp(@TempDir Path folder) {
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
dubboProperties = folder.resolve(CommonConstants.DUBBO_PROPERTIES_KEY).toFile();
|
||||
System.setProperty(CommonConstants.DUBBO_PROPERTIES_KEY, dubboProperties.getAbsolutePath());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDown() {
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
System.clearProperty(CommonConstants.DUBBO_PROPERTIES_KEY);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearMethodAfterEachUT() {
|
||||
// ApplicationModel.getConfigManager().clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckRegistry1() {
|
||||
System.setProperty("dubbo.registry.address", "addr1");
|
||||
try {
|
||||
InterfaceConfig interfaceConfig = new InterfaceConfig();
|
||||
interfaceConfig.setApplication(new ApplicationConfig("testCheckRegistry1"));
|
||||
interfaceConfig.checkRegistry();
|
||||
Assertions.assertEquals(1, interfaceConfig.getRegistries().size());
|
||||
Assertions.assertEquals("addr1", interfaceConfig.getRegistries().get(0).getAddress());
|
||||
} finally {
|
||||
System.clearProperty("dubbo.registry.address");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckRegistry2() {
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
InterfaceConfig interfaceConfig = new InterfaceConfig();
|
||||
interfaceConfig.checkRegistry();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkInterfaceAndMethods1() {
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
InterfaceConfig interfaceConfig = new InterfaceConfig();
|
||||
interfaceConfig.checkInterfaceAndMethods(null, null);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkInterfaceAndMethods2() {
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
InterfaceConfig interfaceConfig = new InterfaceConfig();
|
||||
interfaceConfig.checkInterfaceAndMethods(AbstractInterfaceConfigTest.class, null);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkInterfaceAndMethod3() {
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
MethodConfig methodConfig = new MethodConfig();
|
||||
InterfaceConfig interfaceConfig = new InterfaceConfig();
|
||||
interfaceConfig.checkInterfaceAndMethods(Greeting.class, Collections.singletonList(methodConfig));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkInterfaceAndMethod4() {
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
MethodConfig methodConfig = new MethodConfig();
|
||||
methodConfig.setName("nihao");
|
||||
InterfaceConfig interfaceConfig = new InterfaceConfig();
|
||||
interfaceConfig.checkInterfaceAndMethods(Greeting.class, Collections.singletonList(methodConfig));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkInterfaceAndMethod5() {
|
||||
MethodConfig methodConfig = new MethodConfig();
|
||||
methodConfig.setName("hello");
|
||||
InterfaceConfig interfaceConfig = new InterfaceConfig();
|
||||
interfaceConfig.checkInterfaceAndMethods(Greeting.class, Collections.singletonList(methodConfig));
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -312,6 +247,7 @@ public class AbstractInterfaceConfigTest {
|
|||
interfaceConfig.setMonitor("monitor-addr");
|
||||
Assertions.assertEquals("monitor-addr", interfaceConfig.getMonitor().getAddress());
|
||||
MonitorConfig monitorConfig = new MonitorConfig();
|
||||
monitorConfig.setAddress("monitor-addr");
|
||||
interfaceConfig.setMonitor(monitorConfig);
|
||||
Assertions.assertSame(monitorConfig, interfaceConfig.getMonitor());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@
|
|||
|
||||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
|
@ -37,13 +40,28 @@ import static org.hamcrest.Matchers.sameInstance;
|
|||
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
|
||||
|
||||
public class ApplicationConfigTest {
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() {
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
SysProps.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testName() throws Exception {
|
||||
ApplicationConfig application = new ApplicationConfig();
|
||||
application.setName("app");
|
||||
assertThat(application.getName(), equalTo("app"));
|
||||
assertThat(application.getId(), equalTo(null));
|
||||
|
||||
application = new ApplicationConfig("app2");
|
||||
assertThat(application.getName(), equalTo("app2"));
|
||||
assertThat(application.getId(), equalTo(null));
|
||||
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
ApplicationConfig.appendParameters(parameters, application);
|
||||
assertThat(parameters, hasEntry(APPLICATION_KEY, "app2"));
|
||||
|
|
@ -185,7 +203,7 @@ public class ApplicationConfigTest {
|
|||
public void testAppendEnvironmentProperties() {
|
||||
try {
|
||||
ApplicationConfig application = new ApplicationConfig("app");
|
||||
System.setProperty("dubbo.labels", "tag1=value1;tag2=value2 ; tag3 = value3");
|
||||
SysProps.setProperty("dubbo.labels", "tag1=value1;tag2=value2 ; tag3 = value3");
|
||||
application.refresh();
|
||||
Map<String, String> parameters = application.getParameters();
|
||||
Assertions.assertEquals("value1", parameters.get("tag1"));
|
||||
|
|
@ -193,11 +211,11 @@ public class ApplicationConfigTest {
|
|||
Assertions.assertEquals("value3", parameters.get("tag3"));
|
||||
|
||||
ApplicationConfig application1 = new ApplicationConfig("app");
|
||||
System.setProperty("dubbo.env.keys", "tag1, tag2,tag3");
|
||||
SysProps.setProperty("dubbo.env.keys", "tag1, tag2,tag3");
|
||||
// mock environment variables
|
||||
System.setProperty("tag1", "value1");
|
||||
System.setProperty("tag2", "value2");
|
||||
System.setProperty("tag3", "value3");
|
||||
SysProps.setProperty("tag1", "value1");
|
||||
SysProps.setProperty("tag2", "value2");
|
||||
SysProps.setProperty("tag3", "value3");
|
||||
application1.refresh();
|
||||
Map<String, String> parameters1 = application1.getParameters();
|
||||
Assertions.assertEquals("value1", parameters1.get("tag1"));
|
||||
|
|
@ -210,8 +228,118 @@ public class ApplicationConfigTest {
|
|||
Assertions.assertEquals("value2", urlParameters.get("tag2"));
|
||||
Assertions.assertEquals("value3", urlParameters.get("tag3"));
|
||||
} finally {
|
||||
System.clearProperty("dubbo.labels");
|
||||
System.clearProperty("dubbo.keys");
|
||||
SysProps.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaData() {
|
||||
ApplicationConfig config = new ApplicationConfig();
|
||||
Map<String, String> metaData = config.getMetaData();
|
||||
Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: "+metaData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideEmptyConfig() {
|
||||
String owner = "tom1";
|
||||
SysProps.setProperty("dubbo.application.name", "demo-app");
|
||||
SysProps.setProperty("dubbo.application.owner", owner);
|
||||
SysProps.setProperty("dubbo.application.version", "1.2.3");
|
||||
|
||||
try {
|
||||
ApplicationConfig applicationConfig = new ApplicationConfig();
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application(applicationConfig)
|
||||
.initialize();
|
||||
|
||||
Assertions.assertEquals(owner, applicationConfig.getOwner());
|
||||
Assertions.assertEquals("1.2.3", applicationConfig.getVersion());
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigById() {
|
||||
String owner = "tom2";
|
||||
SysProps.setProperty("dubbo.applications.demo-app.owner", owner);
|
||||
SysProps.setProperty("dubbo.applications.demo-app.version", "1.2.3");
|
||||
SysProps.setProperty("dubbo.applications.demo-app.name", "demo-app");
|
||||
|
||||
try {
|
||||
ApplicationConfig applicationConfig = new ApplicationConfig();
|
||||
applicationConfig.setId("demo-app");
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application(applicationConfig)
|
||||
.initialize();
|
||||
|
||||
Assertions.assertEquals("demo-app", applicationConfig.getId());
|
||||
Assertions.assertEquals("demo-app", applicationConfig.getName());
|
||||
Assertions.assertEquals(owner, applicationConfig.getOwner());
|
||||
Assertions.assertEquals("1.2.3", applicationConfig.getVersion());
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigByName() {
|
||||
String owner = "tom3";
|
||||
SysProps.setProperty("dubbo.applications.demo-app.owner", owner);
|
||||
SysProps.setProperty("dubbo.applications.demo-app.version", "1.2.3");
|
||||
|
||||
try {
|
||||
ApplicationConfig applicationConfig = new ApplicationConfig();
|
||||
applicationConfig.setName("demo-app");
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application(applicationConfig)
|
||||
.initialize();
|
||||
|
||||
Assertions.assertEquals(owner, applicationConfig.getOwner());
|
||||
Assertions.assertEquals("1.2.3", applicationConfig.getVersion());
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadConfig() {
|
||||
String owner = "tom4";
|
||||
SysProps.setProperty("dubbo.applications.demo-app.owner", owner);
|
||||
SysProps.setProperty("dubbo.applications.demo-app.version", "1.2.3");
|
||||
|
||||
try {
|
||||
DubboBootstrap.getInstance()
|
||||
.initialize();
|
||||
|
||||
ApplicationConfig applicationConfig = DubboBootstrap.getInstance().getApplication();
|
||||
|
||||
Assertions.assertEquals("demo-app", applicationConfig.getId());
|
||||
Assertions.assertEquals("demo-app", applicationConfig.getName());
|
||||
Assertions.assertEquals(owner, applicationConfig.getOwner());
|
||||
Assertions.assertEquals("1.2.3", applicationConfig.getVersion());
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigConvertCase() {
|
||||
SysProps.setProperty("dubbo.application.NAME", "demo-app");
|
||||
SysProps.setProperty("dubbo.application.qos-Enable", "false");
|
||||
SysProps.setProperty("dubbo.application.qos_host", "127.0.0.1");
|
||||
SysProps.setProperty("dubbo.application.qosPort", "2345");
|
||||
|
||||
try {
|
||||
DubboBootstrap.getInstance()
|
||||
.initialize();
|
||||
|
||||
ApplicationConfig applicationConfig = DubboBootstrap.getInstance().getApplication();
|
||||
|
||||
Assertions.assertEquals(false, applicationConfig.getQosEnable());
|
||||
Assertions.assertEquals("127.0.0.1", applicationConfig.getQosHost());
|
||||
Assertions.assertEquals(2345, applicationConfig.getQosPort());
|
||||
Assertions.assertEquals("demo-app", applicationConfig.getName());
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,14 +18,43 @@
|
|||
package org.apache.dubbo.config;
|
||||
|
||||
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
|
||||
|
||||
public class ConfigCenterConfigTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
SysProps.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrefix() {
|
||||
ConfigCenterConfig config = new ConfigCenterConfig();
|
||||
Assertions.assertEquals("dubbo.config-center", config.getPrefix());
|
||||
Assertions.assertEquals(Arrays.asList("dubbo.config-center"), config.getPrefixes());
|
||||
|
||||
config.setId("configcenterA");
|
||||
Assertions.assertEquals(Arrays.asList("dubbo.config-centers.configcenterA", "dubbo.config-center"),
|
||||
config.getPrefixes());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -34,11 +63,226 @@ public class ConfigCenterConfigTest {
|
|||
config.setNamespace("namespace");
|
||||
config.setGroup("group");
|
||||
config.setAddress("zookeeper://127.0.0.1:2181");
|
||||
config.setHighestPriority(null);
|
||||
config.refresh();
|
||||
|
||||
Assertions.assertEquals("zookeeper://127.0.0.1:2181/ConfigCenterConfig?check=true&" +
|
||||
"config-file=dubbo.properties&group=group&highest-priority=true&" +
|
||||
"config-file=dubbo.properties&group=group&" +
|
||||
"namespace=namespace&timeout=3000",
|
||||
config.toUrl().toFullString()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfig() {
|
||||
|
||||
String zkAddr = "zookeeper://127.0.0.1:2181";
|
||||
// sysprops has no id
|
||||
SysProps.setProperty("dubbo.config-center.check", "false");
|
||||
SysProps.setProperty("dubbo.config-center.address", zkAddr);
|
||||
|
||||
try {
|
||||
//No id and no address
|
||||
ConfigCenterConfig configCenter = new ConfigCenterConfig();
|
||||
configCenter.setAddress("N/A");
|
||||
|
||||
try {
|
||||
DubboBootstrap.getInstance()
|
||||
.application("demo-app")
|
||||
.configCenter(configCenter)
|
||||
.initialize();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Collection<ConfigCenterConfig> configCenters = ApplicationModel.getConfigManager().getConfigCenters();
|
||||
Assertions.assertEquals(1, configCenters.size());
|
||||
Assertions.assertEquals(configCenter, configCenters.iterator().next());
|
||||
Assertions.assertEquals(zkAddr, configCenter.getAddress());
|
||||
Assertions.assertEquals(false, configCenter.isCheck());
|
||||
} finally {
|
||||
SysProps.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfig2() {
|
||||
|
||||
String zkAddr = "nacos://127.0.0.1:8848";
|
||||
// sysprops has no id
|
||||
SysProps.setProperty("dubbo.config-center.check", "false");
|
||||
SysProps.setProperty("dubbo.config-center.address", zkAddr);
|
||||
|
||||
try {
|
||||
//No id but has address
|
||||
ConfigCenterConfig configCenter = new ConfigCenterConfig();
|
||||
configCenter.setAddress("zookeeper://127.0.0.1:2181");
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("demo-app")
|
||||
.configCenter(configCenter)
|
||||
.start();
|
||||
|
||||
Collection<ConfigCenterConfig> configCenters = ApplicationModel.getConfigManager().getConfigCenters();
|
||||
Assertions.assertEquals(1, configCenters.size());
|
||||
Assertions.assertEquals(configCenter, configCenters.iterator().next());
|
||||
Assertions.assertEquals(zkAddr, configCenter.getAddress());
|
||||
Assertions.assertEquals(false, configCenter.isCheck());
|
||||
} finally {
|
||||
SysProps.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigBySystemProps() {
|
||||
|
||||
//Config instance has Id, but sysprops without id
|
||||
SysProps.setProperty("dubbo.config-center.check", "false");
|
||||
SysProps.setProperty("dubbo.config-center.timeout", "1234");
|
||||
|
||||
try {
|
||||
// Config instance has id
|
||||
ConfigCenterConfig configCenter = new ConfigCenterConfig();
|
||||
configCenter.setTimeout(3000L);
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("demo-app")
|
||||
.configCenter(configCenter)
|
||||
.initialize();
|
||||
|
||||
Collection<ConfigCenterConfig> configCenters = ApplicationModel.getConfigManager().getConfigCenters();
|
||||
Assertions.assertEquals(1, configCenters.size());
|
||||
Assertions.assertEquals(configCenter, configCenters.iterator().next());
|
||||
Assertions.assertEquals(1234, configCenter.getTimeout());
|
||||
Assertions.assertEquals(false, configCenter.isCheck());
|
||||
} finally {
|
||||
SysProps.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigByDubboProps() {
|
||||
|
||||
// Config instance has id, dubbo props has no id
|
||||
Map props = new HashMap();
|
||||
props.put("dubbo.config-center.check", "false");
|
||||
props.put("dubbo.config-center.timeout", "1234");
|
||||
ConfigUtils.getProperties().putAll(props);
|
||||
|
||||
try {
|
||||
// Config instance has id
|
||||
ConfigCenterConfig configCenter = new ConfigCenterConfig();
|
||||
configCenter.setTimeout(3000L);
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("demo-app")
|
||||
.configCenter(configCenter)
|
||||
.initialize();
|
||||
|
||||
Collection<ConfigCenterConfig> configCenters = ApplicationModel.getConfigManager().getConfigCenters();
|
||||
Assertions.assertEquals(1, configCenters.size());
|
||||
Assertions.assertEquals(configCenter, configCenters.iterator().next());
|
||||
Assertions.assertEquals(3000L, configCenter.getTimeout());
|
||||
Assertions.assertEquals(false, configCenter.isCheck());
|
||||
} finally {
|
||||
props.keySet().forEach(ConfigUtils.getProperties()::remove);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigBySystemPropsWithId() {
|
||||
|
||||
// Both config instance and sysprops have id
|
||||
SysProps.setProperty("dubbo.config-centers.configcenterA.check", "false");
|
||||
SysProps.setProperty("dubbo.config-centers.configcenterA.timeout", "1234");
|
||||
|
||||
try {
|
||||
// Config instance has id
|
||||
ConfigCenterConfig configCenter = new ConfigCenterConfig();
|
||||
configCenter.setId("configcenterA");
|
||||
configCenter.setTimeout(3000L);
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("demo-app")
|
||||
.configCenter(configCenter)
|
||||
.start();
|
||||
|
||||
Collection<ConfigCenterConfig> configCenters = ApplicationModel.getConfigManager().getConfigCenters();
|
||||
Assertions.assertEquals(1, configCenters.size());
|
||||
Assertions.assertEquals(configCenter, configCenters.iterator().next());
|
||||
Assertions.assertEquals(1234, configCenter.getTimeout());
|
||||
Assertions.assertEquals(false, configCenter.isCheck());
|
||||
} finally {
|
||||
SysProps.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigByDubboPropsWithId() {
|
||||
|
||||
// Config instance has id, dubbo props has id
|
||||
Map props = new HashMap();
|
||||
props.put("dubbo.config-centers.configcenterA.check", "false");
|
||||
props.put("dubbo.config-centers.configcenterA.timeout", "1234");
|
||||
ConfigUtils.getProperties().putAll(props);
|
||||
|
||||
try {
|
||||
// Config instance has id
|
||||
ConfigCenterConfig configCenter = new ConfigCenterConfig();
|
||||
configCenter.setId("configcenterA");
|
||||
configCenter.setTimeout(3000L);
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("demo-app")
|
||||
.configCenter(configCenter)
|
||||
.start();
|
||||
|
||||
Collection<ConfigCenterConfig> configCenters = ApplicationModel.getConfigManager().getConfigCenters();
|
||||
Assertions.assertEquals(1, configCenters.size());
|
||||
Assertions.assertEquals(configCenter, configCenters.iterator().next());
|
||||
Assertions.assertEquals(3000L, configCenter.getTimeout());
|
||||
Assertions.assertEquals(false, configCenter.isCheck());
|
||||
} finally {
|
||||
props.keySet().forEach(ConfigUtils.getProperties()::remove);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaData() {
|
||||
ConfigCenterConfig configCenter = new ConfigCenterConfig();
|
||||
Map<String, String> metaData = configCenter.getMetaData();
|
||||
Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: "+metaData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParameters() {
|
||||
ConfigCenterConfig cc = new ConfigCenterConfig();
|
||||
cc.setParameters(new LinkedHashMap<>());
|
||||
cc.getParameters().put(CLIENT_KEY, null);
|
||||
|
||||
Map<String, String> params = new LinkedHashMap<>();
|
||||
ConfigCenterConfig.appendParameters(params, cc);
|
||||
|
||||
Map<String, String> attributes = new LinkedHashMap<>();
|
||||
ConfigCenterConfig.appendAttributes(attributes, cc);
|
||||
|
||||
String encodedParametersStr = attributes.get("parameters");
|
||||
Assertions.assertEquals("[]", encodedParametersStr);
|
||||
Assertions.assertEquals(0, StringUtils.parseParameters(encodedParametersStr).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAttributes() {
|
||||
ConfigCenterConfig cc = new ConfigCenterConfig();
|
||||
cc.setAddress("zookeeper://127.0.0.1:2181");
|
||||
Map<String, String> attributes = new LinkedHashMap<>();
|
||||
ConfigCenterConfig.appendAttributes(attributes, cc);
|
||||
|
||||
Assertions.assertEquals(cc.getAddress(), attributes.get("address"));
|
||||
Assertions.assertEquals(cc.getProtocol(), attributes.get("protocol"));
|
||||
Assertions.assertEquals(""+cc.getPort(), attributes.get("port"));
|
||||
Assertions.assertEquals(null, attributes.get("valid"));
|
||||
Assertions.assertEquals(null, attributes.get("refreshed"));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,13 +17,35 @@
|
|||
|
||||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.config.api.DemoService;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
public class ConsumerConfigTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
SysProps.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTimeout() throws Exception {
|
||||
try {
|
||||
|
|
@ -78,4 +100,160 @@ public class ConsumerConfigTest {
|
|||
consumer.setQueues(5);
|
||||
assertThat(consumer.getQueues(), equalTo(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigSingle() {
|
||||
SysProps.setProperty("dubbo.consumer.check", "false");
|
||||
SysProps.setProperty("dubbo.consumer.group", "demo");
|
||||
SysProps.setProperty("dubbo.consumer.threads", "10");
|
||||
|
||||
try {
|
||||
ConsumerConfig consumerConfig = new ConsumerConfig();
|
||||
consumerConfig.setGroup("groupA");
|
||||
consumerConfig.setThreads(20);
|
||||
consumerConfig.setCheck(true);
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("demo-app")
|
||||
.consumer(consumerConfig)
|
||||
.initialize();
|
||||
|
||||
Collection<ConsumerConfig> consumers = ApplicationModel.getConfigManager().getConsumers();
|
||||
Assertions.assertEquals(1, consumers.size());
|
||||
Assertions.assertEquals(consumerConfig, consumers.iterator().next());
|
||||
Assertions.assertEquals(false, consumerConfig.isCheck());
|
||||
Assertions.assertEquals("demo", consumerConfig.getGroup());
|
||||
Assertions.assertEquals(10, consumerConfig.getThreads());
|
||||
} finally {
|
||||
SysProps.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigByPluralityId() {
|
||||
SysProps.setProperty("dubbo.consumer.group", "demoA"); //ignore
|
||||
SysProps.setProperty("dubbo.consumers.consumerA.check", "false");
|
||||
SysProps.setProperty("dubbo.consumers.consumerA.group", "demoB");
|
||||
SysProps.setProperty("dubbo.consumers.consumerA.threads", "10");
|
||||
|
||||
try {
|
||||
ConsumerConfig consumerConfig = new ConsumerConfig();
|
||||
consumerConfig.setId("consumerA");
|
||||
consumerConfig.setGroup("groupA");
|
||||
consumerConfig.setThreads(20);
|
||||
consumerConfig.setCheck(true);
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("demo-app")
|
||||
.consumer(consumerConfig)
|
||||
.initialize();
|
||||
|
||||
Collection<ConsumerConfig> consumers = ApplicationModel.getConfigManager().getConsumers();
|
||||
Assertions.assertEquals(1, consumers.size());
|
||||
Assertions.assertEquals(consumerConfig, consumers.iterator().next());
|
||||
Assertions.assertEquals(false, consumerConfig.isCheck());
|
||||
Assertions.assertEquals("demoB", consumerConfig.getGroup());
|
||||
Assertions.assertEquals(10, consumerConfig.getThreads());
|
||||
} finally {
|
||||
SysProps.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigBySingularId() {
|
||||
// override success
|
||||
SysProps.setProperty("dubbo.consumer.group", "demoA");
|
||||
SysProps.setProperty("dubbo.consumer.threads", "15");
|
||||
// ignore singular format: dubbo.{tag-name}.{config-id}.{config-item}={config-value}
|
||||
SysProps.setProperty("dubbo.consumer.consumerA.check", "false");
|
||||
SysProps.setProperty("dubbo.consumer.consumerA.group", "demoB");
|
||||
SysProps.setProperty("dubbo.consumer.consumerA.threads", "10");
|
||||
|
||||
try {
|
||||
ConsumerConfig consumerConfig = new ConsumerConfig();
|
||||
consumerConfig.setId("consumerA");
|
||||
consumerConfig.setGroup("groupA");
|
||||
consumerConfig.setThreads(20);
|
||||
consumerConfig.setCheck(true);
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("demo-app")
|
||||
.consumer(consumerConfig)
|
||||
.initialize();
|
||||
|
||||
Collection<ConsumerConfig> consumers = ApplicationModel.getConfigManager().getConsumers();
|
||||
Assertions.assertEquals(1, consumers.size());
|
||||
Assertions.assertEquals(consumerConfig, consumers.iterator().next());
|
||||
Assertions.assertEquals(true, consumerConfig.isCheck());
|
||||
Assertions.assertEquals("demoA", consumerConfig.getGroup());
|
||||
Assertions.assertEquals(15, consumerConfig.getThreads());
|
||||
} finally {
|
||||
SysProps.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigByDubboProps() {
|
||||
Map props = new HashMap();
|
||||
props.put("dubbo.consumers.consumerA.check", "false");
|
||||
props.put("dubbo.consumers.consumerA.group", "demo");
|
||||
props.put("dubbo.consumers.consumerA.threads", "10");
|
||||
ConfigUtils.getProperties().putAll(props);
|
||||
|
||||
try {
|
||||
ConsumerConfig consumerConfig = new ConsumerConfig();
|
||||
consumerConfig.setId("consumerA");
|
||||
//
|
||||
consumerConfig.setGroup("groupA");
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("demo-app")
|
||||
.consumer(consumerConfig)
|
||||
.initialize();
|
||||
|
||||
Collection<ConsumerConfig> consumers = ApplicationModel.getConfigManager().getConsumers();
|
||||
Assertions.assertEquals(1, consumers.size());
|
||||
Assertions.assertEquals(consumerConfig, consumers.iterator().next());
|
||||
Assertions.assertEquals(false, consumerConfig.isCheck());
|
||||
Assertions.assertEquals("groupA", consumerConfig.getGroup());
|
||||
Assertions.assertEquals(10, consumerConfig.getThreads());
|
||||
} finally {
|
||||
props.keySet().forEach(ConfigUtils.getProperties()::remove);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReferenceAndConsumerConfigOverlay() {
|
||||
SysProps.setProperty("dubbo.consumer.group", "demo");
|
||||
SysProps.setProperty("dubbo.consumer.threads", "12");
|
||||
SysProps.setProperty("dubbo.consumer.timeout", "1234");
|
||||
SysProps.setProperty("dubbo.consumer.init", "false");
|
||||
SysProps.setProperty("dubbo.consumer.check", "false");
|
||||
SysProps.setProperty("dubbo.registry.address", "N/A");
|
||||
|
||||
try {
|
||||
ReferenceConfig referenceConfig = new ReferenceConfig();
|
||||
referenceConfig.setInterface(DemoService.class);
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("demo-app")
|
||||
.reference(referenceConfig)
|
||||
.initialize();
|
||||
|
||||
Assertions.assertEquals("demo", referenceConfig.getGroup());
|
||||
Assertions.assertEquals(1234, referenceConfig.getTimeout());
|
||||
Assertions.assertEquals(false, referenceConfig.isInit());
|
||||
Assertions.assertEquals(false, referenceConfig.isCheck());
|
||||
} finally {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaData() {
|
||||
ConsumerConfig consumerConfig = new ConsumerConfig();
|
||||
Map<String, String> metaData = consumerConfig.getMetaData();
|
||||
Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: "+metaData);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,11 +21,19 @@ 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.provider.impl.DemoServiceImpl;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -71,6 +79,16 @@ public class MethodConfigTest {
|
|||
arguments = {@Argument(index = ARGUMENTS_INDEX, callback = ARGUMENTS_CALLBACK, type = ARGUMENTS_TYPE)})})
|
||||
private String testField;
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() {
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
SysProps.clear();
|
||||
}
|
||||
|
||||
//TODO remove this test
|
||||
@Test
|
||||
public void testStaticConstructor() throws NoSuchFieldException {
|
||||
|
|
@ -161,14 +179,14 @@ public class MethodConfigTest {
|
|||
assertThat(method.getSticky(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
//@Test
|
||||
public void testOnreturn() throws Exception {
|
||||
MethodConfig method = new MethodConfig();
|
||||
method.setOnreturn("on-return-object");
|
||||
assertThat(method.getOnreturn(), equalTo((Object) "on-return-object"));
|
||||
Map<String, Object> attribute = new HashMap<String, Object>();
|
||||
MethodConfig.appendAttributes(attribute, method);
|
||||
assertThat(attribute, hasEntry((Object) ON_RETURN_INSTANCE_KEY, (Object) "on-return-object"));
|
||||
assertThat(method.getOnreturn(), equalTo("on-return-object"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
MethodConfig.appendAttributes(attributes, method);
|
||||
assertThat(attributes, hasEntry(ON_RETURN_INSTANCE_KEY, "on-return-object"));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
MethodConfig.appendParameters(parameters, method);
|
||||
assertThat(parameters.size(), is(0));
|
||||
|
|
@ -179,22 +197,22 @@ public class MethodConfigTest {
|
|||
MethodConfig method = new MethodConfig();
|
||||
method.setOnreturnMethod("on-return-method");
|
||||
assertThat(method.getOnreturnMethod(), equalTo("on-return-method"));
|
||||
Map<String, Object> attribute = new HashMap<String, Object>();
|
||||
MethodConfig.appendAttributes(attribute, method);
|
||||
assertThat(attribute, hasEntry((Object) ON_RETURN_METHOD_KEY, (Object) "on-return-method"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
MethodConfig.appendAttributes(attributes, method);
|
||||
assertThat(attributes, hasEntry((Object) ON_RETURN_METHOD_KEY, (Object) "on-return-method"));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
MethodConfig.appendParameters(parameters, method);
|
||||
assertThat(parameters.size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
//@Test
|
||||
public void testOnthrow() throws Exception {
|
||||
MethodConfig method = new MethodConfig();
|
||||
method.setOnthrow("on-throw-object");
|
||||
assertThat(method.getOnthrow(), equalTo((Object) "on-throw-object"));
|
||||
Map<String, Object> attribute = new HashMap<String, Object>();
|
||||
MethodConfig.appendAttributes(attribute, method);
|
||||
assertThat(attribute, hasEntry((Object) ON_THROW_INSTANCE_KEY, (Object) "on-throw-object"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
MethodConfig.appendAttributes(attributes, method);
|
||||
assertThat(attributes, hasEntry((Object) ON_THROW_INSTANCE_KEY, (Object) "on-throw-object"));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
MethodConfig.appendParameters(parameters, method);
|
||||
assertThat(parameters.size(), is(0));
|
||||
|
|
@ -205,22 +223,22 @@ public class MethodConfigTest {
|
|||
MethodConfig method = new MethodConfig();
|
||||
method.setOnthrowMethod("on-throw-method");
|
||||
assertThat(method.getOnthrowMethod(), equalTo("on-throw-method"));
|
||||
Map<String, Object> attribute = new HashMap<String, Object>();
|
||||
MethodConfig.appendAttributes(attribute, method);
|
||||
assertThat(attribute, hasEntry((Object) ON_THROW_METHOD_KEY, (Object) "on-throw-method"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
MethodConfig.appendAttributes(attributes, method);
|
||||
assertThat(attributes, hasEntry((Object) ON_THROW_METHOD_KEY, (Object) "on-throw-method"));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
MethodConfig.appendParameters(parameters, method);
|
||||
assertThat(parameters.size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
//@Test
|
||||
public void testOninvoke() throws Exception {
|
||||
MethodConfig method = new MethodConfig();
|
||||
method.setOninvoke("on-invoke-object");
|
||||
assertThat(method.getOninvoke(), equalTo((Object) "on-invoke-object"));
|
||||
Map<String, Object> attribute = new HashMap<String, Object>();
|
||||
MethodConfig.appendAttributes(attribute, method);
|
||||
assertThat(attribute, hasEntry((Object) ON_INVOKE_INSTANCE_KEY, (Object) "on-invoke-object"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
MethodConfig.appendAttributes(attributes, method);
|
||||
assertThat(attributes, hasEntry((Object) ON_INVOKE_INSTANCE_KEY, (Object) "on-invoke-object"));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
MethodConfig.appendParameters(parameters, method);
|
||||
assertThat(parameters.size(), is(0));
|
||||
|
|
@ -231,9 +249,9 @@ public class MethodConfigTest {
|
|||
MethodConfig method = new MethodConfig();
|
||||
method.setOninvokeMethod("on-invoke-method");
|
||||
assertThat(method.getOninvokeMethod(), equalTo("on-invoke-method"));
|
||||
Map<String, Object> attribute = new HashMap<String, Object>();
|
||||
MethodConfig.appendAttributes(attribute, method);
|
||||
assertThat(attribute, hasEntry((Object) ON_INVOKE_METHOD_KEY, (Object) "on-invoke-method"));
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
MethodConfig.appendAttributes(attributes, method);
|
||||
assertThat(attributes, hasEntry((Object) ON_INVOKE_METHOD_KEY, (Object) "on-invoke-method"));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
MethodConfig.appendParameters(parameters, method);
|
||||
assertThat(parameters.size(), is(0));
|
||||
|
|
@ -245,4 +263,83 @@ public class MethodConfigTest {
|
|||
method.setReturn(true);
|
||||
assertThat(method.isReturn(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideMethodConfig() {
|
||||
|
||||
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");
|
||||
|
||||
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 {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideMethodConfigOfService() {
|
||||
|
||||
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 +".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 {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaData() {
|
||||
MethodConfig methodConfig = new MethodConfig();
|
||||
Map<String, String> metaData = methodConfig.getMetaData();
|
||||
Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: "+metaData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.dubbo.config;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
|
@ -38,7 +39,7 @@ public class ModuleConfigTest {
|
|||
ModuleConfig module = new ModuleConfig();
|
||||
module.setName("module-name");
|
||||
assertThat(module.getName(), equalTo("module-name"));
|
||||
assertThat(module.getId(), equalTo("module-name"));
|
||||
assertThat(module.getId(), equalTo(null));
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
ModuleConfig.appendParameters(parameters, module);
|
||||
assertThat(parameters, hasEntry("module", "module-name"));
|
||||
|
|
@ -101,4 +102,11 @@ public class ModuleConfigTest {
|
|||
module.setDefault(true);
|
||||
assertThat(module.isDefault(), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaData() {
|
||||
MonitorConfig config = new MonitorConfig();
|
||||
Map<String, String> metaData = config.getMetaData();
|
||||
Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: "+metaData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.dubbo.config;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
|
@ -104,4 +105,11 @@ public class MonitorConfigTest {
|
|||
monitor.setInterval("100");
|
||||
assertThat(monitor.getInterval(), equalTo("100"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaData() {
|
||||
MonitorConfig config = new MonitorConfig();
|
||||
Map<String, String> metaData = config.getMetaData();
|
||||
Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: "+metaData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,14 @@
|
|||
|
||||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
|
@ -30,14 +36,25 @@ import static org.hamcrest.Matchers.is;
|
|||
|
||||
public class ProtocolConfigTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
SysProps.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testName() throws Exception {
|
||||
ProtocolConfig protocol = new ProtocolConfig();
|
||||
protocol.setName("name");
|
||||
String protocolName = "xprotocol";
|
||||
protocol.setName(protocolName);
|
||||
Map<String, String> parameters = new HashMap<String, String>();
|
||||
ProtocolConfig.appendParameters(parameters, protocol);
|
||||
assertThat(protocol.getName(), equalTo("name"));
|
||||
assertThat(protocol.getId(), equalTo("name"));
|
||||
assertThat(protocol.getName(), equalTo(protocolName));
|
||||
assertThat(protocol.getId(), equalTo(null));
|
||||
assertThat(parameters.isEmpty(), is(true));
|
||||
}
|
||||
|
||||
|
|
@ -201,4 +218,151 @@ public class ProtocolConfigTest {
|
|||
protocol.setExtension("extension");
|
||||
assertThat(protocol.getExtension(), equalTo("extension"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaData() {
|
||||
ProtocolConfig config = new ProtocolConfig();
|
||||
Map<String, String> metaData = config.getMetaData();
|
||||
Assertions.assertEquals(0, metaData.size(), "actual: "+metaData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideEmptyConfig() {
|
||||
//dubbo.protocol.name=rest
|
||||
//dubbo.protocol.port=1234
|
||||
SysProps.setProperty("dubbo.protocol.name", "rest");
|
||||
SysProps.setProperty("dubbo.protocol.port", "1234");
|
||||
|
||||
try {
|
||||
ProtocolConfig protocolConfig = new ProtocolConfig();
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("test-app")
|
||||
.protocol(protocolConfig)
|
||||
.initialize();
|
||||
|
||||
Assertions.assertEquals("rest", protocolConfig.getName());
|
||||
Assertions.assertEquals(1234, protocolConfig.getPort());
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigByName() {
|
||||
SysProps.setProperty("dubbo.protocols.rest.port", "1234");
|
||||
|
||||
try {
|
||||
ProtocolConfig protocolConfig = new ProtocolConfig();
|
||||
protocolConfig.setName("rest");
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("test-app")
|
||||
.protocol(protocolConfig)
|
||||
.initialize();
|
||||
|
||||
Assertions.assertEquals("rest", protocolConfig.getName());
|
||||
Assertions.assertEquals(1234, protocolConfig.getPort());
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigById() {
|
||||
SysProps.setProperty("dubbo.protocols.rest1.name", "rest");
|
||||
SysProps.setProperty("dubbo.protocols.rest1.port", "1234");
|
||||
|
||||
try {
|
||||
ProtocolConfig protocolConfig = new ProtocolConfig();
|
||||
protocolConfig.setName("xxx");
|
||||
protocolConfig.setId("rest1");
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("test-app")
|
||||
.protocol(protocolConfig)
|
||||
.initialize();
|
||||
|
||||
Assertions.assertEquals("rest", protocolConfig.getName());
|
||||
Assertions.assertEquals(1234, protocolConfig.getPort());
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateConfigFromPropsWithId() {
|
||||
SysProps.setProperty("dubbo.protocols.rest1.name", "rest");
|
||||
SysProps.setProperty("dubbo.protocols.rest1.port", "1234");
|
||||
SysProps.setProperty("dubbo.protocol.name", "dubbo"); // ignore
|
||||
SysProps.setProperty("dubbo.protocol.port", "2346");
|
||||
|
||||
try {
|
||||
|
||||
DubboBootstrap bootstrap = DubboBootstrap.getInstance();
|
||||
bootstrap.application("test-app")
|
||||
.initialize();
|
||||
|
||||
ConfigManager configManager = bootstrap.getConfigManager();
|
||||
Collection<ProtocolConfig> protocols = configManager.getProtocols();
|
||||
Assertions.assertEquals(1, protocols.size());
|
||||
|
||||
ProtocolConfig protocol = configManager.getProtocol("rest1").get();
|
||||
|
||||
Assertions.assertEquals("rest", protocol.getName());
|
||||
Assertions.assertEquals(1234, protocol.getPort());
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateConfigFromPropsWithName() {
|
||||
SysProps.setProperty("dubbo.protocols.rest.port", "1234");
|
||||
SysProps.setProperty("dubbo.protocol.name", "dubbo"); // ignore
|
||||
SysProps.setProperty("dubbo.protocol.port", "2346");
|
||||
|
||||
try {
|
||||
|
||||
DubboBootstrap bootstrap = DubboBootstrap.getInstance();
|
||||
bootstrap.application("test-app")
|
||||
.initialize();
|
||||
|
||||
ConfigManager configManager = bootstrap.getConfigManager();
|
||||
Collection<ProtocolConfig> protocols = configManager.getProtocols();
|
||||
Assertions.assertEquals(1, protocols.size());
|
||||
|
||||
ProtocolConfig protocol = configManager.getProtocol("rest").get();
|
||||
|
||||
Assertions.assertEquals("rest", protocol.getName());
|
||||
Assertions.assertEquals(1234, protocol.getPort());
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDefaultConfigFromProps() {
|
||||
SysProps.setProperty("dubbo.protocol.name", "rest");
|
||||
SysProps.setProperty("dubbo.protocol.port", "2346");
|
||||
String protocolId = "rest-protocol";
|
||||
SysProps.setProperty("dubbo.protocol.id", protocolId); // Allow override config id from props
|
||||
|
||||
try {
|
||||
|
||||
DubboBootstrap bootstrap = DubboBootstrap.getInstance();
|
||||
bootstrap.application("test-app")
|
||||
.initialize();
|
||||
|
||||
ConfigManager configManager = bootstrap.getConfigManager();
|
||||
Collection<ProtocolConfig> protocols = configManager.getProtocols();
|
||||
Assertions.assertEquals(1, protocols.size());
|
||||
|
||||
ProtocolConfig protocol = configManager.getProtocol("rest").get();
|
||||
Assertions.assertEquals("rest", protocol.getName());
|
||||
Assertions.assertEquals(2346, protocol.getPort());
|
||||
Assertions.assertEquals(protocolId, protocol.getId());
|
||||
|
||||
ProtocolConfig protocolConfig = configManager.getProtocol(protocolId).get();
|
||||
|
||||
} finally {
|
||||
DubboBootstrap.getInstance().stop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.dubbo.config;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
@ -216,4 +217,11 @@ public class ProviderConfigTest {
|
|||
provider.setWait(10);
|
||||
assertThat(provider.getWait(), equalTo(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaData() {
|
||||
ProtocolConfig config = new ProtocolConfig();
|
||||
Map<String, String> metaData = config.getMetaData();
|
||||
Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: "+metaData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ 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.provider.impl.DemoServiceImpl;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.curator.test.TestingServer;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
|
@ -33,6 +33,8 @@ import org.junit.jupiter.api.Disabled;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
|
||||
import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
|
||||
|
|
@ -43,7 +45,7 @@ public class ReferenceConfigTest {
|
|||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
int zkServerPort = NetUtils.getAvailablePort(NetUtils.getRandomPort());
|
||||
this.zkServer = new TestingServer(zkServerPort, true);
|
||||
this.zkServer.start();
|
||||
|
|
@ -52,8 +54,8 @@ public class ReferenceConfigTest {
|
|||
|
||||
@AfterEach
|
||||
public void tearDown() throws IOException {
|
||||
DubboBootstrap.reset();
|
||||
zkServer.stop();
|
||||
ApplicationModel.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -61,6 +63,7 @@ public class ReferenceConfigTest {
|
|||
public void testInjvm() throws Exception {
|
||||
ApplicationConfig application = new ApplicationConfig();
|
||||
application.setName("test-protocol-random-port");
|
||||
application.setEnableFileCache(false);
|
||||
ApplicationModel.getConfigManager().setApplication(application);
|
||||
|
||||
RegistryConfig registry = new RegistryConfig();
|
||||
|
|
@ -101,9 +104,10 @@ public class ReferenceConfigTest {
|
|||
* unit test for dubbo-1765
|
||||
*/
|
||||
@Test
|
||||
public void testReferenceRetry() {
|
||||
public void test1ReferenceRetry() {
|
||||
ApplicationConfig application = new ApplicationConfig();
|
||||
application.setName("test-reference-retry");
|
||||
application.setEnableFileCache(false);
|
||||
ApplicationModel.getConfigManager().setApplication(application);
|
||||
|
||||
RegistryConfig registry = new RegistryConfig();
|
||||
|
|
@ -149,6 +153,44 @@ public class ReferenceConfigTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaData() {
|
||||
ReferenceConfig config = new ReferenceConfig();
|
||||
Map<String, String> metaData = config.getMetaData();
|
||||
Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: "+metaData);
|
||||
|
||||
// test merged and override consumer attributes
|
||||
ConsumerConfig consumerConfig = new ConsumerConfig();
|
||||
consumerConfig.setAsync(true);
|
||||
consumerConfig.setActives(10);
|
||||
config.setConsumer(consumerConfig);
|
||||
config.setAsync(false);// override
|
||||
|
||||
metaData = config.getMetaData();
|
||||
Assertions.assertEquals(2, metaData.size());
|
||||
Assertions.assertEquals("" + consumerConfig.getActives(), metaData.get("actives"));
|
||||
Assertions.assertEquals("" + config.isAsync(), metaData.get("async"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPrefixes() {
|
||||
|
||||
ReferenceConfig referenceConfig = new ReferenceConfig();
|
||||
referenceConfig.setInterface(DemoService.class);
|
||||
|
||||
List<String> prefixes = referenceConfig.getPrefixes();
|
||||
Assertions.assertTrue(prefixes.contains("dubbo.reference." + referenceConfig.getInterface()));
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
referenceConfig.getPrefixes();
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
System.out.println("ReferenceConfig get prefixes cost: " + (end - start));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructWithReferenceAnnotation() throws NoSuchFieldException {
|
||||
Reference reference = getClass().getDeclaredField("innerTest").getAnnotation(Reference.class);
|
||||
|
|
|
|||
|
|
@ -17,12 +17,16 @@
|
|||
|
||||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.utils.UrlUtils;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
|
@ -38,6 +42,12 @@ import static org.hamcrest.Matchers.hasKey;
|
|||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
public class RegistryConfigTest {
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
SysProps.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProtocol() throws Exception {
|
||||
RegistryConfig registry = new RegistryConfig();
|
||||
|
|
@ -192,6 +202,35 @@ public class RegistryConfigTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testMetaData() {
|
||||
RegistryConfig config = new RegistryConfig();
|
||||
Map<String, String> metaData = config.getMetaData();
|
||||
Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: "+metaData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverrideConfigBySystemProps() {
|
||||
|
||||
SysProps.setProperty("dubbo.registry.address", "zookeeper://${zookeeper.address}:${zookeeper.port}");
|
||||
SysProps.setProperty("dubbo.registry.useAsConfigCenter", "false");
|
||||
SysProps.setProperty("dubbo.registry.useAsMetadataCenter", "false");
|
||||
SysProps.setProperty("zookeeper.address", "localhost");
|
||||
SysProps.setProperty("zookeeper.port", "2188");
|
||||
|
||||
try {
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application("demo-app")
|
||||
.initialize();
|
||||
|
||||
Collection<RegistryConfig> registries = ApplicationModel.getConfigManager().getRegistries();
|
||||
Assertions.assertEquals(1, registries.size());
|
||||
RegistryConfig registryConfig = registries.iterator().next();
|
||||
Assertions.assertEquals("zookeeper://localhost:2188", registryConfig.getAddress());
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
public void testPreferredWithTrueValue() {
|
||||
RegistryConfig registry = new RegistryConfig();
|
||||
registry.setPreferred(true);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import org.apache.dubbo.registry.Registry;
|
|||
import org.apache.dubbo.rpc.Exporter;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Protocol;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
|
@ -38,6 +39,7 @@ import org.junit.jupiter.api.Test;
|
|||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
|
||||
|
|
@ -78,6 +80,8 @@ public class ServiceConfigTest {
|
|||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
ApplicationModel.getConfigManager().clear();
|
||||
|
||||
MockProtocol2.delegate = protocolDelegate;
|
||||
MockRegistryFactory2.registry = registryDelegate;
|
||||
Mockito.when(protocolDelegate.export(Mockito.any(Invoker.class))).thenReturn(exporter);
|
||||
|
|
@ -126,12 +130,11 @@ public class ServiceConfigTest {
|
|||
delayService.setMethods(Collections.singletonList(method));
|
||||
delayService.setDelay(100);
|
||||
|
||||
// ApplicationModel.getConfigManager().clear();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
// ApplicationModel.getConfigManager().clear();
|
||||
ApplicationModel.getConfigManager().clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -281,4 +284,24 @@ public class ServiceConfigTest {
|
|||
Assertions.assertNotNull(service.toUrl().getApplication());
|
||||
Assertions.assertEquals("app", service.toUrl().getApplication());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaData() {
|
||||
// test new instance
|
||||
ServiceConfig config = new ServiceConfig();
|
||||
Map<String, String> metaData = config.getMetaData();
|
||||
Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: " + metaData);
|
||||
|
||||
// test merged and override provider attributes
|
||||
ProviderConfig providerConfig = new ProviderConfig();
|
||||
providerConfig.setAsync(true);
|
||||
providerConfig.setActives(10);
|
||||
config.setProvider(providerConfig);
|
||||
config.setAsync(false);// override
|
||||
|
||||
metaData = config.getMetaData();
|
||||
Assertions.assertEquals(2, metaData.size());
|
||||
Assertions.assertEquals("" + providerConfig.getActives(), metaData.get("actives"));
|
||||
Assertions.assertEquals("" + config.isAsync(), metaData.get("async"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Use to set and clear System property
|
||||
*/
|
||||
public class SysProps {
|
||||
|
||||
private static Map<String, String> map = new LinkedHashMap<String, String>();
|
||||
|
||||
public static void reset() {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
public static void setProperty(String key, String value) {
|
||||
map.put(key, value);
|
||||
System.setProperty(key, value);
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
for (String key : map.keySet()) {
|
||||
System.clearProperty(key);
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,18 +17,21 @@
|
|||
package org.apache.dubbo.config.bootstrap;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.config.configcenter.wrapper.CompositeDynamicConfiguration;
|
||||
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.api.DemoService;
|
||||
import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
import org.apache.dubbo.config.SysProps;
|
||||
import org.apache.dubbo.monitor.MonitorService;
|
||||
import org.apache.dubbo.registry.RegistryService;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
|
@ -58,23 +61,28 @@ public class DubboBootstrapTest {
|
|||
|
||||
@BeforeAll
|
||||
public static void setUp(@TempDir Path folder) {
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
dubboProperties = folder.resolve(CommonConstants.DUBBO_PROPERTIES_KEY).toFile();
|
||||
System.setProperty(CommonConstants.DUBBO_PROPERTIES_KEY, dubboProperties.getAbsolutePath());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDown() {
|
||||
System.clearProperty(CommonConstants.DUBBO_PROPERTIES_KEY);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() throws IOException {
|
||||
ApplicationModel.reset();
|
||||
public void afterEach() throws IOException {
|
||||
DubboBootstrap.reset();
|
||||
SysProps.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkApplication() {
|
||||
System.setProperty("dubbo.application.name", "demo");
|
||||
SysProps.setProperty("dubbo.application.name", "demo");
|
||||
ApplicationConfig applicationConfig = new ApplicationConfig();
|
||||
applicationConfig.refresh();
|
||||
Assertions.assertEquals("demo", applicationConfig.getName());
|
||||
System.clearProperty("dubbo.application.name");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -103,13 +111,21 @@ public class DubboBootstrapTest {
|
|||
|
||||
@Test
|
||||
public void testLoadRegistries() {
|
||||
System.setProperty("dubbo.registry.address", "addr1");
|
||||
AbstractInterfaceConfigTest.InterfaceConfig interfaceConfig = new AbstractInterfaceConfigTest.InterfaceConfig();
|
||||
// FIXME: now we need to check first, then load
|
||||
interfaceConfig.setApplication(new ApplicationConfig("testLoadRegistries"));
|
||||
interfaceConfig.checkRegistry();
|
||||
ApplicationModel.getEnvironment().setDynamicConfiguration(new CompositeDynamicConfiguration());
|
||||
List<URL> urls = ConfigValidationUtils.loadRegistries(interfaceConfig, true);
|
||||
SysProps.setProperty("dubbo.registry.address", "addr1");
|
||||
|
||||
ServiceConfig serviceConfig = new ServiceConfig();
|
||||
serviceConfig.setInterface(DemoService.class);
|
||||
serviceConfig.setRef(new DemoServiceImpl());
|
||||
serviceConfig.setApplication(new ApplicationConfig("testLoadRegistries"));
|
||||
|
||||
// load configs from props
|
||||
DubboBootstrap.getInstance()
|
||||
.initialize();
|
||||
|
||||
serviceConfig.refresh();
|
||||
|
||||
//ApplicationModel.getEnvironment().setDynamicConfiguration(new CompositeDynamicConfiguration());
|
||||
List<URL> urls = ConfigValidationUtils.loadRegistries(serviceConfig, true);
|
||||
Assertions.assertEquals(1, urls.size());
|
||||
URL url = urls.get(0);
|
||||
Assertions.assertEquals("registry", url.getProtocol());
|
||||
|
|
@ -124,8 +140,8 @@ public class DubboBootstrapTest {
|
|||
|
||||
@Test
|
||||
public void testLoadMonitor() {
|
||||
System.setProperty("dubbo.monitor.address", "monitor-addr:12080");
|
||||
System.setProperty("dubbo.monitor.protocol", "monitor");
|
||||
SysProps.setProperty("dubbo.monitor.address", "monitor-addr:12080");
|
||||
SysProps.setProperty("dubbo.monitor.protocol", "monitor");
|
||||
AbstractInterfaceConfigTest.InterfaceConfig interfaceConfig = new AbstractInterfaceConfigTest.InterfaceConfig();
|
||||
interfaceConfig.setApplication(new ApplicationConfig("testLoadMonitor"));
|
||||
interfaceConfig.setMonitor(new MonitorConfig());
|
||||
|
|
|
|||
|
|
@ -33,13 +33,6 @@ class AbstractBuilderTest {
|
|||
Assertions.assertEquals("id", builder.build().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void prefix() {
|
||||
Builder builder = new Builder();
|
||||
builder.prefix("prefix");
|
||||
Assertions.assertEquals("prefix", builder.build().getPrefix());
|
||||
}
|
||||
|
||||
@Test
|
||||
void appendParameter() {
|
||||
Map<String, String> source = null;
|
||||
|
|
@ -96,13 +89,11 @@ class AbstractBuilderTest {
|
|||
void build() {
|
||||
Builder builder = new Builder();
|
||||
builder.id("id");
|
||||
builder.prefix("prefix");
|
||||
|
||||
Config config = builder.build();
|
||||
Config config2 = builder.build();
|
||||
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
|
||||
Assertions.assertNotSame(config, config2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,13 +24,20 @@ import org.apache.dubbo.config.ModuleConfig;
|
|||
import org.apache.dubbo.config.MonitorConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
class AbstractInterfaceBuilderTest {
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
void local() {
|
||||
InterfaceBuilder builder = new InterfaceBuilder();
|
||||
|
|
@ -254,7 +261,7 @@ class AbstractInterfaceBuilderTest {
|
|||
ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
|
||||
|
||||
InterfaceBuilder builder = new InterfaceBuilder();
|
||||
builder.id("id").prefix("prefix").local(true).stub(false).monitor("123").proxy("mockproxyfactory").cluster("mockcluster")
|
||||
builder.id("id").local(true).stub(false).monitor("123").proxy("mockproxyfactory").cluster("mockcluster")
|
||||
.filter("mockfilter").listener("mockinvokerlistener").owner("owner").connections(1)
|
||||
.layer("layer").application(applicationConfig).module(moduleConfig)
|
||||
.addRegistry(registryConfig).registryIds("registryIds")
|
||||
|
|
@ -267,7 +274,6 @@ class AbstractInterfaceBuilderTest {
|
|||
InterfaceConfig config2 = builder.build();
|
||||
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
Assertions.assertEquals("true", config.getLocal());
|
||||
Assertions.assertEquals("false", config.getStub());
|
||||
Assertions.assertEquals(monitorConfig, config.getMonitor());
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ class AbstractMethodBuilderTest {
|
|||
@Test
|
||||
void build() {
|
||||
MethodBuilder builder = new MethodBuilder();
|
||||
builder.id("id").prefix("prefix").timeout(1).retries(2).actives(3).loadbalance("mockloadbalance").async(true)
|
||||
builder.id("id").timeout(1).retries(2).actives(3).loadbalance("mockloadbalance").async(true)
|
||||
.sent(false).mock("mock").merger("merger").cache("cache").validation("validation")
|
||||
.appendParameter("default.num", "one");
|
||||
|
||||
|
|
@ -158,7 +158,6 @@ class AbstractMethodBuilderTest {
|
|||
MethodConfig config2 = builder.build();
|
||||
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
Assertions.assertEquals(1, config.getTimeout());
|
||||
Assertions.assertEquals(2, config.getRetries());
|
||||
Assertions.assertEquals(3, config.getActives());
|
||||
|
|
|
|||
|
|
@ -111,13 +111,12 @@ class AbstractReferenceBuilderTest {
|
|||
void build() {
|
||||
ReferenceBuilder builder = new ReferenceBuilder();
|
||||
builder.check(true).init(false).generic(true).injvm(false).lazy(true).reconnect("reconnect").sticky(false)
|
||||
.version("version").group("group").id("id").prefix("prefix");
|
||||
.version("version").group("group").id("id");
|
||||
|
||||
ReferenceConfig config = builder.build();
|
||||
ReferenceConfig config2 = builder.build();
|
||||
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
Assertions.assertTrue(config.isCheck());
|
||||
Assertions.assertFalse(config.isInit());
|
||||
Assertions.assertTrue(config.isGeneric());
|
||||
|
|
|
|||
|
|
@ -197,13 +197,12 @@ class AbstractServiceBuilderTest {
|
|||
builder.version("version").group("group").deprecated(true).delay(1000).export(false).weight(1)
|
||||
.document("document").dynamic(true).token("token").accesslog("accesslog")
|
||||
.addProtocol(protocol).protocolIds("protocolIds").tag("tag").executes(100).register(false)
|
||||
.warmup(200).serialization("serialization").id("id").prefix("prefix");
|
||||
.warmup(200).serialization("serialization").id("id");
|
||||
|
||||
ServiceConfig config = builder.build();
|
||||
ServiceConfig config2 = builder.build();
|
||||
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
Assertions.assertEquals("version", config.getVersion());
|
||||
Assertions.assertEquals("group", config.getGroup());
|
||||
Assertions.assertEquals("document", config.getDocument());
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ class ApplicationBuilderTest {
|
|||
RegistryConfig registry = new RegistryConfig();
|
||||
|
||||
ApplicationBuilder builder = new ApplicationBuilder();
|
||||
builder.id("id").prefix("prefix").name("name").version("version").owner("owner").organization("organization").architecture("architecture")
|
||||
builder.id("id").name("name").version("version").owner("owner").organization("organization").architecture("architecture")
|
||||
.environment("develop").compiler("compiler").logger("log4j").monitor(monitor).isDefault(false)
|
||||
.dumpDirectory("dumpDirectory").qosEnable(true).qosPort(8080).qosAcceptForeignIp(false)
|
||||
.shutwait("shutwait").registryIds("registryIds").addRegistry(registry)
|
||||
|
|
@ -258,7 +258,6 @@ class ApplicationBuilderTest {
|
|||
ApplicationConfig config2 = builder.build();
|
||||
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
Assertions.assertEquals("name", config.getName());
|
||||
Assertions.assertEquals("version", config.getVersion());
|
||||
Assertions.assertEquals("owner", config.getOwner());
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ class ConfigCenterBuilderTest {
|
|||
builder.check(true).protocol("protocol").address("address").appConfigFile("appConfigFile")
|
||||
.cluster("cluster").configFile("configFile").group("group").highestPriority(false)
|
||||
.namespace("namespace").password("password").timeout(1000L).username("usernama")
|
||||
.appendParameter("default.num", "one").id("id").prefix("prefix");
|
||||
.appendParameter("default.num", "one").id("id");
|
||||
|
||||
ConfigCenterConfig config = builder.build();
|
||||
ConfigCenterConfig config2 = builder.build();
|
||||
|
|
@ -162,7 +162,6 @@ class ConfigCenterBuilderTest {
|
|||
Assertions.assertTrue(config.getParameters().containsKey("default.num"));
|
||||
Assertions.assertEquals("one", config.getParameters().get("default.num"));
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
|
||||
Assertions.assertNotSame(config, config2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ class ConsumerBuilderTest {
|
|||
void build() {
|
||||
ConsumerBuilder builder = new ConsumerBuilder();
|
||||
builder.isDefault(true).client("client").threadPool("threadPool").coreThreads(10).threads(100).queues(200)
|
||||
.shareConnections(300).id("id").prefix("prefix");
|
||||
.shareConnections(300).id("id");
|
||||
|
||||
ConsumerConfig config = builder.build();
|
||||
ConsumerConfig config2 = builder.build();
|
||||
|
|
@ -85,7 +85,6 @@ class ConsumerBuilderTest {
|
|||
Assertions.assertEquals("client", config.getClient());
|
||||
Assertions.assertEquals("threadPool", config.getThreadpool());
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
Assertions.assertEquals(10, config.getCorethreads());
|
||||
Assertions.assertEquals(100, config.getThreads());
|
||||
Assertions.assertEquals(200, config.getQueues());
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ class MetadataReportBuilderTest {
|
|||
MetadataReportBuilder builder = new MetadataReportBuilder();
|
||||
builder.address("address").username("username").password("password").timeout(1000).group("group")
|
||||
.retryTimes(1).retryPeriod(2).cycleReport(true).syncReport(false)
|
||||
.appendParameter("default.num", "one").id("id").prefix("prefix");
|
||||
.appendParameter("default.num", "one").id("id");
|
||||
|
||||
MetadataReportConfig config = builder.build();
|
||||
MetadataReportConfig config2 = builder.build();
|
||||
|
|
@ -145,7 +145,6 @@ class MetadataReportBuilderTest {
|
|||
Assertions.assertTrue(config.getParameters().containsKey("default.num"));
|
||||
Assertions.assertEquals("one", config.getParameters().get("default.num"));
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
Assertions.assertNotSame(config, config2);
|
||||
}
|
||||
}
|
||||
|
|
@ -113,7 +113,7 @@ class MonitorBuilderTest {
|
|||
MonitorBuilder builder = new MonitorBuilder();
|
||||
builder.protocol("protocol").address("address").group("group").interval("interval").isDefault(true)
|
||||
.password("password").username("username").version("version")
|
||||
.appendParameter("default.num", "one").id("id").prefix("prefix");
|
||||
.appendParameter("default.num", "one").id("id");
|
||||
|
||||
MonitorConfig config = builder.build();
|
||||
MonitorConfig config2 = builder.build();
|
||||
|
|
@ -129,7 +129,6 @@ class MonitorBuilderTest {
|
|||
Assertions.assertTrue(config.getParameters().containsKey("default.num"));
|
||||
Assertions.assertEquals("one", config.getParameters().get("default.num"));
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
Assertions.assertNotSame(config, config2);
|
||||
}
|
||||
}
|
||||
|
|
@ -293,7 +293,7 @@ class ProtocolBuilderTest {
|
|||
.dispatcher("mockdispatcher").networker("networker").server("server").client("client")
|
||||
.telnet("mocktelnethandler").prompt("prompt").status("mockstatuschecker").register(true).keepAlive(false)
|
||||
.optimizer("optimizer").extension("extension").isDefault(true)
|
||||
.appendParameter("default.num", "one").id("id").prefix("prefix");
|
||||
.appendParameter("default.num", "one").id("id");
|
||||
|
||||
ProtocolConfig config = builder.build();
|
||||
ProtocolConfig config2 = builder.build();
|
||||
|
|
@ -332,7 +332,6 @@ class ProtocolBuilderTest {
|
|||
Assertions.assertTrue(config.getParameters().containsKey("default.num"));
|
||||
Assertions.assertEquals("one", config.getParameters().get("default.num"));
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
Assertions.assertNotSame(config, config2);
|
||||
}
|
||||
}
|
||||
|
|
@ -192,7 +192,7 @@ class ProviderBuilderTest {
|
|||
.charset("utf-8").payload(6).buffer(1024).transporter("mocktransporter").exchanger("mockexchanger")
|
||||
.dispatcher("mockdispatcher").networker("networker").server("server").client("client")
|
||||
.telnet("mocktelnethandler").prompt("prompt").status("mockstatuschecker").wait(Integer.valueOf(1000))
|
||||
.isDefault(true).id("id").prefix("prefix");
|
||||
.isDefault(true).id("id");
|
||||
|
||||
ProviderConfig config = builder.build();
|
||||
ProviderConfig config2 = builder.build();
|
||||
|
|
@ -221,7 +221,6 @@ class ProviderBuilderTest {
|
|||
Assertions.assertEquals("mockstatuschecker", config.getStatus());
|
||||
Assertions.assertTrue(config.isDefault());
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
Assertions.assertNotSame(config, config2);
|
||||
}
|
||||
}
|
||||
|
|
@ -220,7 +220,7 @@ class RegistryBuilderTest {
|
|||
.transporter("transporter").server("server").client("client").cluster("cluster").group("group")
|
||||
.version("version").timeout(1000).session(2000).file("file").wait(Integer.valueOf(10)).isCheck(true)
|
||||
.isDynamic(false).register(true).subscribe(false).isDefault(true).simplified(false).extraKeys("A")
|
||||
.parameter("default.num", "one").id("id").prefix("prefix");
|
||||
.parameter("default.num", "one").id("id");
|
||||
|
||||
RegistryConfig config = builder.build();
|
||||
RegistryConfig config2 = builder.build();
|
||||
|
|
@ -250,7 +250,6 @@ class RegistryBuilderTest {
|
|||
Assertions.assertTrue(config.getParameters().containsKey("default.num"));
|
||||
Assertions.assertEquals("one", config.getParameters().get("default.num"));
|
||||
Assertions.assertEquals("id", config.getId());
|
||||
Assertions.assertEquals("prefix", config.getPrefix());
|
||||
Assertions.assertNotSame(config, config2);
|
||||
}
|
||||
}
|
||||
|
|
@ -28,6 +28,7 @@ import org.apache.dubbo.config.ProtocolConfig;
|
|||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
|
||||
|
|
@ -49,7 +50,7 @@ public class CacheTest {
|
|||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
// ApplicationModel.getConfigManager().clear();
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.config.ApplicationConfig;
|
|||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.config.bootstrap.EchoService;
|
||||
import org.apache.dubbo.config.bootstrap.EchoServiceImpl;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
|
|
@ -51,7 +52,7 @@ public class PublishingServiceDefinitionListenerTest {
|
|||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
String metadataType = DEFAULT_METADATA_STORAGE_TYPE;
|
||||
ConfigManager configManager = ApplicationModel.getConfigManager();
|
||||
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-demo-provider");
|
||||
|
|
@ -62,7 +63,7 @@ public class PublishingServiceDefinitionListenerTest {
|
|||
|
||||
@AfterEach
|
||||
public void reset() {
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ package org.apache.dubbo.config.url;
|
|||
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
|
@ -43,13 +43,13 @@ public class ExporterSideConfigUrlTest extends UrlTestBase {
|
|||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
initServConf();
|
||||
}
|
||||
|
||||
@AfterEach()
|
||||
public void teardown() {
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.config.utils;
|
|||
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.config.utils.service.FooService;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
|
@ -31,6 +32,7 @@ public class ReferenceConfigCacheTest {
|
|||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
DubboBootstrap.reset();
|
||||
MockReferenceConfig.setCounter(0);
|
||||
ReferenceConfigCache.CACHE_HOLDER.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.dubbo.metadata;
|
|||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.config.metadata.ConfigurableMetadataServiceExporter;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
|
|
@ -41,7 +42,7 @@ public class MetadataServiceExporterTest {
|
|||
|
||||
@BeforeAll
|
||||
public static void init() {
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
ApplicationModel.getConfigManager().setApplication(new ApplicationConfig("Test"));
|
||||
ApplicationModel.getConfigManager().addRegistry(new RegistryConfig("multicast://224.5.6.7:1234"));
|
||||
ApplicationModel.getConfigManager().addProtocol(new ProtocolConfig("injvm"));
|
||||
|
|
@ -49,8 +50,7 @@ public class MetadataServiceExporterTest {
|
|||
|
||||
@AfterAll
|
||||
public static void destroy() {
|
||||
ApplicationModel.getConfigManager().setApplication(null);
|
||||
ApplicationModel.reset();
|
||||
DubboBootstrap.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
dubbo.override.key2=properties
|
||||
dubbo.override.protocol=properties
|
||||
dubbo.override.protocol=properties
|
||||
dubbo.application.enable-file-cache=false
|
||||
|
|
@ -77,12 +77,24 @@
|
|||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-rpc-triple</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-rpc-injvm</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-rpc-rest</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-remoting-netty4</artifactId>
|
||||
|
|
|
|||
|
|
@ -21,5 +21,14 @@ package org.apache.dubbo.config.spring;
|
|||
*/
|
||||
public interface Constants {
|
||||
|
||||
/**
|
||||
* attributes of reference annotation
|
||||
*/
|
||||
String REFERENCE_PROPS = "referenceProps";
|
||||
|
||||
/**
|
||||
* Registration sources of the reference, may be xml file or annotation location
|
||||
*/
|
||||
String REFERENCE_SOURCES = "referenceSources";
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,9 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
|||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
|
@ -135,6 +137,9 @@ public class ReferenceBean<T> implements FactoryBean,
|
|||
//actual reference config
|
||||
private ReferenceConfig referenceConfig;
|
||||
|
||||
// Registration sources of this reference, may be xml file or annotation location
|
||||
private List<Map<String,Object>> sources = new ArrayList<>();
|
||||
|
||||
public ReferenceBean() {
|
||||
super();
|
||||
}
|
||||
|
|
@ -158,6 +163,30 @@ public class ReferenceBean<T> implements FactoryBean,
|
|||
this.setId(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create bean instance.
|
||||
* <p/>
|
||||
* When Spring searches beans by type, if Spring cannot determine the type of a factory bean, it may try to initialize it.
|
||||
* The ReferenceBean is also a FactoryBean.
|
||||
*
|
||||
* <p/>
|
||||
* In addition, if some ReferenceBeans are dependent on beans that are initialized very early,
|
||||
* and dubbo config beans are not ready yet, there will be many unexpected problems if initializing the dubbo reference immediately.
|
||||
*
|
||||
* <p/>
|
||||
* When it is initialized, only a lazy proxy object will be created,
|
||||
* and dubbo reference-related resources will not be initialized.
|
||||
* <br/>
|
||||
* In this way, the influence of Spring is eliminated, and the dubbo configuration initialization is controllable.
|
||||
*
|
||||
* <p/>
|
||||
* Dubbo config beans are initialized in DubboConfigInitializationPostProcessor.
|
||||
* <br/>
|
||||
* The actual references will be processing in DubboBootstrap.referServices().
|
||||
*
|
||||
* @see org.apache.dubbo.config.spring.context.DubboConfigInitializationPostProcessor
|
||||
* @see org.apache.dubbo.config.bootstrap.DubboBootstrap
|
||||
*/
|
||||
@Override
|
||||
public Object getObject() {
|
||||
if (lazyProxy == null) {
|
||||
|
|
@ -214,6 +243,9 @@ public class ReferenceBean<T> implements FactoryBean,
|
|||
Assert.notNull(this.actualInterface, "The actual interface of ReferenceBean is not initialized");
|
||||
this.interfaceName = actualInterface.getName();
|
||||
|
||||
// this.sources = (List<Map<String, Object>>) beanDefinition.getAttribute(Constants.REFERENCE_SOURCES);
|
||||
// Assert.notNull(this.sources, "The registration sources of this reference is empty");
|
||||
|
||||
ReferenceBeanManager referenceBeanManager = beanFactory.getBean(ReferenceBeanManager.BEAN_NAME, ReferenceBeanManager.class);
|
||||
referenceBeanManager.addReference(this);
|
||||
}
|
||||
|
|
@ -227,11 +259,6 @@ public class ReferenceBean<T> implements FactoryBean,
|
|||
// do nothing
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Object get() {
|
||||
return referenceConfig.get();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
|
@ -281,7 +308,7 @@ public class ReferenceBean<T> implements FactoryBean,
|
|||
}
|
||||
|
||||
/**
|
||||
* create lazy proxy for reference
|
||||
* Create lazy proxy for reference.
|
||||
*/
|
||||
private void createLazyProxy() {
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.dubbo.config.spring;
|
|||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.config.annotation.Service;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
import org.apache.dubbo.config.spring.context.event.ServiceBeanExportedEvent;
|
||||
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
|
|
@ -64,6 +65,7 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
|
|||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
//TODO remove SpringExtensionFactory.addApplicationContext();
|
||||
SpringExtensionFactory.addApplicationContext(applicationContext);
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +90,8 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
|
|||
setPath(getInterface());
|
||||
}
|
||||
}
|
||||
//register service bean and set bootstrap
|
||||
DubboBootstrap.getInstance().service(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.spring.beans.factory.annotation;
|
||||
|
||||
import org.apache.dubbo.config.annotation.Service;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* {@link Service} Annotation {@link BeanDefinitionRegistryPostProcessor Bean Definition Registry Post Processor}
|
||||
*
|
||||
* @since 2.5.8
|
||||
* @deprecated Recommend {@link ServiceClassPostProcessor} as the substitute
|
||||
*/
|
||||
@Deprecated
|
||||
public class ServiceAnnotationBeanPostProcessor extends ServiceClassPostProcessor {
|
||||
|
||||
public ServiceAnnotationBeanPostProcessor(String... packagesToScan) {
|
||||
this(Arrays.asList(packagesToScan));
|
||||
}
|
||||
|
||||
public ServiceAnnotationBeanPostProcessor(Collection<String> packagesToScan) {
|
||||
this(new LinkedHashSet<>(packagesToScan));
|
||||
}
|
||||
|
||||
public ServiceAnnotationBeanPostProcessor(Set<String> packagesToScan) {
|
||||
super(packagesToScan);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ package org.apache.dubbo.config.spring.beans.factory.annotation;
|
|||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.ArrayUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.MethodConfig;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.apache.dubbo.config.annotation.Method;
|
||||
|
|
@ -35,14 +36,12 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
|||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.config.SingletonBeanRegistry;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
|
|
@ -55,8 +54,6 @@ import org.springframework.core.env.Environment;
|
|||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collection;
|
||||
|
|
@ -87,7 +84,7 @@ import static org.springframework.util.ClassUtils.resolveClassName;
|
|||
* @see BeanDefinitionRegistryPostProcessor
|
||||
* @since 2.7.7
|
||||
*/
|
||||
public class ServiceClassPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware,
|
||||
public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware,
|
||||
ResourceLoaderAware, BeanClassLoaderAware {
|
||||
|
||||
private final static List<Class<? extends Annotation>> serviceAnnotationTypes = asList(
|
||||
|
|
@ -110,15 +107,15 @@ public class ServiceClassPostProcessor implements BeanDefinitionRegistryPostProc
|
|||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
public ServiceClassPostProcessor(String... packagesToScan) {
|
||||
public ServiceAnnotationPostProcessor(String... packagesToScan) {
|
||||
this(asList(packagesToScan));
|
||||
}
|
||||
|
||||
public ServiceClassPostProcessor(Collection<String> packagesToScan) {
|
||||
public ServiceAnnotationPostProcessor(Collection<String> packagesToScan) {
|
||||
this(new LinkedHashSet<>(packagesToScan));
|
||||
}
|
||||
|
||||
public ServiceClassPostProcessor(Set<String> packagesToScan) {
|
||||
public ServiceAnnotationPostProcessor(Set<String> packagesToScan) {
|
||||
this.packagesToScan = packagesToScan;
|
||||
}
|
||||
|
||||
|
|
@ -403,7 +400,7 @@ public class ServiceClassPostProcessor implements BeanDefinitionRegistryPostProc
|
|||
propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(serviceAnnotation, environment, ignoreAttributeNames));
|
||||
|
||||
//set config id, for ConfigManager cache key
|
||||
builder.addPropertyValue("id", beanName);
|
||||
//builder.addPropertyValue("id", beanName);
|
||||
// References "ref" property to annotated-@Service Bean
|
||||
addPropertyReference(builder, "ref", annotatedServiceBeanName);
|
||||
// Set interface
|
||||
|
|
@ -416,65 +413,59 @@ public class ServiceClassPostProcessor implements BeanDefinitionRegistryPostProc
|
|||
builder.addPropertyValue("methods", methodConfigs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link org.apache.dubbo.config.ProviderConfig} Bean reference
|
||||
*/
|
||||
String providerConfigBeanName = serviceAnnotationAttributes.getString("provider");
|
||||
if (StringUtils.hasText(providerConfigBeanName)) {
|
||||
addPropertyReference(builder, "provider", providerConfigBeanName);
|
||||
// convert provider to providerIds
|
||||
String providerConfigId = serviceAnnotationAttributes.getString("provider");
|
||||
if (StringUtils.hasText(providerConfigId)) {
|
||||
addPropertyValue(builder, "providerIds", providerConfigId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link org.apache.dubbo.config.MonitorConfig} Bean reference
|
||||
*/
|
||||
String monitorConfigBeanName = serviceAnnotationAttributes.getString("monitor");
|
||||
if (StringUtils.hasText(monitorConfigBeanName)) {
|
||||
addPropertyReference(builder, "monitor", monitorConfigBeanName);
|
||||
// Convert registry[] to registryIds
|
||||
String[] registryConfigIds = serviceAnnotationAttributes.getStringArray("registry");
|
||||
if (registryConfigIds != null && registryConfigIds.length > 0) {
|
||||
resolveStringArray(registryConfigIds);
|
||||
builder.addPropertyValue("registryIds", StringUtils.join(registryConfigIds, ','));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link org.apache.dubbo.config.ApplicationConfig} Bean reference
|
||||
*/
|
||||
String applicationConfigBeanName = serviceAnnotationAttributes.getString("application");
|
||||
if (StringUtils.hasText(applicationConfigBeanName)) {
|
||||
addPropertyReference(builder, "application", applicationConfigBeanName);
|
||||
// Convert protocol[] to protocolIds
|
||||
String[] protocolConfigIds = serviceAnnotationAttributes.getStringArray("protocol");
|
||||
if (protocolConfigIds != null && protocolConfigIds.length > 0) {
|
||||
resolveStringArray(protocolConfigIds);
|
||||
builder.addPropertyValue("protocolIds", StringUtils.join(protocolConfigIds, ','));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link org.apache.dubbo.config.ModuleConfig} Bean reference
|
||||
*/
|
||||
String moduleConfigBeanName = serviceAnnotationAttributes.getString("module");
|
||||
if (StringUtils.hasText(moduleConfigBeanName)) {
|
||||
addPropertyReference(builder, "module", moduleConfigBeanName);
|
||||
// TODO Could we ignore these attributes: applicatin/monitor/module ? Use global config
|
||||
// monitor reference
|
||||
String monitorConfigId = serviceAnnotationAttributes.getString("monitor");
|
||||
if (StringUtils.hasText(monitorConfigId)) {
|
||||
addPropertyReference(builder, "monitor", monitorConfigId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add {@link org.apache.dubbo.config.RegistryConfig} Bean reference
|
||||
*/
|
||||
String[] registryConfigBeanNames = serviceAnnotationAttributes.getStringArray("registry");
|
||||
|
||||
List<RuntimeBeanReference> registryRuntimeBeanReferences = toRuntimeBeanReferences(registryConfigBeanNames);
|
||||
|
||||
if (!registryRuntimeBeanReferences.isEmpty()) {
|
||||
builder.addPropertyValue("registries", registryRuntimeBeanReferences);
|
||||
// application reference
|
||||
String applicationConfigId = serviceAnnotationAttributes.getString("application");
|
||||
if (StringUtils.hasText(applicationConfigId)) {
|
||||
addPropertyReference(builder, "application", applicationConfigId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link org.apache.dubbo.config.ProtocolConfig} Bean reference
|
||||
*/
|
||||
String[] protocolConfigBeanNames = serviceAnnotationAttributes.getStringArray("protocol");
|
||||
|
||||
List<RuntimeBeanReference> protocolRuntimeBeanReferences = toRuntimeBeanReferences(protocolConfigBeanNames);
|
||||
|
||||
if (!protocolRuntimeBeanReferences.isEmpty()) {
|
||||
builder.addPropertyValue("protocols", protocolRuntimeBeanReferences);
|
||||
// module reference
|
||||
String moduleConfigId = serviceAnnotationAttributes.getString("module");
|
||||
if (StringUtils.hasText(moduleConfigId)) {
|
||||
addPropertyReference(builder, "module", moduleConfigId);
|
||||
}
|
||||
|
||||
return builder.getBeanDefinition();
|
||||
|
||||
}
|
||||
|
||||
private String[] resolveStringArray(String[] strs) {
|
||||
if (strs == null) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < strs.length; i++) {
|
||||
strs[i] = environment.resolvePlaceholders(strs[i]);
|
||||
}
|
||||
return strs;
|
||||
}
|
||||
|
||||
private List convertMethodConfigs(Object methodsAnnotation) {
|
||||
if (methodsAnnotation == null) {
|
||||
return Collections.EMPTY_LIST;
|
||||
|
|
@ -482,30 +473,16 @@ public class ServiceClassPostProcessor implements BeanDefinitionRegistryPostProc
|
|||
return MethodConfig.constructMethodConfig((Method[]) methodsAnnotation);
|
||||
}
|
||||
|
||||
private ManagedList<RuntimeBeanReference> toRuntimeBeanReferences(String... beanNames) {
|
||||
|
||||
ManagedList<RuntimeBeanReference> runtimeBeanReferences = new ManagedList<>();
|
||||
|
||||
if (!ObjectUtils.isEmpty(beanNames)) {
|
||||
|
||||
for (String beanName : beanNames) {
|
||||
|
||||
String resolvedBeanName = environment.resolvePlaceholders(beanName);
|
||||
|
||||
runtimeBeanReferences.add(new RuntimeBeanReference(resolvedBeanName));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return runtimeBeanReferences;
|
||||
|
||||
}
|
||||
|
||||
private void addPropertyReference(BeanDefinitionBuilder builder, String propertyName, String beanName) {
|
||||
String resolvedBeanName = environment.resolvePlaceholders(beanName);
|
||||
builder.addPropertyReference(propertyName, resolvedBeanName);
|
||||
}
|
||||
|
||||
private void addPropertyValue(BeanDefinitionBuilder builder, String propertyName, String value) {
|
||||
String resolvedBeanName = environment.resolvePlaceholders(value);
|
||||
builder.addPropertyValue(propertyName, resolvedBeanName);
|
||||
}
|
||||
|
||||
private Map<String, String> convertParameters(String[] parameters) {
|
||||
if (ArrayUtils.isEmpty(parameters)) {
|
||||
return null;
|
||||
|
|
@ -16,11 +16,10 @@
|
|||
*/
|
||||
package org.apache.dubbo.config.spring.beans.factory.config;
|
||||
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
|
||||
import com.alibaba.spring.beans.factory.config.GenericBeanPostProcessorAdapter;
|
||||
import org.apache.dubbo.config.Constants;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
|
|
@ -54,15 +53,13 @@ public class DubboConfigDefaultPropertyValueBeanPostProcessor extends GenericBea
|
|||
public static final String BEAN_NAME = "dubboConfigDefaultPropertyValueBeanPostProcessor";
|
||||
|
||||
protected void processBeforeInitialization(AbstractConfig dubboConfigBean, String beanName) throws BeansException {
|
||||
// [Feature] https://github.com/apache/dubbo/issues/5721
|
||||
setBeanNameAsDefaultValue(dubboConfigBean, "id", beanName);
|
||||
if (dubboConfigBean instanceof ProtocolConfig) {
|
||||
ProtocolConfig config = (ProtocolConfig) dubboConfigBean;
|
||||
if (StringUtils.isEmpty(config.getName())) {
|
||||
config.setName("dubbo");
|
||||
}
|
||||
} else {
|
||||
setBeanNameAsDefaultValue(dubboConfigBean, "name", beanName);
|
||||
// ignore auto generate bean name
|
||||
if (!beanName.contains("#")) {
|
||||
// [Feature] https://github.com/apache/dubbo/issues/5721
|
||||
setPropertyIfAbsent(dubboConfigBean, Constants.ID, beanName);
|
||||
|
||||
// beanName should not be used as config name, fix https://github.com/apache/dubbo/pull/7624
|
||||
//setPropertyIfAbsent(dubboConfigBean, "name", beanName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +68,7 @@ public class DubboConfigDefaultPropertyValueBeanPostProcessor extends GenericBea
|
|||
// DO NOTHING
|
||||
}
|
||||
|
||||
protected void setBeanNameAsDefaultValue(Object bean, String propertyName, String beanName) {
|
||||
protected void setPropertyIfAbsent(Object bean, String propertyName, String beanName) {
|
||||
|
||||
Class<?> beanClass = getTargetClass(bean);
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue