diff --git a/CHANGELOG.md b/CHANGELOG.md index 70d2c02e4..577fec6e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,3 +4,4 @@ - [fix: add gateway context config example.](https://github.com/Tencent/spring-cloud-tencent/pull/1563) - [feat:support config empty protection.](https://github.com/Tencent/spring-cloud-tencent/pull/1585) - [feat:upgrade springframework version.](https://github.com/Tencent/spring-cloud-tencent/pull/1590) +- [feat:support dynamic multi-discovery.](https://github.com/Tencent/spring-cloud-tencent/pull/1595) diff --git a/spring-cloud-starter-tencent-all/pom.xml b/spring-cloud-starter-tencent-all/pom.xml index c8a70ee68..e49b8f535 100644 --- a/spring-cloud-starter-tencent-all/pom.xml +++ b/spring-cloud-starter-tencent-all/pom.xml @@ -69,5 +69,10 @@ com.tencent.cloud spring-cloud-starter-tencent-fault-tolerance + + + com.tencent.cloud + spring-cloud-starter-tencent-multi-discovery-plugin + diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java index 89c651b48..a9f5a9ae2 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocator.java @@ -21,20 +21,15 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import com.tencent.cloud.polaris.config.config.ConfigFileGroup; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; -import com.tencent.cloud.polaris.config.enums.ConfigFileFormat; import com.tencent.cloud.polaris.context.config.PolarisContextProperties; import com.tencent.polaris.api.utils.ClassUtils; import com.tencent.polaris.api.utils.CollectionUtils; import com.tencent.polaris.api.utils.StringUtils; import com.tencent.polaris.configuration.api.core.ConfigFileMetadata; import com.tencent.polaris.configuration.api.core.ConfigFileService; -import com.tencent.polaris.configuration.api.core.ConfigKVFile; -import com.tencent.polaris.configuration.client.internal.CompositeConfigFile; import com.tencent.polaris.configuration.client.internal.DefaultConfigFileMetadata; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,6 +40,9 @@ import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.Environment; import org.springframework.core.env.PropertySource; +import static com.tencent.cloud.polaris.config.utils.PolarisPropertySourceUtils.loadGroupPolarisPropertySource; +import static com.tencent.cloud.polaris.config.utils.PolarisPropertySourceUtils.loadPolarisPropertySource; + /** * Spring cloud reserved core configuration loading SPI. *

@@ -74,64 +72,6 @@ public class PolarisConfigFileLocator implements PropertySourceLocator { this.environment = environment; } - public static PolarisPropertySource loadPolarisPropertySource(ConfigFileService configFileService, String namespace, String group, String fileName) { - ConfigKVFile configKVFile = loadConfigKVFile(configFileService, namespace, group, fileName); - - Map map = new ConcurrentHashMap<>(); - for (String key : configKVFile.getPropertyNames()) { - map.put(key, configKVFile.getProperty(key, null)); - } - - return new PolarisPropertySource(namespace, group, fileName, configKVFile, map); - } - - public static PolarisPropertySource loadGroupPolarisPropertySource(ConfigFileService configFileService, String namespace, String group) { - List configKVFiles = new ArrayList<>(); - - com.tencent.polaris.configuration.api.core.ConfigFileGroup remoteGroup = configFileService.getConfigFileGroup(namespace, group); - if (remoteGroup == null) { - return null; - } - - for (ConfigFileMetadata configFile : remoteGroup.getConfigFileMetadataList()) { - String fileName = configFile.getFileName(); - ConfigKVFile configKVFile = loadConfigKVFile(configFileService, namespace, group, fileName); - configKVFiles.add(configKVFile); - } - - CompositeConfigFile compositeConfigFile = new CompositeConfigFile(configKVFiles); - - Map map = new ConcurrentHashMap<>(); - for (String key : compositeConfigFile.getPropertyNames()) { - String value = compositeConfigFile.getProperty(key, null); - map.put(key, value); - } - - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("namespace='" + namespace + '\'' - + ", group='" + group + '\'' + ", fileName='" + compositeConfigFile + '\'' - + ", map='" + map + '\''); - } - - return new PolarisPropertySource(namespace, group, "", compositeConfigFile, map); - } - - public static ConfigKVFile loadConfigKVFile(ConfigFileService configFileService, String namespace, String group, String fileName) { - ConfigKVFile configKVFile; - // unknown extension is resolved as yaml file - if (ConfigFileFormat.isYamlFile(fileName) || ConfigFileFormat.isUnknownFile(fileName)) { - configKVFile = configFileService.getConfigYamlFile(namespace, group, fileName); - } - else if (ConfigFileFormat.isPropertyFile(fileName)) { - configKVFile = configFileService.getConfigPropertiesFile(namespace, group, fileName); - } - else { - LOGGER.warn("[SCT Config] Unsupported config file. namespace = {}, group = {}, fileName = {}", namespace, group, fileName); - - throw new IllegalStateException("Only configuration files in the format of properties / yaml / yaml" + " can be injected into the spring context"); - } - return configKVFile; - } /** * order: spring boot default config files > custom config files > tsf default config group. diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFilePuller.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFilePuller.java index a1e05f7cc..0a3872ac8 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFilePuller.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFilePuller.java @@ -21,24 +21,24 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import com.tencent.cloud.polaris.config.config.ConfigFileGroup; import com.tencent.cloud.polaris.config.configdata.PolarisConfigDataLoader; -import com.tencent.cloud.polaris.config.enums.ConfigFileFormat; import com.tencent.cloud.polaris.context.config.PolarisContextProperties; +import com.tencent.polaris.api.utils.ClassUtils; import com.tencent.polaris.api.utils.CollectionUtils; import com.tencent.polaris.api.utils.StringUtils; import com.tencent.polaris.configuration.api.core.ConfigFileMetadata; import com.tencent.polaris.configuration.api.core.ConfigFileService; -import com.tencent.polaris.configuration.api.core.ConfigKVFile; import com.tencent.polaris.configuration.client.internal.DefaultConfigFileMetadata; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.env.CompositePropertySource; +import static com.tencent.cloud.polaris.config.utils.PolarisPropertySourceUtils.loadGroupPolarisPropertySource; +import static com.tencent.cloud.polaris.config.utils.PolarisPropertySourceUtils.loadPolarisPropertySource; + /** * PolarisConfigFilePuller pull configFile from Polaris. * @@ -82,7 +82,7 @@ public final class PolarisConfigFilePuller { String[] defaultProfiles, String serviceName) { List internalConfigFiles = getInternalConfigFiles(activeProfiles, defaultProfiles, serviceName); for (ConfigFileMetadata configFile : internalConfigFiles) { - PolarisPropertySource polarisPropertySource = loadPolarisPropertySource( + PolarisPropertySource polarisPropertySource = loadPolarisPropertySource(configFileService, configFile.getNamespace(), configFile.getFileGroup(), configFile.getFileName()); compositePropertySource.addPropertySource(polarisPropertySource); PolarisPropertySourceManager.addPropertySource(polarisPropertySource); @@ -124,7 +124,7 @@ public final class PolarisConfigFilePuller { return; } for (String fileName : files) { - PolarisPropertySource polarisPropertySource = loadPolarisPropertySource(groupNamespace, group, fileName); + PolarisPropertySource polarisPropertySource = loadPolarisPropertySource(configFileService, groupNamespace, group, fileName); compositePropertySource.addPropertySource(polarisPropertySource); PolarisPropertySourceManager.addPropertySource(polarisPropertySource); LOGGER.info( @@ -133,27 +133,35 @@ public final class PolarisConfigFilePuller { } } - private PolarisPropertySource loadPolarisPropertySource(String namespace, String group, String fileName) { - ConfigKVFile configKVFile; - // unknown extension is resolved as yaml file - if (ConfigFileFormat.isYamlFile(fileName) || ConfigFileFormat.isUnknownFile(fileName)) { - configKVFile = configFileService.getConfigYamlFile(namespace, group, fileName); - } - else if (ConfigFileFormat.isPropertyFile(fileName)) { - configKVFile = configFileService.getConfigPropertiesFile(namespace, group, fileName); + /** + * Init TSF config groups. + * @param compositePropertySource compositePropertySource + */ + public void initTsfConfigGroups(CompositePropertySource compositePropertySource) { + String tsfId = System.getProperty("tsf_id"); + String tsfNamespaceName = System.getProperty("tsf_namespace_name"); + String tsfGroupName = System.getProperty("tsf_group_name"); + + if (StringUtils.isEmpty(tsfNamespaceName) || StringUtils.isEmpty(tsfGroupName)) { + return; } - else { - LOGGER.warn("[SCT Config] Unsupported config file. namespace = {}, group = {}, fileName = {}", namespace, - group, fileName); + String namespace = polarisContextProperties.getNamespace(); + List tsfConfigGroups = new ArrayList<>(); + tsfConfigGroups.add((StringUtils.isNotBlank(tsfId) ? tsfId + "." : "") + tsfGroupName + ".application_config_group"); + tsfConfigGroups.add((StringUtils.isNotBlank(tsfId) ? tsfId + "." : "") + tsfNamespaceName + ".global_config_group"); - throw new IllegalStateException("Only configuration files in the format of properties / yaml / yaml" - + " can be injected into the spring context"); + if (ClassUtils.isClassPresent("org.springframework.cloud.gateway.filter.GlobalFilter")) { + tsfConfigGroups.add((StringUtils.isNotBlank(tsfId) ? tsfId + "." : "") + tsfGroupName + ".gateway_config_group"); } - Map map = new ConcurrentHashMap<>(); - for (String key : configKVFile.getPropertyNames()) { - map.put(key, configKVFile.getProperty(key, null)); + for (String tsfConfigGroup : tsfConfigGroups) { + PolarisPropertySource polarisPropertySource = loadGroupPolarisPropertySource(configFileService, namespace, tsfConfigGroup); + if (polarisPropertySource == null) { + // not register to polaris + continue; + } + compositePropertySource.addPropertySource(polarisPropertySource); + PolarisPropertySourceManager.addPropertySource(polarisPropertySource); } - return new PolarisPropertySource(namespace, group, fileName, configKVFile, map); } private List getInternalConfigFiles( diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java index 1445834df..2dc4e9759 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java @@ -53,6 +53,9 @@ import org.springframework.core.env.PropertySource; import org.springframework.lang.NonNull; import org.springframework.util.CollectionUtils; +import static com.tencent.cloud.polaris.config.utils.PolarisPropertySourceUtils.loadGroupPolarisPropertySource; +import static com.tencent.cloud.polaris.config.utils.PolarisPropertySourceUtils.loadPolarisPropertySource; + /** * 1. Listen to the Polaris server configuration publishing event 2. Write the changed * configuration content to propertySource 3. Refresh the context through contextRefresher @@ -153,7 +156,7 @@ public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationL registeredPolarisPropertySets.add(entry.getKey()); LOGGER.info("[SCT Config] add polaris config file:{}", entry.getKey()); ConfigFileMetadata configFileMetadata = entry.getValue(); - PolarisPropertySource p = PolarisConfigFileLocator.loadPolarisPropertySource( + PolarisPropertySource p = loadPolarisPropertySource( configFileService, configFileMetadata.getNamespace(), configFileMetadata.getFileGroup(), configFileMetadata.getFileName()); LOGGER.info("[SCT Config] changed property = {}", p.getSource().keySet()); @@ -194,7 +197,7 @@ public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationL PolarisPropertySource newGroupSource = null; if (isGroupRefresh) { - newGroupSource = PolarisConfigFileLocator.loadGroupPolarisPropertySource(configFileService, + newGroupSource = loadGroupPolarisPropertySource(configFileService, effectPolarisPropertySource.getNamespace(), effectPolarisPropertySource.getGroup()); } @@ -301,7 +304,8 @@ public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationL .withClientIp(context.getExtensions().getValueContext().getHost()) .withNamespace(polarisPropertySource.getNamespace()) .withConfigGroup(polarisPropertySource.getGroup()) - .withConfigVersion(Optional.ofNullable(configKVFileChangeEvent.getConfigFile()).map(ConfigFile::getName).orElse(null)) + .withConfigVersion(Optional.ofNullable(configKVFileChangeEvent.getConfigFile()).map(ConfigFile::getName) + .orElse(null)) .withConfigFileName(polarisPropertySource.getFileName()); BaseFlow.reportConfigEvent(context.getExtensions(), builder.build()); diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/configdata/PolarisConfigDataLoader.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/configdata/PolarisConfigDataLoader.java index 2b0ade83f..4fb731f61 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/configdata/PolarisConfigDataLoader.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/configdata/PolarisConfigDataLoader.java @@ -130,6 +130,8 @@ public class PolarisConfigDataLoader implements ConfigDataLoader map = new ConcurrentHashMap<>(); + for (String key : configKVFile.getPropertyNames()) { + map.put(key, configKVFile.getProperty(key, null)); + } + + return new PolarisPropertySource(namespace, group, fileName, configKVFile, map); + } + + public static PolarisPropertySource loadGroupPolarisPropertySource(ConfigFileService configFileService, String namespace, String group) { + List configKVFiles = new ArrayList<>(); + + com.tencent.polaris.configuration.api.core.ConfigFileGroup remoteGroup = configFileService.getConfigFileGroup(namespace, group); + if (remoteGroup == null) { + return null; + } + + for (ConfigFileMetadata configFile : remoteGroup.getConfigFileMetadataList()) { + String fileName = configFile.getFileName(); + ConfigKVFile configKVFile = loadConfigKVFile(configFileService, namespace, group, fileName); + configKVFiles.add(configKVFile); + } + + CompositeConfigFile compositeConfigFile = new CompositeConfigFile(configKVFiles); + + Map map = new ConcurrentHashMap<>(); + for (String key : compositeConfigFile.getPropertyNames()) { + String value = compositeConfigFile.getProperty(key, null); + map.put(key, value); + } + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("namespace='" + namespace + '\'' + + ", group='" + group + '\'' + ", fileName='" + compositeConfigFile + '\'' + + ", map='" + map + '\''); + } + + return new PolarisPropertySource(namespace, group, "", compositeConfigFile, map); + } + + public static ConfigKVFile loadConfigKVFile(ConfigFileService configFileService, String namespace, String group, String fileName) { + ConfigKVFile configKVFile; + // unknown extension is resolved as yaml file + if (ConfigFileFormat.isYamlFile(fileName) || ConfigFileFormat.isUnknownFile(fileName)) { + configKVFile = configFileService.getConfigYamlFile(namespace, group, fileName); + } + else if (ConfigFileFormat.isPropertyFile(fileName)) { + configKVFile = configFileService.getConfigPropertiesFile(namespace, group, fileName); + } + else { + LOGGER.warn("[SCT Config] Unsupported config file. namespace = {}, group = {}, fileName = {}", namespace, group, fileName); + + throw new IllegalStateException("Only configuration files in the format of properties / yaml / yaml" + " can be injected into the spring context"); + } + return configKVFile; + } } diff --git a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java index 1cd98ce11..f6c6abb85 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java +++ b/spring-cloud-starter-tencent-polaris-config/src/test/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigFileLocatorTest.java @@ -28,6 +28,7 @@ import java.util.Map; import com.tencent.cloud.polaris.config.config.ConfigFileGroup; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; import com.tencent.cloud.polaris.config.enums.RefreshType; +import com.tencent.cloud.polaris.config.utils.PolarisPropertySourceUtils; import com.tencent.cloud.polaris.context.config.PolarisContextProperties; import com.tencent.polaris.configuration.api.core.ConfigFileService; import com.tencent.polaris.configuration.api.core.ConfigKVFile; @@ -299,8 +300,8 @@ public class PolarisConfigFileLocatorTest { when(mockPropertySource.getPropertySourceName()).thenReturn(expectedAppConfigGroup); CompositePropertySource compositePropertySource = mock(CompositePropertySource.class); - try (MockedStatic mockedStatic = mockStatic(PolarisConfigFileLocator.class)) { - mockedStatic.when(() -> PolarisConfigFileLocator.loadGroupPolarisPropertySource( + try (MockedStatic mockedStatic = mockStatic(PolarisPropertySourceUtils.class)) { + mockedStatic.when(() -> PolarisPropertySourceUtils.loadGroupPolarisPropertySource( eq(configFileService), eq(polarisNamespace), any() diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java index 1738f2d69..51f190c9e 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisRegistration.java @@ -237,6 +237,13 @@ public class PolarisRegistration implements Registration { return registerEnabled; } + public String getNamespace() { + if (polarisDiscoveryProperties != null) { + return polarisDiscoveryProperties.getNamespace(); + } + return null; + } + public SDKContext getPolarisContext() { return polarisContext; } diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java index c6816a0f5..40e5ab59a 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java @@ -199,6 +199,7 @@ public class PolarisServiceRegistry implements ServiceRegistry metadata = configuration.getProvider().getRateLimit().getMetadata(); - metadata.put(TsfRateLimitConstants.RATE_LIMIT_MASTER_IP_KEY, tsfCoreProperties.getRatelimitMasterIp()); - metadata.put(TsfRateLimitConstants.RATE_LIMIT_MASTER_PORT_KEY, String.valueOf(tsfCoreProperties.getRatelimitMasterPort())); - metadata.put(TsfRateLimitConstants.SERVICE_NAME_KEY, tsfCoreProperties.getServiceName()); - metadata.put(TsfRateLimitConstants.INSTANCE_ID_KEY, tsfCoreProperties.getInstanceId()); - metadata.put(TsfRateLimitConstants.TOKEN_KEY, consulProperties.getAclToken()); - } + Map metadata = configuration.getProvider().getRateLimit().getMetadata(); + metadata.put(TsfRateLimitConstants.RATE_LIMIT_MASTER_IP_KEY, tsfCoreProperties.getRatelimitMasterIp()); + metadata.put(TsfRateLimitConstants.RATE_LIMIT_MASTER_PORT_KEY, String.valueOf(tsfCoreProperties.getRatelimitMasterPort())); + metadata.put(TsfRateLimitConstants.SERVICE_NAME_KEY, tsfCoreProperties.getServiceName()); + metadata.put(TsfRateLimitConstants.INSTANCE_ID_KEY, tsfCoreProperties.getInstanceId()); + metadata.put(TsfRateLimitConstants.TOKEN_KEY, consulProperties.getAclToken()); } @Override diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/ConditionalOnOnlyTsfConsulEnabled.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/ConditionalOnOnlyTsfConsulEnabled.java new file mode 100644 index 000000000..e431c087b --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/ConditionalOnOnlyTsfConsulEnabled.java @@ -0,0 +1,47 @@ +/* + * Tencent is pleased to support the open source community by making spring-cloud-tencent available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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 com.tencent.cloud.common.tsf; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.Conditional; +import org.springframework.core.type.AnnotatedTypeMetadata; + +/** + * Condition that if Only TSF Consul enabled. + * + * @author Haotian Zhang + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +@Conditional(ConditionalOnOnlyTsfConsulEnabled.OnTsfEnabledCondition.class) +public @interface ConditionalOnOnlyTsfConsulEnabled { + + class OnTsfEnabledCondition implements Condition { + + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { + return TsfContextUtils.isOnlyTsfConsulEnabled(conditionContext.getEnvironment()); + } + } +} diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/ConditionalOnTsfConsulEnabled.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/ConditionalOnTsfConsulEnabled.java index f576d219e..d04180349 100644 --- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/ConditionalOnTsfConsulEnabled.java +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/ConditionalOnTsfConsulEnabled.java @@ -22,16 +22,13 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import com.tencent.polaris.api.utils.StringUtils; - import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.Conditional; -import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata; /** - * Condition that if Polaris enabled. + * Condition that if TSF Consul enabled. * * @author Haotian Zhang */ @@ -44,20 +41,7 @@ public @interface ConditionalOnTsfConsulEnabled { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { - Environment environment = conditionContext.getEnvironment(); - boolean tsfConsulEnable = false; - - String tsfAppId = environment.getProperty("tsf_app_id"); - if (StringUtils.isNotBlank(tsfAppId)) { - String tsfConsulIp = environment.getProperty("tsf_consul_ip"); - String tsePolarisAddress = environment.getProperty("polaris_address"); - if (StringUtils.isBlank(tsePolarisAddress) && StringUtils.isNotBlank(environment.getProperty("spring.cloud.polaris.address"))) { - tsePolarisAddress = environment.getProperty("spring.cloud.polaris.address"); - } - tsfConsulEnable = StringUtils.isNotBlank(tsfConsulIp) && StringUtils.isBlank(tsePolarisAddress); - } - - return tsfConsulEnable; + return TsfContextUtils.isTsfConsulEnabled(conditionContext.getEnvironment()); } } } diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/TsfContextUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/TsfContextUtils.java new file mode 100644 index 000000000..8049e7fb5 --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/tsf/TsfContextUtils.java @@ -0,0 +1,80 @@ +/* + * Tencent is pleased to support the open source community by making spring-cloud-tencent available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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 com.tencent.cloud.common.tsf; + +import java.util.concurrent.atomic.AtomicBoolean; + +import com.tencent.polaris.api.utils.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.core.env.Environment; + +/** + * Utils for TSF. + * + * @author Haotian Zhang + */ +public final class TsfContextUtils { + + private static final Logger LOG = LoggerFactory.getLogger(TsfContextUtils.class); + + private static final AtomicBoolean isTsfConsulEnabledFirstConfiguration = new AtomicBoolean(true); + + private static final AtomicBoolean isOnlyTsfConsulEnabledFirstConfiguration = new AtomicBoolean(true); + + private static boolean tsfConsulEnabled = false; + + private static boolean onlyTsfConsulEnabled = false; + + private TsfContextUtils() { + } + + public static boolean isTsfConsulEnabled(Environment environment) { + if (environment != null && isTsfConsulEnabledFirstConfiguration.compareAndSet(true, false)) { + if (isOnlyTsfConsulEnabled(environment)) { + tsfConsulEnabled = true; + } + else { + boolean consulEnabled = Boolean.parseBoolean(environment.getProperty("tsf_consul_enable", "true")); + String tsfConsulIp = environment.getProperty("tsf_consul_ip"); + tsfConsulEnabled = consulEnabled && StringUtils.isNotBlank(tsfConsulIp); + if (tsfConsulEnabled) { + LOG.info("Tsf Consul is enabled: {}", tsfConsulIp); + } + } + } + return tsfConsulEnabled; + } + + public static boolean isOnlyTsfConsulEnabled(Environment environment) { + if (environment != null && isOnlyTsfConsulEnabledFirstConfiguration.compareAndSet(true, false)) { + boolean consulEnabled = Boolean.parseBoolean(environment.getProperty("tsf_consul_enable", "true")); + String tsfConsulIp = environment.getProperty("tsf_consul_ip"); + String polarisAddress = environment.getProperty("polaris_address"); + if (StringUtils.isBlank(polarisAddress) && StringUtils.isNotBlank(environment.getProperty("spring.cloud.polaris.address"))) { + polarisAddress = environment.getProperty("spring.cloud.polaris.address"); + } + onlyTsfConsulEnabled = consulEnabled && StringUtils.isNotBlank(tsfConsulIp) && StringUtils.isBlank(polarisAddress); + if (onlyTsfConsulEnabled) { + LOG.info("Only Tsf Consul is enabled: {}", tsfConsulIp); + } + } + return onlyTsfConsulEnabled; + } +} diff --git a/spring-cloud-tencent-coverage/pom.xml b/spring-cloud-tencent-coverage/pom.xml index 8db0a1fd7..1eaf785c5 100644 --- a/spring-cloud-tencent-coverage/pom.xml +++ b/spring-cloud-tencent-coverage/pom.xml @@ -88,6 +88,12 @@ com.tencent.cloud spring-cloud-tencent-lossless-plugin + + + com.tencent.cloud + spring-cloud-starter-tencent-multi-discovery-plugin + ${revision} + diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index 050e67473..f8d190654 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -213,6 +213,12 @@ ${revision} + + com.tencent.cloud + spring-cloud-starter-tencent-multi-discovery-plugin + ${revision} + + org.springdoc diff --git a/spring-cloud-tencent-plugin-starters/pom.xml b/spring-cloud-tencent-plugin-starters/pom.xml index 1ba1a6322..9563cc3ff 100644 --- a/spring-cloud-tencent-plugin-starters/pom.xml +++ b/spring-cloud-tencent-plugin-starters/pom.xml @@ -22,6 +22,7 @@ spring-cloud-starter-tencent-trace-plugin spring-cloud-starter-tencent-fault-tolerance spring-cloud-tencent-security-protection-plugin + spring-cloud-starter-tencent-multi-discovery-plugin diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-multi-discovery-plugin/pom.xml b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-multi-discovery-plugin/pom.xml new file mode 100644 index 000000000..f8b47e1af --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-multi-discovery-plugin/pom.xml @@ -0,0 +1,25 @@ + + + spring-cloud-tencent-plugin-starters + com.tencent.cloud + ${revision} + ../pom.xml + + 4.0.0 + spring-cloud-starter-tencent-multi-discovery-plugin + Spring Cloud Tencent Trace Plugin + + + + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-discovery + + + + com.tencent.cloud + spring-cloud-starter-tencent-polaris-config + + + diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-multi-discovery-plugin/src/main/java/com/tencent/cloud/plugin/discovery/multi/config/MultiDiscoveryAutoConfiguration.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-multi-discovery-plugin/src/main/java/com/tencent/cloud/plugin/discovery/multi/config/MultiDiscoveryAutoConfiguration.java new file mode 100644 index 000000000..b2d676f79 --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-multi-discovery-plugin/src/main/java/com/tencent/cloud/plugin/discovery/multi/config/MultiDiscoveryAutoConfiguration.java @@ -0,0 +1,46 @@ +/* + * Tencent is pleased to support the open source community by making spring-cloud-tencent available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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 com.tencent.cloud.plugin.discovery.multi.config; + +import com.tencent.cloud.plugin.discovery.multi.listeners.ConsulDiscoveryConfigChangeListener; +import com.tencent.cloud.polaris.registry.PolarisRegistration; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Auto configuration for multi discovery. + * + * @author Haotian Zhang + */ +@Configuration(proxyBeanMethods = false) +public class MultiDiscoveryAutoConfiguration { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnProperty(value = "spring.cloud.consul.enabled", havingValue = "true") + protected static class ConsulMultiDiscoveryConfig { + + @Bean + @ConditionalOnMissingBean + public ConsulDiscoveryConfigChangeListener consulDiscoveryConfigChangeListener(PolarisRegistration polarisRegistration) { + return new ConsulDiscoveryConfigChangeListener(polarisRegistration); + } + } +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-multi-discovery-plugin/src/main/java/com/tencent/cloud/plugin/discovery/multi/listeners/ConsulDiscoveryConfigChangeListener.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-multi-discovery-plugin/src/main/java/com/tencent/cloud/plugin/discovery/multi/listeners/ConsulDiscoveryConfigChangeListener.java new file mode 100644 index 000000000..6f602444c --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-multi-discovery-plugin/src/main/java/com/tencent/cloud/plugin/discovery/multi/listeners/ConsulDiscoveryConfigChangeListener.java @@ -0,0 +1,114 @@ +/* + * Tencent is pleased to support the open source community by making spring-cloud-tencent available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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 com.tencent.cloud.plugin.discovery.multi.listeners; + +import java.util.Set; + +import com.tencent.cloud.polaris.config.annotation.PolarisConfigKVFileChangeListener; +import com.tencent.cloud.polaris.config.listener.ConfigChangeEvent; +import com.tencent.cloud.polaris.registry.PolarisRegistration; +import com.tencent.polaris.api.plugin.common.PluginTypes; +import com.tencent.polaris.api.plugin.server.ServerConnector; +import com.tencent.polaris.api.rpc.InstanceRegisterRequest; +import com.tencent.polaris.api.utils.StringUtils; +import com.tencent.polaris.client.api.SDKContext; +import com.tencent.polaris.discovery.client.flow.RegisterStateManager; +import com.tencent.polaris.plugins.connector.common.DestroyableServerConnector; +import com.tencent.polaris.plugins.connector.composite.CompositeConnector; +import com.tencent.polaris.plugins.connector.consul.ConsulAPIConnector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Consul Discovery Config Listener . + * + * @author Haotian Zhang + */ +public final class ConsulDiscoveryConfigChangeListener { + + private static final Logger LOG = LoggerFactory.getLogger(ConsulDiscoveryConfigChangeListener.class); + + private final PolarisRegistration polarisRegistration; + + private final SDKContext sdkContext; + private final ConsulAPIConnector consulAPIConnector; + private InstanceRegisterRequest instanceRegisterRequest; + + public ConsulDiscoveryConfigChangeListener(PolarisRegistration polarisRegistration) { + this.polarisRegistration = polarisRegistration; + this.sdkContext = polarisRegistration.getPolarisContext(); + + ServerConnector connector = (ServerConnector) sdkContext.getPlugins() + .getPlugin(PluginTypes.SERVER_CONNECTOR.getBaseType(), sdkContext.getValueContext() + .getServerConnectorProtocol()); + ConsulAPIConnector temp = null; + if (connector instanceof CompositeConnector) { + CompositeConnector compositeConnector = (CompositeConnector) connector; + for (DestroyableServerConnector sc : compositeConnector.getServerConnectors()) { + if (sc instanceof ConsulAPIConnector) { + temp = (ConsulAPIConnector) sc; + break; + } + } + } + else if (connector instanceof ConsulAPIConnector) { + temp = (ConsulAPIConnector) connector; + } + this.consulAPIConnector = temp; + } + + @PolarisConfigKVFileChangeListener(interestedKeyPrefixes = "spring.cloud.consul.discovery") + public void onChange(ConfigChangeEvent event) { + if (consulAPIConnector != null) { + initInstanceRegisterRequest(); + + Set changedKeys = event.changedKeys(); + for (String changedKey : changedKeys) { + if (StringUtils.equals(changedKey, "spring.cloud.consul.discovery.enabled")) { + LOG.info("{} = {}", changedKey, event.getChange(changedKey)); + boolean discoveryEnabled = !StringUtils.equals("false", event.getChange(changedKey).getNewValue() + .toString()); + consulAPIConnector.setDiscoveryEnable(discoveryEnabled); + } + else if (StringUtils.equals(changedKey, "spring.cloud.consul.discovery.register")) { + LOG.info("{} = {}", changedKey, event.getChange(changedKey)); + boolean registerEnabled = !StringUtils.equals("false", event.getChange(changedKey).getNewValue() + .toString()); + if (registerEnabled) { + consulAPIConnector.registerInstance(RegisterStateManager.getRegisterState(sdkContext, instanceRegisterRequest) + .getInstanceRegisterRequest().getRequest(), null); + } + else { + consulAPIConnector.deregisterInstance(RegisterStateManager.getRegisterState(sdkContext, instanceRegisterRequest) + .getInstanceRegisterRequest().getRequest()); + } + } + } + } + } + + private void initInstanceRegisterRequest() { + if (instanceRegisterRequest == null) { + this.instanceRegisterRequest = new InstanceRegisterRequest(); + instanceRegisterRequest.setNamespace(polarisRegistration.getNamespace()); + instanceRegisterRequest.setService(polarisRegistration.getServiceId()); + instanceRegisterRequest.setHost(polarisRegistration.getHost()); + instanceRegisterRequest.setPort(polarisRegistration.getPort()); + } + } +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-multi-discovery-plugin/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-multi-discovery-plugin/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..74518ad07 --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-multi-discovery-plugin/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.tencent.cloud.plugin.discovery.multi.config.MultiDiscoveryAutoConfiguration diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfContextAutoConfiguration.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfContextAutoConfiguration.java index aa8a704c9..1d2cbd3e7 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfContextAutoConfiguration.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfContextAutoConfiguration.java @@ -17,7 +17,7 @@ package com.tencent.cloud.polaris.context.config.extend.tsf; -import com.tencent.cloud.common.tsf.ConditionalOnTsfConsulEnabled; +import com.tencent.cloud.common.tsf.ConditionalOnOnlyTsfConsulEnabled; import com.tencent.cloud.polaris.context.config.PolarisContextAutoConfiguration; import com.tencent.cloud.polaris.context.config.extend.consul.ConsulProperties; @@ -33,7 +33,7 @@ import org.springframework.context.annotation.Configuration; */ @Configuration(proxyBeanMethods = false) @AutoConfigureAfter(PolarisContextAutoConfiguration.class) -@ConditionalOnTsfConsulEnabled +@ConditionalOnOnlyTsfConsulEnabled public class TsfContextAutoConfiguration { @Bean diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfContextUtils.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfContextUtils.java deleted file mode 100644 index b058f9005..000000000 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfContextUtils.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making spring-cloud-tencent available. - * - * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * 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 com.tencent.cloud.polaris.context.config.extend.tsf; - -import java.util.concurrent.atomic.AtomicBoolean; - -import com.tencent.polaris.api.utils.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.springframework.core.env.Environment; - -/** - * Utils for TSF. - * - * @author Haotian Zhang - */ -public final class TsfContextUtils { - - private static final Logger LOG = LoggerFactory.getLogger(TsfContextUtils.class); - - private static final AtomicBoolean isFirstConfiguration = new AtomicBoolean(true); - - private static boolean tsfConsulEnabled = false; - - private TsfContextUtils() { - } - - public static boolean isTsfConsulEnabled(Environment environment) { - if (environment != null && isFirstConfiguration.compareAndSet(true, false)) { - String tsfConsulIp = environment.getProperty("tsf_consul_ip"); - String tsePolarisAddress = environment.getProperty("polaris_address"); - if (StringUtils.isBlank(tsePolarisAddress) && StringUtils.isNotBlank(environment.getProperty("spring.cloud.polaris.address"))) { - tsePolarisAddress = environment.getProperty("spring.cloud.polaris.address"); - } - tsfConsulEnabled = StringUtils.isNotBlank(tsfConsulIp) && StringUtils.isBlank(tsePolarisAddress); - if (tsfConsulEnabled) { - LOG.info("Tsf Consul is enabled: {}", tsfConsulIp); - } - } - return tsfConsulEnabled; - } -} diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfCoreEnvironmentPostProcessor.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfCoreEnvironmentPostProcessor.java index 0c9d04696..323aed563 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfCoreEnvironmentPostProcessor.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfCoreEnvironmentPostProcessor.java @@ -20,6 +20,7 @@ package com.tencent.cloud.polaris.context.config.extend.tsf; import java.util.HashMap; import java.util.Map; +import com.tencent.cloud.common.tsf.TsfContextUtils; import com.tencent.polaris.api.utils.StringUtils; import org.apache.commons.logging.Log; @@ -64,13 +65,13 @@ public final class TsfCoreEnvironmentPostProcessor implements EnvironmentPostPro // enabled String polarisEnabled = environment.getProperty("spring.cloud.polaris.enabled"); if (StringUtils.isBlank(polarisEnabled)) { - defaultProperties.put("spring.cloud.polaris.enabled", true); + defaultProperties.put("spring.cloud.polaris.enabled", "true"); } // lossless String polarisAdminPort = environment.getProperty("polaris_admin_port"); if (StringUtils.isNotBlank(polarisAdminPort)) { - defaultProperties.put("spring.cloud.polaris.lossless.enabled", true); + defaultProperties.put("spring.cloud.polaris.lossless.enabled", environment.getProperty("spring.cloud.polaris.lossless.enabled", "true")); } if (TsfContextUtils.isTsfConsulEnabled(environment)) { @@ -114,16 +115,12 @@ public final class TsfCoreEnvironmentPostProcessor implements EnvironmentPostPro // context defaultProperties.put("spring.cloud.polaris.enabled", "true"); - defaultProperties.put("spring.cloud.polaris.discovery.enabled", "false"); - defaultProperties.put("spring.cloud.polaris.discovery.register", "false"); - defaultProperties.put("spring.cloud.consul.enabled", "true"); + defaultProperties.put("spring.cloud.consul.enabled", environment.getProperty("tsf_consul_enable", "true")); defaultProperties.put("spring.cloud.consul.host", tsfConsulIp); defaultProperties.put("spring.cloud.consul.port", tsfConsulPort); defaultProperties.put("spring.cloud.consul.token", tsfConsulToken); // discovery - defaultProperties.put("spring.cloud.consul.discovery.enabled", "true"); - defaultProperties.put("spring.cloud.consul.discovery.register", "true"); defaultProperties.put("spring.cloud.consul.discovery.instance-id", tsfInstanceId); defaultProperties.put("spring.cloud.polaris.discovery.instance-id", tsfInstanceId); defaultProperties.put("spring.cloud.polaris.discovery.zero-protection.enabled", @@ -147,25 +144,31 @@ public final class TsfCoreEnvironmentPostProcessor implements EnvironmentPostPro defaultProperties.put("spring.cloud.polaris.contract.report.enabled", environment.getProperty("tsf.swagger.enabled", "true")); defaultProperties.put("spring.cloud.polaris.contract.name", tsfApplicationId); - // configuration - defaultProperties.put("spring.cloud.polaris.config.enabled", "true"); - defaultProperties.put("spring.cloud.polaris.config.internal-enabled", "false"); - defaultProperties.put("spring.cloud.polaris.config.data-source", "consul"); - defaultProperties.put("spring.cloud.polaris.config.address", "http://" + tsfConsulIp + ":" + tsfConsulPort); - defaultProperties.put("spring.cloud.polaris.config.port", tsfConsulPort); - defaultProperties.put("spring.cloud.polaris.config.token", tsfConsulToken); - defaultProperties.put("spring.cloud.polaris.config.groups[0].namespace", "config"); - defaultProperties.put("spring.cloud.polaris.config.groups[0].name", "application"); - defaultProperties.put("spring.cloud.polaris.config.groups[0].files[0]", tsfApplicationId + "/" + tsfGroupId + "/"); - defaultProperties.put("spring.cloud.polaris.config.groups[0].files[1]", tsfNamespaceId + "/"); - defaultProperties.put("spring.cloud.polaris.config.refresh-type", - environment.getProperty("spring.cloud.polaris.config.refresh-type", "refresh_context")); - - // router - defaultProperties.put("spring.cloud.polaris.router.rule-router.fail-over", - environment.getProperty("spring.cloud.polaris.router.rule-router.fail-over", "none")); - defaultProperties.put("spring.cloud.polaris.router.namespace-router.enabled", - environment.getProperty("spring.cloud.polaris.router.namespace-router.enabled", "true")); + if (TsfContextUtils.isOnlyTsfConsulEnabled(environment)) { + // context + defaultProperties.put("spring.cloud.polaris.discovery.enabled", "false"); + defaultProperties.put("spring.cloud.polaris.discovery.register", "false"); + + // configuration + defaultProperties.put("spring.cloud.polaris.config.enabled", "true"); + defaultProperties.put("spring.cloud.polaris.config.internal-enabled", "false"); + defaultProperties.put("spring.cloud.polaris.config.data-source", "consul"); + defaultProperties.put("spring.cloud.polaris.config.address", "http://" + tsfConsulIp + ":" + tsfConsulPort); + defaultProperties.put("spring.cloud.polaris.config.port", tsfConsulPort); + defaultProperties.put("spring.cloud.polaris.config.token", tsfConsulToken); + defaultProperties.put("spring.cloud.polaris.config.groups[0].namespace", "config"); + defaultProperties.put("spring.cloud.polaris.config.groups[0].name", "application"); + defaultProperties.put("spring.cloud.polaris.config.groups[0].files[0]", tsfApplicationId + "/" + tsfGroupId + "/"); + defaultProperties.put("spring.cloud.polaris.config.groups[0].files[1]", tsfNamespaceId + "/"); + defaultProperties.put("spring.cloud.polaris.config.refresh-type", + environment.getProperty("spring.cloud.polaris.config.refresh-type", "refresh_context")); + + // router + defaultProperties.put("spring.cloud.polaris.router.rule-router.fail-over", + environment.getProperty("spring.cloud.polaris.router.rule-router.fail-over", "none")); + defaultProperties.put("spring.cloud.polaris.router.namespace-router.enabled", + environment.getProperty("spring.cloud.polaris.router.namespace-router.enabled", "true")); + } } MapPropertySource propertySource = new MapPropertySource("tsf-polaris-properties", defaultProperties); diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfLastEnvironmentPostProcessor.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfLastEnvironmentPostProcessor.java new file mode 100644 index 000000000..e31da91ba --- /dev/null +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfLastEnvironmentPostProcessor.java @@ -0,0 +1,74 @@ +/* + * Tencent is pleased to support the open source community by making spring-cloud-tencent available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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 com.tencent.cloud.polaris.context.config.extend.tsf; + +import java.util.HashMap; +import java.util.Map; + +import com.tencent.cloud.common.tsf.TsfContextUtils; +import com.tencent.polaris.api.utils.StringUtils; +import org.apache.commons.logging.Log; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor; +import org.springframework.boot.env.EnvironmentPostProcessor; +import org.springframework.boot.logging.DeferredLogFactory; +import org.springframework.core.Ordered; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MapPropertySource; + +/** + * Read TSF env. + * + * @author Haotian Zhang + */ +public final class TsfLastEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered { + + /** + * run before {@link ConfigDataEnvironmentPostProcessor}. + */ + public static final int ORDER = ConfigDataEnvironmentPostProcessor.ORDER + 1; + + private final Log LOGGER; + + private TsfLastEnvironmentPostProcessor(DeferredLogFactory logFactory) { + this.LOGGER = logFactory.getLog(getClass()); + } + + @Override + public int getOrder() { + return ORDER; + } + + @Override + public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { + String tsfAppId = environment.getProperty("tsf_app_id"); + // TSF deploy + if (StringUtils.isNotBlank(tsfAppId)) { + Map defaultProperties = new HashMap<>(); + + if (TsfContextUtils.isTsfConsulEnabled(environment)) { + defaultProperties.put("spring.cloud.consul.discovery.enabled", environment.getProperty("spring.cloud.consul.discovery.enabled", "true")); + defaultProperties.put("spring.cloud.consul.discovery.register", environment.getProperty("spring.cloud.consul.discovery.register", "true")); + } + + MapPropertySource tsfLastPropertySource = new MapPropertySource("tsf-last-properties", defaultProperties); + environment.getPropertySources().addLast(tsfLastPropertySource); + } + } +} diff --git a/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories index 8829038c0..f33d0939d 100644 --- a/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-tencent-polaris-context/src/main/resources/META-INF/spring.factories @@ -6,4 +6,5 @@ org.springframework.context.ApplicationListener=\ com.tencent.cloud.polaris.context.listener.FailedEventApplicationListener org.springframework.boot.env.EnvironmentPostProcessor=\ com.tencent.cloud.polaris.context.config.PolarisContextEnvironmentPostProcessor,\ - com.tencent.cloud.polaris.context.config.extend.tsf.TsfCoreEnvironmentPostProcessor + com.tencent.cloud.polaris.context.config.extend.tsf.TsfCoreEnvironmentPostProcessor,\ + com.tencent.cloud.polaris.context.config.extend.tsf.TsfLastEnvironmentPostProcessor