Merge branch 'apache-3.1' into apache-3.2
# Conflicts: # dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
This commit is contained in:
commit
ab10b8a189
|
|
@ -33,12 +33,15 @@ import org.apache.dubbo.rpc.RpcInvocation;
|
|||
import org.apache.dubbo.rpc.TimeoutCountDown;
|
||||
import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ENABLE_TIMEOUT_COUNTDOWN_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_APPLICATION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_ATTACHMENT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TIME_COUNTDOWN_KEY;
|
||||
|
||||
/**
|
||||
|
|
@ -95,13 +98,21 @@ public class ConsumerContextFilter implements ClusterFilter, ClusterFilter.Liste
|
|||
}
|
||||
|
||||
// pass default timeout set by end user (ReferenceConfig)
|
||||
Object countDown = context.getObjectAttachment(TIME_COUNTDOWN_KEY);
|
||||
Object countDown = RpcContext.getServerAttachment().getObjectAttachment(TIME_COUNTDOWN_KEY);
|
||||
if (countDown != null) {
|
||||
TimeoutCountDown timeoutCountDown = (TimeoutCountDown) countDown;
|
||||
if (timeoutCountDown.isExpired()) {
|
||||
return AsyncRpcResult.newDefaultAsyncResult(new RpcException(RpcException.TIMEOUT_TERMINATE,
|
||||
"No time left for making the following call: " + invocation.getServiceName() + "."
|
||||
+ invocation.getMethodName() + ", terminate directly."), invocation);
|
||||
String methodName = RpcUtils.getMethodName(invocation);
|
||||
// When the client has enabled the timeout-countdown function,
|
||||
// the subsequent calls launched by the Server side will be enabled by default,
|
||||
// and support to turn off the function on a node to get rid of the timeout control.
|
||||
if (invoker.getUrl().getMethodParameter(methodName, ENABLE_TIMEOUT_COUNTDOWN_KEY, true)) {
|
||||
context.setObjectAttachment(TIMEOUT_ATTACHMENT_KEY, countDown);
|
||||
|
||||
TimeoutCountDown timeoutCountDown = (TimeoutCountDown) countDown;
|
||||
if (timeoutCountDown.isExpired()) {
|
||||
return AsyncRpcResult.newDefaultAsyncResult(new RpcException(RpcException.TIMEOUT_TERMINATE,
|
||||
"No time left for making the following call: " + invocation.getServiceName() + "."
|
||||
+ invocation.getMethodName() + ", terminate directly."), invocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
RpcContext.removeClientResponseContext();
|
||||
|
|
|
|||
|
|
@ -120,7 +120,8 @@ public class JdkCompiler extends AbstractCompiler {
|
|||
Boolean result = compiler.getTask(null, javaFileManager, diagnosticCollector, options,
|
||||
null, Collections.singletonList(javaFileObject)).call();
|
||||
if (result == null || !result) {
|
||||
throw new IllegalStateException("Compilation failed. class: " + name + ", diagnostics: " + diagnosticCollector);
|
||||
throw new IllegalStateException("Compilation failed. class: " + name + ", diagnostics: "
|
||||
+ diagnosticCollector.getDiagnostics());
|
||||
}
|
||||
return classLoader.loadClass(name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ public class Environment extends LifecycleAdapter implements ApplicationExt {
|
|||
public void initialize() throws IllegalStateException {
|
||||
if (initialized.compareAndSet(false, true)) {
|
||||
this.propertiesConfiguration = new PropertiesConfiguration(scopeModel);
|
||||
this.systemConfiguration = new SystemConfiguration();
|
||||
this.systemConfiguration = new SystemConfiguration(scopeModel);
|
||||
this.environmentConfiguration = new EnvironmentConfiguration();
|
||||
this.externalConfiguration = new InmemoryConfiguration("ExternalConfig");
|
||||
this.appExternalConfiguration = new InmemoryConfiguration("AppExternalConfig");
|
||||
|
|
|
|||
|
|
@ -17,8 +17,18 @@
|
|||
package org.apache.dubbo.common.config;
|
||||
|
||||
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* FIXME: is this really necessary? PropertiesConfiguration should have already covered this:
|
||||
|
|
@ -28,8 +38,23 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
*/
|
||||
public class SystemConfiguration implements Configuration {
|
||||
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(SystemConfiguration.class);
|
||||
|
||||
private final Map<String, Object> cache = new ConcurrentHashMap<>();
|
||||
|
||||
private final ScheduledExecutorService sharedScheduledExecutor;
|
||||
|
||||
public SystemConfiguration(ScopeModel scopeModel) {
|
||||
sharedScheduledExecutor = ScopeModelUtil.getFrameworkModel(scopeModel).getBeanFactory()
|
||||
.getBean(FrameworkExecutorRepository.class).getSharedScheduledExecutor();
|
||||
sharedScheduledExecutor.scheduleWithFixedDelay(() -> {
|
||||
if (!cache.isEmpty()) {
|
||||
Set<String> keys = cache.keySet();
|
||||
keys.forEach((key) -> overwriteCache(key, System.getProperty(key)));
|
||||
}
|
||||
}, 60000, 60000, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getInternalProperty(String key) {
|
||||
if (cache.containsKey(key)) {
|
||||
|
|
@ -72,8 +97,14 @@ public class SystemConfiguration implements Configuration {
|
|||
}
|
||||
|
||||
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return (Map) System.getProperties();
|
||||
Properties properties = System.getProperties();
|
||||
Map<String, String> res = new ConcurrentHashMap<>(properties.size());
|
||||
try {
|
||||
res.putAll((Map) properties);
|
||||
} catch (Exception e) {
|
||||
logger.warn("System property get failed", e);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -664,47 +664,7 @@ public abstract class AbstractConfig implements Serializable {
|
|||
try {
|
||||
// check and init before do refresh
|
||||
preProcessRefresh();
|
||||
|
||||
Environment environment = getScopeModel().getModelEnvironment();
|
||||
List<Map<String, String>> configurationMaps = environment.getConfigurationMaps();
|
||||
|
||||
// Search props starts with PREFIX in order
|
||||
String preferredPrefix = null;
|
||||
List<String> prefixes = getPrefixes();
|
||||
for (String prefix : prefixes) {
|
||||
if (ConfigurationUtils.hasSubProperties(configurationMaps, prefix)) {
|
||||
preferredPrefix = prefix;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (preferredPrefix == null) {
|
||||
preferredPrefix = prefixes.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);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
String idOrName = "";
|
||||
if (StringUtils.hasText(this.getId())) {
|
||||
idOrName = "[id=" + this.getId() + "]";
|
||||
} else {
|
||||
String name = ReflectUtils.getProperty(this, "getName");
|
||||
if (StringUtils.hasText(name)) {
|
||||
idOrName = "[name=" + name + "]";
|
||||
}
|
||||
}
|
||||
logger.debug("Refreshing " + this.getClass().getSimpleName() + idOrName +
|
||||
" with prefix [" + preferredPrefix +
|
||||
"], extracted props: " + subProperties);
|
||||
}
|
||||
|
||||
assignProperties(this, environment, subProperties, subPropsConfiguration);
|
||||
|
||||
// process extra refresh of subclass, e.g. refresh method configs
|
||||
processExtraRefresh(preferredPrefix, subPropsConfiguration);
|
||||
|
||||
refreshWithPrefixes(getPrefixes(), getConfigMode());
|
||||
} catch (Exception e) {
|
||||
logger.error(COMMON_FAILED_OVERRIDE_FIELD, "", "", "Failed to override field value of config bean: " + this, e);
|
||||
throw new IllegalStateException("Failed to override field value of config bean: " + this, e);
|
||||
|
|
@ -714,12 +674,53 @@ public abstract class AbstractConfig implements Serializable {
|
|||
refreshed.set(true);
|
||||
}
|
||||
|
||||
private void assignProperties(Object obj, Environment environment, Map<String, String> properties, InmemoryConfiguration configuration) {
|
||||
protected void refreshWithPrefixes(List<String> prefixes, ConfigMode configMode) {
|
||||
Environment environment = getScopeModel().getModelEnvironment();
|
||||
List<Map<String, String>> configurationMaps = environment.getConfigurationMaps();
|
||||
|
||||
// Search props starts with PREFIX in order
|
||||
String preferredPrefix = null;
|
||||
for (String prefix : prefixes) {
|
||||
if (ConfigurationUtils.hasSubProperties(configurationMaps, prefix)) {
|
||||
preferredPrefix = prefix;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (preferredPrefix == null) {
|
||||
preferredPrefix = prefixes.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);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
String idOrName = "";
|
||||
if (StringUtils.hasText(this.getId())) {
|
||||
idOrName = "[id=" + this.getId() + "]";
|
||||
} else {
|
||||
String name = ReflectUtils.getProperty(this, "getName");
|
||||
if (StringUtils.hasText(name)) {
|
||||
idOrName = "[name=" + name + "]";
|
||||
}
|
||||
}
|
||||
logger.debug("Refreshing " + this.getClass().getSimpleName() + idOrName +
|
||||
" with prefix [" + preferredPrefix +
|
||||
"], extracted props: " + subProperties);
|
||||
}
|
||||
|
||||
assignProperties(this, environment, subProperties, subPropsConfiguration, configMode);
|
||||
|
||||
// process extra refresh of subclass, e.g. refresh method configs
|
||||
processExtraRefresh(preferredPrefix, subPropsConfiguration);
|
||||
}
|
||||
|
||||
private void assignProperties(Object obj, Environment environment, Map<String, String> properties, InmemoryConfiguration configuration, ConfigMode configMode) {
|
||||
// if old one (this) contains non-null value, do not override
|
||||
boolean overrideIfAbsent = getConfigMode() == ConfigMode.OVERRIDE_IF_ABSENT;
|
||||
boolean overrideIfAbsent = configMode == ConfigMode.OVERRIDE_IF_ABSENT;
|
||||
|
||||
// even if old one (this) contains non-null value, do override
|
||||
boolean overrideAll = getConfigMode() == ConfigMode.OVERRIDE_ALL;
|
||||
boolean overrideAll = configMode == ConfigMode.OVERRIDE_ALL;
|
||||
|
||||
// loop methods, get override value and set the new value back to method
|
||||
List<Method> methods = MethodUtils.getMethods(obj.getClass(), method -> method.getDeclaringClass() != Object.class);
|
||||
|
|
@ -807,7 +808,7 @@ public abstract class AbstractConfig implements Serializable {
|
|||
String fieldName = MethodUtils.extractFieldName(method);
|
||||
Map<String, String> subProperties = ConfigurationUtils.getSubProperties(properties, fieldName);
|
||||
InmemoryConfiguration subPropsConfiguration = new InmemoryConfiguration(subProperties);
|
||||
assignProperties(inner, environment, subProperties, subPropsConfiguration);
|
||||
assignProperties(inner, environment, subProperties, subPropsConfiguration, configMode);
|
||||
method.invoke(obj, inner);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new IllegalStateException("Cannot assign nested class when refreshing config: " + obj.getClass().getName(), e);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.common.utils.ClassUtils;
|
|||
import org.apache.dubbo.common.utils.RegexProperties;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.apache.dubbo.config.context.ConfigMode;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
|
@ -134,6 +135,8 @@ public abstract class ReferenceConfigBase<T> extends AbstractReferenceConfig {
|
|||
.getDefaultConsumer()
|
||||
.orElseThrow(() -> new IllegalStateException("Default consumer is not initialized"));
|
||||
}
|
||||
// try set properties from `dubbo.reference` if not set in current config
|
||||
refreshWithPrefixes(super.getPrefixes(), ConfigMode.OVERRIDE_IF_ABSENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.annotation.Service;
|
||||
import org.apache.dubbo.config.context.ConfigMode;
|
||||
import org.apache.dubbo.config.support.Parameter;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
|
@ -174,6 +175,8 @@ public abstract class ServiceConfigBase<T> extends AbstractServiceConfig {
|
|||
.getDefaultProvider()
|
||||
.orElseThrow(() -> new IllegalStateException("Default provider is not initialized"));
|
||||
}
|
||||
// try set properties from `dubbo.service` if not set in current config
|
||||
refreshWithPrefixes(super.getPrefixes(), ConfigMode.OVERRIDE_IF_ABSENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -272,7 +272,6 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
|
|||
ApplicationConfig.class,
|
||||
ProtocolConfig.class,
|
||||
RegistryConfig.class,
|
||||
MetadataReportConfig.class,
|
||||
MonitorConfig.class,
|
||||
MetricsConfig.class,
|
||||
SslConfig.class);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.config;
|
||||
|
||||
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;
|
||||
|
|
@ -44,7 +45,7 @@ class SystemConfigurationTest {
|
|||
@BeforeEach
|
||||
public void init() {
|
||||
|
||||
sysConfig = new SystemConfiguration();
|
||||
sysConfig = new SystemConfiguration(ApplicationModel.defaultModel().getDefaultModule());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -114,4 +115,4 @@ class SystemConfigurationTest {
|
|||
MockTwo
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -393,22 +393,33 @@ class ConfigManagerTest {
|
|||
@Test
|
||||
void testLoadConfigsOfTypeFromProps() {
|
||||
try {
|
||||
System.setProperty("dubbo.protocols.dubbo1.port", "20880");
|
||||
System.setProperty("dubbo.protocols.dubbo2.port", "20881");
|
||||
System.setProperty("dubbo.protocols.rest1.port", "8080");
|
||||
System.setProperty("dubbo.protocols.rest2.port", "8081");
|
||||
|
||||
ApplicationModel.defaultModel().destroy();
|
||||
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
||||
configManager = applicationModel.getApplicationConfigManager();
|
||||
moduleConfigManager = applicationModel.getDefaultModule().getConfigManager();
|
||||
|
||||
// dubbo.application.enable-file-cache = false
|
||||
configManager.loadConfigsOfTypeFromProps(ApplicationConfig.class);
|
||||
Optional<ApplicationConfig> application = configManager.getApplication();
|
||||
Assertions.assertTrue(application.isPresent());
|
||||
configManager.removeConfig(application.get());
|
||||
|
||||
System.setProperty("dubbo.protocols.dubbo1.port", "20880");
|
||||
System.setProperty("dubbo.protocols.dubbo2.port", "20881");
|
||||
System.setProperty("dubbo.protocols.rest1.port", "8080");
|
||||
System.setProperty("dubbo.protocols.rest2.port", "8081");
|
||||
configManager.loadConfigsOfTypeFromProps(ProtocolConfig.class);
|
||||
Collection<ProtocolConfig> protocols = configManager.getProtocols();
|
||||
Assertions.assertEquals(protocols.size(), 4);
|
||||
|
||||
System.setProperty("dubbo.applications.app1.name", "app-demo1");
|
||||
System.setProperty("dubbo.applications.app2.name", "app-demo2");
|
||||
|
||||
ApplicationModel.defaultModel().destroy();
|
||||
applicationModel = ApplicationModel.defaultModel();
|
||||
configManager = applicationModel.getApplicationConfigManager();
|
||||
moduleConfigManager = applicationModel.getDefaultModule().getConfigManager();
|
||||
try {
|
||||
configManager.loadConfigsOfTypeFromProps(ApplicationConfig.class);
|
||||
Assertions.fail();
|
||||
|
|
@ -456,4 +467,4 @@ class ConfigManagerTest {
|
|||
Assertions.assertFalse(moduleConfigManager.getConsumers().isEmpty());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
|
@ -73,16 +75,17 @@ import java.util.concurrent.ScheduledFuture;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.apache.dubbo.common.config.ConfigurationUtils.parseProperties;
|
||||
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.constants.LoggerCodeConstants.CONFIG_REFRESH_INSTANCE_ERROR;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_REGISTER_INSTANCE_ERROR;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_FAILED_START_MODEL;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_FAILED_EXECUTE_DESTORY;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_FAILED_INIT_CONFIG_CENTER;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_FAILED_START_MODEL;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_REFRESH_INSTANCE_ERROR;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_REGISTER_INSTANCE_ERROR;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.PROTOCOL_PROMETHEUS;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.isEmpty;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
|
||||
|
|
@ -302,8 +305,10 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
MetadataReportInstance metadataReportInstance = applicationModel.getBeanFactory().getBean(MetadataReportInstance.class);
|
||||
List<MetadataReportConfig> validMetadataReportConfigs = new ArrayList<>(metadataReportConfigs.size());
|
||||
for (MetadataReportConfig metadataReportConfig : metadataReportConfigs) {
|
||||
ConfigValidationUtils.validateMetadataConfig(metadataReportConfig);
|
||||
validMetadataReportConfigs.add(metadataReportConfig);
|
||||
if (ConfigValidationUtils.isValidMetadataConfig(metadataReportConfig)) {
|
||||
ConfigValidationUtils.validateMetadataConfig(metadataReportConfig);
|
||||
validMetadataReportConfigs.add(metadataReportConfig);
|
||||
}
|
||||
}
|
||||
metadataReportInstance.init(validMetadataReportConfigs);
|
||||
if (!metadataReportInstance.inited()) {
|
||||
|
|
@ -405,41 +410,57 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
|
||||
private void useRegistryAsMetadataCenterIfNecessary() {
|
||||
|
||||
Collection<MetadataReportConfig> metadataConfigs = configManager.getMetadataConfigs();
|
||||
|
||||
if (CollectionUtils.isNotEmpty(metadataConfigs)) {
|
||||
Collection<MetadataReportConfig> originMetadataConfigs = configManager.getMetadataConfigs();
|
||||
if (originMetadataConfigs.stream().anyMatch(m -> Objects.nonNull(m.getAddress()))) {
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<MetadataReportConfig> metadataConfigsToOverride = originMetadataConfigs
|
||||
.stream()
|
||||
.filter(m -> Objects.isNull(m.getAddress()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (metadataConfigsToOverride.size() > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
MetadataReportConfig metadataConfigToOverride = metadataConfigsToOverride.stream().findFirst().orElse(null);
|
||||
|
||||
List<RegistryConfig> defaultRegistries = configManager.getDefaultRegistries();
|
||||
if (defaultRegistries.size() > 0) {
|
||||
if (!defaultRegistries.isEmpty()) {
|
||||
defaultRegistries
|
||||
.stream()
|
||||
.filter(this::isUsedRegistryAsMetadataCenter)
|
||||
.map(this::registryAsMetadataCenter)
|
||||
.map(registryConfig -> registryAsMetadataCenter(registryConfig, metadataConfigToOverride))
|
||||
.forEach(metadataReportConfig -> {
|
||||
if (metadataReportConfig.getId() == null) {
|
||||
Collection<MetadataReportConfig> metadataReportConfigs = configManager.getMetadataConfigs();
|
||||
if (CollectionUtils.isNotEmpty(metadataReportConfigs)) {
|
||||
for (MetadataReportConfig existedConfig : metadataReportConfigs) {
|
||||
if (existedConfig.getId() == null && existedConfig.getAddress().equals(metadataReportConfig.getAddress())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
configManager.addMetadataReport(metadataReportConfig);
|
||||
} else {
|
||||
Optional<MetadataReportConfig> configOptional = configManager.getConfig(MetadataReportConfig.class, metadataReportConfig.getId());
|
||||
if (configOptional.isPresent()) {
|
||||
return;
|
||||
}
|
||||
configManager.addMetadataReport(metadataReportConfig);
|
||||
}
|
||||
logger.info("use registry as metadata-center: " + metadataReportConfig);
|
||||
overrideMetadataReportConfig(metadataConfigToOverride, metadataReportConfig);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void overrideMetadataReportConfig(MetadataReportConfig metadataConfigToOverride, MetadataReportConfig metadataReportConfig) {
|
||||
if (metadataReportConfig.getId() == null) {
|
||||
Collection<MetadataReportConfig> metadataReportConfigs = configManager.getMetadataConfigs();
|
||||
if (CollectionUtils.isNotEmpty(metadataReportConfigs)) {
|
||||
for (MetadataReportConfig existedConfig : metadataReportConfigs) {
|
||||
if (existedConfig.getId() == null && existedConfig.getAddress().equals(metadataReportConfig.getAddress())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
configManager.removeConfig(metadataConfigToOverride);
|
||||
configManager.addMetadataReport(metadataReportConfig);
|
||||
} else {
|
||||
Optional<MetadataReportConfig> configOptional = configManager.getConfig(MetadataReportConfig.class, metadataReportConfig.getId());
|
||||
if (configOptional.isPresent()) {
|
||||
return;
|
||||
}
|
||||
configManager.removeConfig(metadataConfigToOverride);
|
||||
configManager.addMetadataReport(metadataReportConfig);
|
||||
}
|
||||
logger.info("use registry as metadata-center: " + metadataReportConfig);
|
||||
}
|
||||
|
||||
private boolean isUsedRegistryAsMetadataCenter(RegistryConfig registryConfig) {
|
||||
return isUsedRegistryAsCenter(registryConfig, registryConfig::getUseAsMetadataCenter, "metadata",
|
||||
MetadataReportFactory.class);
|
||||
|
|
@ -495,24 +516,37 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
return false;
|
||||
}
|
||||
|
||||
private MetadataReportConfig registryAsMetadataCenter(RegistryConfig registryConfig) {
|
||||
String protocol = registryConfig.getProtocol();
|
||||
URL url = URL.valueOf(registryConfig.getAddress(), registryConfig.getScopeModel());
|
||||
MetadataReportConfig metadataReportConfig = new MetadataReportConfig();
|
||||
metadataReportConfig.setId(registryConfig.getId());
|
||||
private MetadataReportConfig registryAsMetadataCenter(RegistryConfig registryConfig, MetadataReportConfig originMetadataReportConfig) {
|
||||
MetadataReportConfig metadataReportConfig = originMetadataReportConfig == null ?
|
||||
new MetadataReportConfig(registryConfig.getApplicationModel()) : originMetadataReportConfig;
|
||||
if (metadataReportConfig.getId() == null) {
|
||||
metadataReportConfig.setId(registryConfig.getId());
|
||||
}
|
||||
metadataReportConfig.setScopeModel(applicationModel);
|
||||
if (metadataReportConfig.getParameters() == null) {
|
||||
metadataReportConfig.setParameters(new HashMap<>());
|
||||
}
|
||||
if (CollectionUtils.isNotEmptyMap(registryConfig.getParameters())) {
|
||||
metadataReportConfig.getParameters().putAll(registryConfig.getParameters()); // copy the parameters
|
||||
for (Map.Entry<String, String> entry : registryConfig.getParameters().entrySet()) {
|
||||
metadataReportConfig.getParameters().putIfAbsent(entry.getKey(), entry.getValue()); // copy the parameters
|
||||
}
|
||||
}
|
||||
metadataReportConfig.getParameters().put(CLIENT_KEY, registryConfig.getClient());
|
||||
metadataReportConfig.setGroup(registryConfig.getGroup());
|
||||
metadataReportConfig.setAddress(getRegistryCompatibleAddress(registryConfig));
|
||||
metadataReportConfig.setUsername(registryConfig.getUsername());
|
||||
metadataReportConfig.setPassword(registryConfig.getPassword());
|
||||
metadataReportConfig.setTimeout(registryConfig.getTimeout());
|
||||
if (metadataReportConfig.getGroup() == null) {
|
||||
metadataReportConfig.setGroup(registryConfig.getGroup());
|
||||
}
|
||||
if (metadataReportConfig.getAddress() == null) {
|
||||
metadataReportConfig.setAddress(getRegistryCompatibleAddress(registryConfig));
|
||||
}
|
||||
if (metadataReportConfig.getUsername() == null) {
|
||||
metadataReportConfig.setUsername(registryConfig.getUsername());
|
||||
}
|
||||
if (metadataReportConfig.getPassword() == null) {
|
||||
metadataReportConfig.setPassword(registryConfig.getPassword());
|
||||
}
|
||||
if (metadataReportConfig.getTimeout() == null) {
|
||||
metadataReportConfig.setTimeout(registryConfig.getTimeout());
|
||||
}
|
||||
return metadataReportConfig;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -512,8 +512,21 @@ public class ConfigValidationUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void validateMetadataConfig(MetadataReportConfig metadataReportConfig) {
|
||||
public static boolean isValidMetadataConfig(MetadataReportConfig metadataReportConfig) {
|
||||
if (metadataReportConfig == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Boolean.FALSE.equals(metadataReportConfig.getReportMetadata()) &&
|
||||
Boolean.FALSE.equals(metadataReportConfig.getReportDefinition())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !isEmpty(metadataReportConfig.getAddress());
|
||||
}
|
||||
|
||||
public static void validateMetadataConfig(MetadataReportConfig metadataReportConfig) {
|
||||
if (!isValidMetadataConfig(metadataReportConfig)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ class MultiInstanceTest {
|
|||
// stop provider app 2 and check threads
|
||||
providerBootstrap2.stop();
|
||||
// shutdown register center after dubbo application to avoid unregister services blocking
|
||||
checkUnclosedThreadsOfApp(stackTraces2, "Found unclosed threads of app 2: ", null);
|
||||
checkUnclosedThreadsOfApp(stackTraces2, "Found unclosed threads of app 2: ", new String[]{"Dubbo-framework-shared-scheduler"});
|
||||
|
||||
} finally {
|
||||
if (providerBootstrap1 != null) {
|
||||
|
|
|
|||
|
|
@ -29,10 +29,11 @@ import java.util.Map;
|
|||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_LOCAL_FILE_CACHE_ENABLED;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_DIRECTORY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PORT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_LOCAL_FILE_CACHE_ENABLED;
|
||||
import static org.apache.dubbo.common.utils.StringUtils.isEmpty;
|
||||
import static org.apache.dubbo.metadata.report.support.Constants.METADATA_REPORT_KEY;
|
||||
|
||||
|
|
@ -86,6 +87,7 @@ public class MetadataReportInstance implements Disposable {
|
|||
String protocol = url.getParameter(METADATA_REPORT_KEY, DEFAULT_DIRECTORY);
|
||||
url = URLBuilder.from(url)
|
||||
.setProtocol(protocol)
|
||||
.setPort(url.getParameter(PORT_KEY, url.getPort()))
|
||||
.setScopeModel(config.getScopeModel())
|
||||
.removeParameter(METADATA_REPORT_KEY)
|
||||
.build();
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ public class RpcInvocation implements Invocation, Serializable {
|
|||
* Deep clone of an invocation & put some service params into attachment from invoker (will not change the invoker in invocation)
|
||||
*
|
||||
* @param invocation original invocation
|
||||
* @param invoker target invoker
|
||||
* @param invoker target invoker
|
||||
*/
|
||||
public RpcInvocation(Invocation invocation, Invoker<?> invoker) {
|
||||
this(invocation.getTargetServiceUniqueName(), invocation.getServiceModel(), invocation.getMethodName(), invocation.getServiceName(),
|
||||
|
|
@ -384,6 +384,9 @@ public class RpcInvocation implements Invocation, Serializable {
|
|||
public Map<String, Object> getObjectAttachments() {
|
||||
try {
|
||||
attachmentLock.lock();
|
||||
if (attachments == null) {
|
||||
attachments = new HashMap<>();
|
||||
}
|
||||
return attachments;
|
||||
} finally {
|
||||
attachmentLock.unlock();
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ public class ContextFilter implements Filter, Filter.Listener {
|
|||
long timeout = RpcUtils.getTimeout(invocation, -1);
|
||||
if (timeout != -1) {
|
||||
// pass to next hop
|
||||
RpcContext.getClientAttachment().setObjectAttachment(TIME_COUNTDOWN_KEY, TimeoutCountDown.newCountDown(timeout, TimeUnit.MILLISECONDS));
|
||||
RpcContext.getServerAttachment().setObjectAttachment(TIME_COUNTDOWN_KEY, TimeoutCountDown.newCountDown(timeout, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
// merged from dubbox
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public class TimeoutFilter implements Filter, Filter.Listener {
|
|||
|
||||
@Override
|
||||
public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
|
||||
Object obj = RpcContext.getClientAttachment().getObjectAttachment(TIME_COUNTDOWN_KEY);
|
||||
Object obj = RpcContext.getServerAttachment().getObjectAttachment(TIME_COUNTDOWN_KEY);
|
||||
if (obj != null) {
|
||||
TimeoutCountDown countDown = (TimeoutCountDown) obj;
|
||||
if (countDown.isExpired()) {
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ public class DubboInvoker<T> extends AbstractInvoker<T> {
|
|||
int timeout;
|
||||
if (countdown == null) {
|
||||
timeout = (int) RpcUtils.getTimeout(getUrl(), methodName, RpcContext.getClientAttachment(), invocation, DEFAULT_TIMEOUT);
|
||||
if (getUrl().getParameter(ENABLE_TIMEOUT_COUNTDOWN_KEY, false)) {
|
||||
if (getUrl().getMethodParameter(methodName, ENABLE_TIMEOUT_COUNTDOWN_KEY, false)) {
|
||||
invocation.setObjectAttachment(TIMEOUT_ATTACHMENT_KEY, timeout); // pass timeout to remote server
|
||||
}
|
||||
} else {
|
||||
|
|
@ -187,6 +187,8 @@ public class DubboInvoker<T> extends AbstractInvoker<T> {
|
|||
timeout = (int) timeoutCountDown.timeRemaining(TimeUnit.MILLISECONDS);
|
||||
invocation.setObjectAttachment(TIMEOUT_ATTACHMENT_KEY, timeout);// pass timeout to remote server
|
||||
}
|
||||
|
||||
invocation.getObjectAttachments().remove(TIME_COUNTDOWN_KEY);
|
||||
return timeout;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ public class InjvmInvoker<T> extends AbstractInvoker<T> {
|
|||
int timeout;
|
||||
if (countdown == null) {
|
||||
timeout = (int) RpcUtils.getTimeout(getUrl(), methodName, RpcContext.getClientAttachment(), invocation, DEFAULT_TIMEOUT);
|
||||
if (getUrl().getParameter(ENABLE_TIMEOUT_COUNTDOWN_KEY, false)) {
|
||||
if (getUrl().getMethodParameter(methodName, ENABLE_TIMEOUT_COUNTDOWN_KEY, false)) {
|
||||
invocation.setObjectAttachment(TIMEOUT_ATTACHMENT_KEY, timeout); // pass timeout to remote server
|
||||
}
|
||||
} else {
|
||||
|
|
@ -294,6 +294,8 @@ public class InjvmInvoker<T> extends AbstractInvoker<T> {
|
|||
timeout = (int) timeoutCountDown.timeRemaining(TimeUnit.MILLISECONDS);
|
||||
invocation.setObjectAttachment(TIMEOUT_ATTACHMENT_KEY, timeout);// pass timeout to remote server
|
||||
}
|
||||
|
||||
invocation.getObjectAttachments().remove(TIME_COUNTDOWN_KEY);
|
||||
return timeout;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ public class TripleInvoker<T> extends AbstractInvoker<T> {
|
|||
if (countdown == null) {
|
||||
timeout = (int) RpcUtils.getTimeout(getUrl(), methodName,
|
||||
RpcContext.getClientAttachment(), invocation, 3000);
|
||||
if (getUrl().getParameter(ENABLE_TIMEOUT_COUNTDOWN_KEY, false)) {
|
||||
if (getUrl().getMethodParameter(methodName, ENABLE_TIMEOUT_COUNTDOWN_KEY, false)) {
|
||||
invocation.setObjectAttachment(TIMEOUT_ATTACHMENT_KEY,
|
||||
timeout); // pass timeout to remote server
|
||||
}
|
||||
|
|
@ -317,6 +317,8 @@ public class TripleInvoker<T> extends AbstractInvoker<T> {
|
|||
invocation.setObjectAttachment(TIMEOUT_ATTACHMENT_KEY,
|
||||
timeout);// pass timeout to remote server
|
||||
}
|
||||
|
||||
invocation.getObjectAttachments().remove(TIME_COUNTDOWN_KEY);
|
||||
return timeout;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue