Feature: support spring cloud config data (#451)
* configdata * configdata * feature:support spring cloud configData * feature:support spring cloud configData * feature:support spring cloud configData * feature:support spring cloud configData * feature:support spring cloud configData * feature:support spring cloud configData * feature:support spring cloud configData * feature:support spring cloud configData * feature:support spring cloud configData * feature:support spring cloud configData * feature:support spring cloud configData * feature:support spring cloud configData * Update PolarisConfigFilePullerTest.java Co-authored-by: wulingxiao <1251605638@qqcom> Co-authored-by: Haotian Zhang <928016560@qq.com> Co-authored-by: lepdou <lepdou@gmail.com>pull/512/head
parent
fe2da06f92
commit
91dd3d79ad
@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.adapter;
|
||||||
|
|
||||||
|
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.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 org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PolarisConfigFilePuller pull configFile from Polaris.
|
||||||
|
*
|
||||||
|
* @author wlx
|
||||||
|
*/
|
||||||
|
public final class PolarisConfigFilePuller {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(PolarisConfigFileLocator.class);
|
||||||
|
|
||||||
|
private PolarisContextProperties polarisContextProperties;
|
||||||
|
|
||||||
|
private ConfigFileService configFileService;
|
||||||
|
|
||||||
|
private PolarisPropertySourceManager polarisPropertySourceManager;
|
||||||
|
|
||||||
|
private PolarisConfigFilePuller() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InitInternalConfigFiles for {@link PolarisConfigDataLoader}.
|
||||||
|
*
|
||||||
|
* @param compositePropertySource compositePropertySource
|
||||||
|
* @param activeProfiles activeProfiles
|
||||||
|
* @param serviceName serviceName
|
||||||
|
*/
|
||||||
|
public void initInternalConfigFiles(CompositePropertySource compositePropertySource, String[] activeProfiles, String serviceName) {
|
||||||
|
List<ConfigFileMetadata> internalConfigFiles = getInternalConfigFiles(activeProfiles, serviceName);
|
||||||
|
for (ConfigFileMetadata configFile : internalConfigFiles) {
|
||||||
|
PolarisPropertySource polarisPropertySource = loadPolarisPropertySource(
|
||||||
|
configFile.getNamespace(), configFile.getFileGroup(), configFile.getFileName());
|
||||||
|
compositePropertySource.addPropertySource(polarisPropertySource);
|
||||||
|
polarisPropertySourceManager.addPropertySource(polarisPropertySource);
|
||||||
|
LOGGER.info("[SCT Config] Load and inject polaris config file. file = {}", configFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init multiple CustomPolarisConfigFile.
|
||||||
|
*
|
||||||
|
* @param compositePropertySource compositePropertySource
|
||||||
|
* @param configFileGroups configFileGroups
|
||||||
|
*/
|
||||||
|
public void initCustomPolarisConfigFiles(CompositePropertySource compositePropertySource,
|
||||||
|
List<ConfigFileGroup> configFileGroups) {
|
||||||
|
configFileGroups.forEach(
|
||||||
|
configFileGroup -> initCustomPolarisConfigFile(compositePropertySource, configFileGroup)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init single CustomPolarisConfigFile.
|
||||||
|
*
|
||||||
|
* @param compositePropertySource compositePropertySource
|
||||||
|
* @param configFileGroup configFileGroup
|
||||||
|
*/
|
||||||
|
public void initCustomPolarisConfigFile(CompositePropertySource compositePropertySource,
|
||||||
|
ConfigFileGroup configFileGroup) {
|
||||||
|
String namespace = polarisContextProperties.getNamespace();
|
||||||
|
String group = configFileGroup.getName();
|
||||||
|
if (!StringUtils.hasText(group)) {
|
||||||
|
throw new IllegalArgumentException("polaris config group name cannot be empty.");
|
||||||
|
}
|
||||||
|
List<String> files = configFileGroup.getFiles();
|
||||||
|
if (CollectionUtils.isEmpty(files)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String fileName : files) {
|
||||||
|
PolarisPropertySource polarisPropertySource = loadPolarisPropertySource(namespace, group, fileName);
|
||||||
|
compositePropertySource.addPropertySource(polarisPropertySource);
|
||||||
|
polarisPropertySourceManager.addPropertySource(polarisPropertySource);
|
||||||
|
LOGGER.info(
|
||||||
|
"[SCT Config] Load and inject polaris config file success. namespace = {}, group = {}, fileName = {}",
|
||||||
|
namespace, group, fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private PolarisPropertySource loadPolarisPropertySource(String namespace, String group, String fileName) {
|
||||||
|
ConfigKVFile configKVFile;
|
||||||
|
// unknown extension is resolved as properties file
|
||||||
|
if (ConfigFileFormat.isPropertyFile(fileName)
|
||||||
|
|| ConfigFileFormat.isUnknownFile(fileName)) {
|
||||||
|
configKVFile = configFileService.getConfigPropertiesFile(namespace, group, fileName);
|
||||||
|
}
|
||||||
|
else if (ConfigFileFormat.isYamlFile(fileName)) {
|
||||||
|
configKVFile = configFileService.getConfigYamlFile(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");
|
||||||
|
}
|
||||||
|
Map<String, Object> map = new ConcurrentHashMap<>();
|
||||||
|
for (String key : configKVFile.getPropertyNames()) {
|
||||||
|
map.put(key, configKVFile.getProperty(key, null));
|
||||||
|
}
|
||||||
|
return new PolarisPropertySource(namespace, group, fileName, configKVFile, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private List<ConfigFileMetadata> getInternalConfigFiles(String[] activeProfiles, String serviceName) {
|
||||||
|
String namespace = polarisContextProperties.getNamespace();
|
||||||
|
if (StringUtils.hasText(polarisContextProperties.getService())) {
|
||||||
|
serviceName = polarisContextProperties.getService();
|
||||||
|
}
|
||||||
|
// priority: application-${profile} > application > boostrap-${profile} > boostrap
|
||||||
|
return getInternalConfigFiles(activeProfiles, namespace, serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ConfigFileMetadata> getInternalConfigFiles(String[] activeProfiles, String namespace, String serviceName) {
|
||||||
|
List<ConfigFileMetadata> internalConfigFiles = new LinkedList<>();
|
||||||
|
for (String activeProfile : activeProfiles) {
|
||||||
|
if (!StringUtils.hasText(activeProfile)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application-" + activeProfile + ".properties"));
|
||||||
|
internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application-" + activeProfile + ".yml"));
|
||||||
|
}
|
||||||
|
|
||||||
|
internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application.properties"));
|
||||||
|
internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "application.yml"));
|
||||||
|
|
||||||
|
for (String activeProfile : activeProfiles) {
|
||||||
|
if (!StringUtils.hasText(activeProfile)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "bootstrap-" + activeProfile + ".properties"));
|
||||||
|
internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "bootstrap-" + activeProfile + ".yml"));
|
||||||
|
}
|
||||||
|
|
||||||
|
internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "bootstrap.properties"));
|
||||||
|
internalConfigFiles.add(new DefaultConfigFileMetadata(namespace, serviceName, "bootstrap.yml"));
|
||||||
|
|
||||||
|
return internalConfigFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method to create PolarisConfigFilePuller for
|
||||||
|
* {@link PolarisConfigDataLoader},{@link PolarisConfigFileLocator}.
|
||||||
|
*
|
||||||
|
* @param polarisContextProperties polarisContextProperties
|
||||||
|
* @param configFileService configFileService
|
||||||
|
* @param polarisPropertySourceManager polarisPropertySourceManager
|
||||||
|
* @return PolarisConfigFilePuller instance
|
||||||
|
*/
|
||||||
|
public static PolarisConfigFilePuller get(PolarisContextProperties polarisContextProperties, ConfigFileService configFileService,
|
||||||
|
PolarisPropertySourceManager polarisPropertySourceManager) {
|
||||||
|
PolarisConfigFilePuller puller = new PolarisConfigFilePuller();
|
||||||
|
puller.polarisContextProperties = polarisContextProperties;
|
||||||
|
puller.configFileService = configFileService;
|
||||||
|
puller.polarisPropertySourceManager = polarisPropertySourceManager;
|
||||||
|
return puller;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.configdata;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import com.tencent.cloud.polaris.config.adapter.PolarisConfigFilePuller;
|
||||||
|
import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager;
|
||||||
|
import com.tencent.cloud.polaris.config.config.ConfigFileGroup;
|
||||||
|
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
|
||||||
|
import com.tencent.polaris.client.api.SDKContext;
|
||||||
|
import com.tencent.polaris.configuration.api.core.ConfigFileService;
|
||||||
|
import com.tencent.polaris.configuration.factory.ConfigFileServiceFactory;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
import org.springframework.boot.ConfigurableBootstrapContext;
|
||||||
|
import org.springframework.boot.context.config.ConfigData;
|
||||||
|
import org.springframework.boot.context.config.ConfigDataLoader;
|
||||||
|
import org.springframework.boot.context.config.ConfigDataLoaderContext;
|
||||||
|
import org.springframework.boot.context.config.ConfigDataResourceNotFoundException;
|
||||||
|
import org.springframework.boot.context.config.Profiles;
|
||||||
|
import org.springframework.boot.logging.DeferredLogFactory;
|
||||||
|
import org.springframework.core.env.CompositePropertySource;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import static org.springframework.boot.context.config.ConfigData.Option.IGNORE_IMPORTS;
|
||||||
|
import static org.springframework.boot.context.config.ConfigData.Option.IGNORE_PROFILES;
|
||||||
|
import static org.springframework.boot.context.config.ConfigData.Option.PROFILE_SPECIFIC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link ConfigDataLoader}.can be used to load {@link ConfigData} for a given
|
||||||
|
* {@link PolarisConfigDataResource} .
|
||||||
|
* <p>
|
||||||
|
* Load {@link ConfigData} via {@link PolarisConfigDataLoader}
|
||||||
|
*
|
||||||
|
* @author wlx
|
||||||
|
* @date 2022/7/5 11:14 下午
|
||||||
|
*/
|
||||||
|
public class PolarisConfigDataLoader implements ConfigDataLoader<PolarisConfigDataResource> {
|
||||||
|
|
||||||
|
private static final String POLARIS_CONFIG_PROPERTY_SOURCE_NAME = "polaris-config";
|
||||||
|
|
||||||
|
private final Log log;
|
||||||
|
|
||||||
|
private ConfigFileService configFileService;
|
||||||
|
|
||||||
|
private PolarisConfigFilePuller puller;
|
||||||
|
|
||||||
|
static final AtomicBoolean INTERNAL_CONFIG_FILES_LOADED = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
static final AtomicBoolean CUSTOM_POLARIS_CONFIG_FILE_LOADED = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
public PolarisConfigDataLoader(DeferredLogFactory logFactory) {
|
||||||
|
this.log = logFactory.getLog(getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigData load(ConfigDataLoaderContext context, PolarisConfigDataResource resource)
|
||||||
|
throws ConfigDataResourceNotFoundException {
|
||||||
|
try {
|
||||||
|
return load(context.getBootstrapContext(), resource);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log.warn("Error getting properties from polaris: " + resource, e);
|
||||||
|
if (!resource.isOptional()) {
|
||||||
|
throw new ConfigDataResourceNotFoundException(resource, e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigData load(ConfigurableBootstrapContext bootstrapContext, PolarisConfigDataResource resource) {
|
||||||
|
CompositePropertySource compositePropertySource = locate(bootstrapContext, resource);
|
||||||
|
return new ConfigData(compositePropertySource.getPropertySources(), getOptions(resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompositePropertySource locate(ConfigurableBootstrapContext bootstrapContext,
|
||||||
|
PolarisConfigDataResource resource) {
|
||||||
|
CompositePropertySource compositePropertySource = new CompositePropertySource(
|
||||||
|
POLARIS_CONFIG_PROPERTY_SOURCE_NAME);
|
||||||
|
SDKContext sdkContext = bootstrapContext.get(SDKContext.class);
|
||||||
|
if (null == this.configFileService) {
|
||||||
|
this.configFileService = ConfigFileServiceFactory.createConfigFileService(sdkContext);
|
||||||
|
}
|
||||||
|
if (null == this.puller) {
|
||||||
|
this.puller = PolarisConfigFilePuller.get(resource.getPolarisContextProperties(),
|
||||||
|
configFileService, bootstrapContext.get(PolarisPropertySourceManager.class));
|
||||||
|
}
|
||||||
|
Profiles profiles = resource.getProfiles();
|
||||||
|
if (INTERNAL_CONFIG_FILES_LOADED.compareAndSet(false, true)) {
|
||||||
|
log.info("loading internal config files");
|
||||||
|
List<String> profilesActive = profiles.getActive();
|
||||||
|
String[] activeProfiles = profilesActive.toArray(new String[]{});
|
||||||
|
this.puller.initInternalConfigFiles(compositePropertySource, activeProfiles, resource.getServiceName());
|
||||||
|
}
|
||||||
|
|
||||||
|
PolarisConfigProperties polarisConfigProperties = resource.getPolarisConfigProperties();
|
||||||
|
if (!CollectionUtils.isEmpty(polarisConfigProperties.getGroups()) &&
|
||||||
|
CUSTOM_POLARIS_CONFIG_FILE_LOADED.compareAndSet(false, true)) {
|
||||||
|
log.info("loading custom config files");
|
||||||
|
this.puller.initCustomPolarisConfigFiles(compositePropertySource,
|
||||||
|
polarisConfigProperties.getGroups());
|
||||||
|
}
|
||||||
|
// load config data
|
||||||
|
if (StringUtils.hasText(resource.getFileName())) {
|
||||||
|
log.info("loading config data config file, group:" + resource.getGroupName() + " file: " + resource.getFileName());
|
||||||
|
this.puller.initCustomPolarisConfigFile(compositePropertySource, configFileGroup(resource));
|
||||||
|
}
|
||||||
|
return compositePropertySource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigData.Option[] getOptions(PolarisConfigDataResource resource) {
|
||||||
|
List<ConfigData.Option> options = new ArrayList<>();
|
||||||
|
options.add(IGNORE_IMPORTS);
|
||||||
|
options.add(IGNORE_PROFILES);
|
||||||
|
PolarisConfigProperties polarisConfigProperties = resource.getPolarisConfigProperties();
|
||||||
|
if (polarisConfigProperties.isPreference()) {
|
||||||
|
// mark it as 'PROFILE_SPECIFIC' config, it has higher priority
|
||||||
|
options.add(PROFILE_SPECIFIC);
|
||||||
|
}
|
||||||
|
return options.toArray(new ConfigData.Option[]{});
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigFileGroup configFileGroup(PolarisConfigDataResource polarisConfigDataResource) {
|
||||||
|
String fileName = polarisConfigDataResource.getFileName();
|
||||||
|
String groupName = polarisConfigDataResource.getGroupName();
|
||||||
|
ConfigFileGroup configFileGroup = new ConfigFileGroup();
|
||||||
|
configFileGroup.setName(groupName);
|
||||||
|
List<String> files = new ArrayList<>();
|
||||||
|
files.add(fileName);
|
||||||
|
configFileGroup.setFiles(files);
|
||||||
|
return configFileGroup;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,291 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.configdata;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import com.tencent.cloud.polaris.config.ConfigurationModifier;
|
||||||
|
import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager;
|
||||||
|
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
|
||||||
|
import com.tencent.cloud.polaris.context.ModifyAddress;
|
||||||
|
import com.tencent.cloud.polaris.context.PolarisConfigModifier;
|
||||||
|
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
|
||||||
|
import com.tencent.polaris.api.utils.StringUtils;
|
||||||
|
import com.tencent.polaris.client.api.SDKContext;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
import org.springframework.boot.BootstrapRegistry;
|
||||||
|
import org.springframework.boot.ConfigurableBootstrapContext;
|
||||||
|
import org.springframework.boot.context.config.ConfigDataLocation;
|
||||||
|
import org.springframework.boot.context.config.ConfigDataLocationNotFoundException;
|
||||||
|
import org.springframework.boot.context.config.ConfigDataLocationResolver;
|
||||||
|
import org.springframework.boot.context.config.ConfigDataLocationResolverContext;
|
||||||
|
import org.springframework.boot.context.config.ConfigDataResourceNotFoundException;
|
||||||
|
import org.springframework.boot.context.config.Profiles;
|
||||||
|
import org.springframework.boot.context.properties.bind.BindHandler;
|
||||||
|
import org.springframework.boot.context.properties.bind.Bindable;
|
||||||
|
import org.springframework.boot.context.properties.bind.Binder;
|
||||||
|
import org.springframework.boot.logging.DeferredLogFactory;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link ConfigDataLocationResolver}, used to resolve {@link ConfigDataLocation locations}
|
||||||
|
* into one or more {@link PolarisConfigDataResource polarisConfigDataResource}.
|
||||||
|
*
|
||||||
|
* @author wlx
|
||||||
|
*/
|
||||||
|
public class PolarisConfigDataLocationResolver implements
|
||||||
|
ConfigDataLocationResolver<PolarisConfigDataResource>, Ordered {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix for Config Server imports.
|
||||||
|
*/
|
||||||
|
public static final String PREFIX = "polaris";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix for Polaris configurationProperties.
|
||||||
|
*/
|
||||||
|
public static final String POLARIS_PREFIX = "spring.cloud.polaris";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* COLON.
|
||||||
|
*/
|
||||||
|
public static final String COLON = ":";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty String.
|
||||||
|
*/
|
||||||
|
public static final String EMPTY_STRING = "";
|
||||||
|
|
||||||
|
private final Log log;
|
||||||
|
|
||||||
|
public PolarisConfigDataLocationResolver(DeferredLogFactory logFactory) {
|
||||||
|
this.log = logFactory.getLog(getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isResolvable(ConfigDataLocationResolverContext context, ConfigDataLocation location) {
|
||||||
|
if (!location.hasPrefix(PREFIX)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return context.getBinder()
|
||||||
|
.bind("spring.cloud.polaris.config.enabled", Boolean.class)
|
||||||
|
.orElse(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PolarisConfigDataResource> resolve(
|
||||||
|
ConfigDataLocationResolverContext context, ConfigDataLocation location)
|
||||||
|
throws ConfigDataLocationNotFoundException,
|
||||||
|
ConfigDataResourceNotFoundException {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PolarisConfigDataResource> resolveProfileSpecific(
|
||||||
|
ConfigDataLocationResolverContext resolverContext,
|
||||||
|
ConfigDataLocation location, Profiles profiles)
|
||||||
|
throws ConfigDataLocationNotFoundException {
|
||||||
|
|
||||||
|
ConfigurableBootstrapContext bootstrapContext = resolverContext.getBootstrapContext();
|
||||||
|
|
||||||
|
PolarisConfigProperties polarisConfigProperties = loadPolarisConfigProperties(
|
||||||
|
resolverContext,
|
||||||
|
PolarisConfigProperties.class,
|
||||||
|
POLARIS_PREFIX + ".config"
|
||||||
|
);
|
||||||
|
if (Objects.isNull(polarisConfigProperties)) {
|
||||||
|
polarisConfigProperties = new PolarisConfigProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
PolarisContextProperties polarisContextProperties = loadPolarisConfigProperties(
|
||||||
|
resolverContext,
|
||||||
|
PolarisContextProperties.class,
|
||||||
|
POLARIS_PREFIX
|
||||||
|
);
|
||||||
|
if (Objects.isNull(polarisContextProperties)) {
|
||||||
|
polarisContextProperties = new PolarisContextProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare and init earlier Polaris SDKContext to pull config files from remote.
|
||||||
|
prepareAndInitEarlierPolarisSdkContext(resolverContext, polarisConfigProperties, polarisContextProperties);
|
||||||
|
|
||||||
|
bootstrapContext.registerIfAbsent(PolarisConfigProperties.class,
|
||||||
|
BootstrapRegistry.InstanceSupplier.of(polarisConfigProperties));
|
||||||
|
|
||||||
|
bootstrapContext.registerIfAbsent(PolarisContextProperties.class,
|
||||||
|
BootstrapRegistry.InstanceSupplier.of(polarisContextProperties));
|
||||||
|
|
||||||
|
bootstrapContext.registerIfAbsent(PolarisPropertySourceManager.class,
|
||||||
|
BootstrapRegistry.InstanceSupplier.of(new PolarisPropertySourceManager()));
|
||||||
|
|
||||||
|
bootstrapContext.addCloseListener(
|
||||||
|
event -> {
|
||||||
|
// destroy earlier Polaris sdkContext
|
||||||
|
event.getBootstrapContext().get(SDKContext.class).destroy();
|
||||||
|
// register PolarisPropertySourceManager to context
|
||||||
|
PolarisPropertySourceManager polarisPropertySourceManager = event.getBootstrapContext().get(PolarisPropertySourceManager.class);
|
||||||
|
event.getApplicationContext().getBeanFactory().registerSingleton(
|
||||||
|
"polarisPropertySourceManager", polarisPropertySourceManager);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return loadConfigDataResources(resolverContext,
|
||||||
|
location, profiles, polarisConfigProperties, polarisContextProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T> T loadPolarisConfigProperties(
|
||||||
|
ConfigDataLocationResolverContext context,
|
||||||
|
Class<T> typeClass,
|
||||||
|
String prefix) {
|
||||||
|
Binder binder = context.getBinder();
|
||||||
|
BindHandler bindHandler = getBindHandler(context);
|
||||||
|
|
||||||
|
T instance;
|
||||||
|
if (!registerNotNecessary(typeClass) && context.getBootstrapContext().isRegistered(typeClass)) {
|
||||||
|
instance = context.getBootstrapContext().get(typeClass);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
instance = binder.bind(prefix, Bindable.of(typeClass), bindHandler)
|
||||||
|
.map(properties -> binder.bind(prefix, Bindable.ofInstance(properties), bindHandler)
|
||||||
|
.orElse(properties))
|
||||||
|
.orElseGet(() -> binder.bind(prefix, Bindable.of(typeClass), bindHandler)
|
||||||
|
.orElseGet(() -> null));
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BindHandler getBindHandler(ConfigDataLocationResolverContext context) {
|
||||||
|
return context.getBootstrapContext().getOrElse(BindHandler.class, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<PolarisConfigDataResource> loadConfigDataResources(ConfigDataLocationResolverContext resolverContext,
|
||||||
|
ConfigDataLocation location,
|
||||||
|
Profiles profiles,
|
||||||
|
PolarisConfigProperties polarisConfigProperties,
|
||||||
|
PolarisContextProperties polarisContextProperties) {
|
||||||
|
List<PolarisConfigDataResource> result = new ArrayList<>();
|
||||||
|
boolean optional = location.isOptional();
|
||||||
|
String groupFileName = getRealGroupFileName(location);
|
||||||
|
String serviceName = loadPolarisConfigProperties(resolverContext,
|
||||||
|
String.class, "spring.application.name");
|
||||||
|
if (StringUtils.isBlank(serviceName)) {
|
||||||
|
serviceName = "application";
|
||||||
|
log.warn("No spring.application.name found, defaulting to 'application'");
|
||||||
|
}
|
||||||
|
String groupName = StringUtils.isBlank(groupFileName) ? EMPTY_STRING : parseGroupName(groupFileName, serviceName);
|
||||||
|
if (StringUtils.isNotBlank(groupName)) {
|
||||||
|
log.info("group from configDataLocation is " + groupName);
|
||||||
|
}
|
||||||
|
String fileName = StringUtils.isBlank(groupFileName) ? EMPTY_STRING : parseFileName(groupFileName);
|
||||||
|
if (StringUtils.isNotBlank(fileName)) {
|
||||||
|
log.info("file from configDataLocation is " + fileName);
|
||||||
|
}
|
||||||
|
PolarisConfigDataResource polarisConfigDataResource = new PolarisConfigDataResource(
|
||||||
|
polarisConfigProperties,
|
||||||
|
polarisContextProperties,
|
||||||
|
profiles, optional,
|
||||||
|
fileName, groupName, serviceName
|
||||||
|
);
|
||||||
|
result.add(polarisConfigDataResource);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRealGroupFileName(ConfigDataLocation location) {
|
||||||
|
String prefixedValue = location.getNonPrefixedValue(PREFIX);
|
||||||
|
if (StringUtils.isBlank(prefixedValue) || !prefixedValue.startsWith(COLON)) {
|
||||||
|
return prefixedValue;
|
||||||
|
}
|
||||||
|
return prefixedValue.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseFileName(String groupFileName) {
|
||||||
|
String[] split = groupFileName.split(COLON);
|
||||||
|
if (split.length > 1) {
|
||||||
|
return split[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return split[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseGroupName(String groupFileName, String serviceName) {
|
||||||
|
String[] split = groupFileName.split(COLON);
|
||||||
|
if (split.length > 1) {
|
||||||
|
return split[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return serviceName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareAndInitEarlierPolarisSdkContext(ConfigDataLocationResolverContext resolverContext,
|
||||||
|
PolarisConfigProperties polarisConfigProperties,
|
||||||
|
PolarisContextProperties polarisContextProperties) {
|
||||||
|
ConfigurableBootstrapContext bootstrapContext = resolverContext.getBootstrapContext();
|
||||||
|
if (!bootstrapContext.isRegistered(SDKContext.class)) {
|
||||||
|
SDKContext sdkContext = sdkContext(resolverContext,
|
||||||
|
polarisConfigProperties, polarisContextProperties);
|
||||||
|
sdkContext.init();
|
||||||
|
bootstrapContext.register(SDKContext.class, BootstrapRegistry.InstanceSupplier.of(sdkContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private SDKContext sdkContext(ConfigDataLocationResolverContext resolverContext,
|
||||||
|
PolarisConfigProperties polarisConfigProperties,
|
||||||
|
PolarisContextProperties polarisContextProperties) {
|
||||||
|
List<PolarisConfigModifier> modifierList = modifierList(polarisConfigProperties, polarisContextProperties);
|
||||||
|
return SDKContext.initContextByConfig(polarisContextProperties.configuration(modifierList, () -> {
|
||||||
|
return loadPolarisConfigProperties(resolverContext, String.class, "spring.cloud.client.ip-address");
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<PolarisConfigModifier> modifierList(PolarisConfigProperties polarisConfigProperties,
|
||||||
|
PolarisContextProperties polarisContextProperties) {
|
||||||
|
// add ModifyAddress and ConfigurationModifier to load SDKContext
|
||||||
|
List<PolarisConfigModifier> modifierList = new ArrayList<>();
|
||||||
|
ModifyAddress modifyAddress = new ModifyAddress();
|
||||||
|
modifyAddress.setProperties(polarisContextProperties);
|
||||||
|
|
||||||
|
ConfigurationModifier configurationModifier = new ConfigurationModifier(polarisConfigProperties,
|
||||||
|
polarisContextProperties);
|
||||||
|
modifierList.add(modifyAddress);
|
||||||
|
modifierList.add(configurationModifier);
|
||||||
|
return modifierList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean registerNotNecessary(Class<?> typeClass) {
|
||||||
|
return typeClass.isPrimitive() ||
|
||||||
|
Number.class.isAssignableFrom(typeClass) ||
|
||||||
|
String.class.isAssignableFrom(typeClass) ||
|
||||||
|
Character.class.isAssignableFrom(typeClass) ||
|
||||||
|
Boolean.class.isAssignableFrom(typeClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.configdata;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor;
|
||||||
|
import org.springframework.cloud.commons.ConfigDataMissingEnvironmentPostProcessor;
|
||||||
|
import org.springframework.cloud.util.PropertyUtils;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PolarisConfigDataMissingEnvironmentPostProcessor to check if miss PolarisConfigData config,if miss config
|
||||||
|
* will throw {@link ImportException}.
|
||||||
|
*
|
||||||
|
* @author wlx
|
||||||
|
* @see ConfigDataMissingEnvironmentPostProcessor
|
||||||
|
* @see ConfigDataMissingEnvironmentPostProcessor.ImportException
|
||||||
|
*/
|
||||||
|
public class PolarisConfigDataMissingEnvironmentPostProcessor extends ConfigDataMissingEnvironmentPostProcessor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* run after {@link ConfigDataEnvironmentPostProcessor}.
|
||||||
|
*/
|
||||||
|
public static final int ORDER = ConfigDataEnvironmentPostProcessor.ORDER + 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return ORDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldProcessEnvironment(Environment environment) {
|
||||||
|
// if using bootstrap or legacy processing don't run
|
||||||
|
if (!PropertyUtils.bootstrapEnabled(environment) && !PropertyUtils.useLegacyProcessing(environment)) {
|
||||||
|
boolean configEnabled = environment.getProperty("spring.cloud.polaris.config.enabled", Boolean.class, true);
|
||||||
|
boolean importCheckEnabled = environment.getProperty("spring.cloud.polaris.config.import-check.enabled", Boolean.class, true);
|
||||||
|
return configEnabled && importCheckEnabled;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getPrefix() {
|
||||||
|
return PolarisConfigDataLocationResolver.PREFIX;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.configdata;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
|
||||||
|
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.config.ConfigData;
|
||||||
|
import org.springframework.boot.context.config.ConfigDataResource;
|
||||||
|
import org.springframework.boot.context.config.Profiles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A polaris configData resource from which {@link ConfigData} can be loaded.
|
||||||
|
*
|
||||||
|
* @author wlx
|
||||||
|
* @date 2022/7/5 11:13 下午
|
||||||
|
*/
|
||||||
|
public class PolarisConfigDataResource extends ConfigDataResource {
|
||||||
|
|
||||||
|
private final PolarisConfigProperties polarisConfigProperties;
|
||||||
|
|
||||||
|
private final PolarisContextProperties polarisContextProperties;
|
||||||
|
|
||||||
|
private final Profiles profiles;
|
||||||
|
|
||||||
|
private final boolean optional;
|
||||||
|
|
||||||
|
private final String fileName;
|
||||||
|
|
||||||
|
private final String groupName;
|
||||||
|
|
||||||
|
private final String serviceName;
|
||||||
|
|
||||||
|
public PolarisConfigDataResource(PolarisConfigProperties polarisConfigProperties,
|
||||||
|
PolarisContextProperties polarisContextProperties,
|
||||||
|
Profiles profiles, boolean optional,
|
||||||
|
String fileName, String groupName, String serviceName) {
|
||||||
|
this.polarisConfigProperties = polarisConfigProperties;
|
||||||
|
this.polarisContextProperties = polarisContextProperties;
|
||||||
|
this.profiles = profiles;
|
||||||
|
this.optional = optional;
|
||||||
|
this.fileName = fileName;
|
||||||
|
this.groupName = groupName;
|
||||||
|
this.serviceName = serviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PolarisConfigProperties getPolarisConfigProperties() {
|
||||||
|
return polarisConfigProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PolarisContextProperties getPolarisContextProperties() {
|
||||||
|
return polarisContextProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Profiles getProfiles() {
|
||||||
|
return profiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOptional() {
|
||||||
|
return optional;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGroupName() {
|
||||||
|
return groupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServiceName() {
|
||||||
|
return serviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PolarisConfigDataResource that = (PolarisConfigDataResource) o;
|
||||||
|
return optional == that.optional &&
|
||||||
|
polarisConfigProperties.equals(that.polarisConfigProperties) &&
|
||||||
|
polarisContextProperties.equals(that.polarisContextProperties) &&
|
||||||
|
profiles.equals(that.profiles) &&
|
||||||
|
fileName.equals(that.fileName) &&
|
||||||
|
groupName.equals(that.groupName) &&
|
||||||
|
serviceName.equals(that.serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(polarisConfigProperties, polarisContextProperties, profiles, optional, fileName, groupName, serviceName);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.adapter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.tencent.cloud.polaris.config.config.ConfigFileGroup;
|
||||||
|
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
|
||||||
|
import com.tencent.polaris.configuration.api.core.ConfigFileService;
|
||||||
|
import com.tencent.polaris.configuration.api.core.ConfigKVFile;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import org.springframework.core.env.CompositePropertySource;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@link PolarisConfigFilePuller}.
|
||||||
|
*
|
||||||
|
* @author wlx
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class PolarisConfigFilePullerTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private PolarisContextProperties polarisContextProperties;
|
||||||
|
@Mock
|
||||||
|
private ConfigFileService configFileService;
|
||||||
|
@Mock
|
||||||
|
private PolarisPropertySourceManager polarisPropertySourceManager;
|
||||||
|
|
||||||
|
private final String testNamespace = "testNamespace";
|
||||||
|
private final String testServiceName = "testServiceName";
|
||||||
|
private final String polarisConfigPropertySourceName = "polaris-config";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPullInternalConfigFiles() {
|
||||||
|
PolarisConfigFilePuller puller = PolarisConfigFilePuller.get(polarisContextProperties, configFileService,
|
||||||
|
polarisPropertySourceManager);
|
||||||
|
|
||||||
|
when(polarisContextProperties.getNamespace()).thenReturn(testNamespace);
|
||||||
|
when(polarisContextProperties.getService()).thenReturn(testServiceName);
|
||||||
|
|
||||||
|
// application.properties
|
||||||
|
Map<String, Object> applicationProperties = new HashMap<>();
|
||||||
|
applicationProperties.put("k1", "v1");
|
||||||
|
applicationProperties.put("k2", "v2");
|
||||||
|
applicationProperties.put("k3", "v3");
|
||||||
|
ConfigKVFile propertiesFile = new MockedConfigKVFile(applicationProperties);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "application.properties"))
|
||||||
|
.thenReturn(propertiesFile);
|
||||||
|
|
||||||
|
Map<String, Object> emptyMap = new HashMap<>();
|
||||||
|
ConfigKVFile emptyConfigFile = new MockedConfigKVFile(emptyMap);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application.yml")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "bootstrap.properties")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yml")).thenReturn(emptyConfigFile);
|
||||||
|
CompositePropertySource compositePropertySource = new CompositePropertySource(polarisConfigPropertySourceName);
|
||||||
|
|
||||||
|
puller.initInternalConfigFiles(compositePropertySource, new String[]{}, testServiceName);
|
||||||
|
|
||||||
|
Assert.assertEquals("v1", compositePropertySource.getProperty("k1"));
|
||||||
|
Assert.assertEquals("v2", compositePropertySource.getProperty("k2"));
|
||||||
|
Assert.assertEquals("v3", compositePropertySource.getProperty("k3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPullInternalConfigFilesWithProfile() {
|
||||||
|
PolarisConfigFilePuller puller = PolarisConfigFilePuller.get(polarisContextProperties, configFileService,
|
||||||
|
polarisPropertySourceManager);
|
||||||
|
|
||||||
|
when(polarisContextProperties.getNamespace()).thenReturn(testNamespace);
|
||||||
|
when(polarisContextProperties.getService()).thenReturn(testServiceName);
|
||||||
|
|
||||||
|
// application.properties
|
||||||
|
Map<String, Object> applicationProperties = new HashMap<>();
|
||||||
|
applicationProperties.put("k1", "v1");
|
||||||
|
applicationProperties.put("k2", "v2");
|
||||||
|
applicationProperties.put("k3", "v3");
|
||||||
|
ConfigKVFile propertiesFile = new MockedConfigKVFile(applicationProperties);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "application.properties"))
|
||||||
|
.thenReturn(propertiesFile);
|
||||||
|
|
||||||
|
// application-dev.properties
|
||||||
|
Map<String, Object> devProperties = new HashMap<>();
|
||||||
|
devProperties.put("k1", "v11");
|
||||||
|
ConfigKVFile devFile = new MockedConfigKVFile(devProperties);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "application-dev.properties"))
|
||||||
|
.thenReturn(devFile);
|
||||||
|
|
||||||
|
Map<String, Object> emptyMap = new HashMap<>();
|
||||||
|
ConfigKVFile emptyConfigFile = new MockedConfigKVFile(emptyMap);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application.yml")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application-dev.yml")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "bootstrap.properties")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "bootstrap-dev.properties")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yml")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap-dev.yml")).thenReturn(emptyConfigFile);
|
||||||
|
List<String> active = new ArrayList<>();
|
||||||
|
active.add("dev");
|
||||||
|
String[] activeProfiles = active.toArray(new String[]{});
|
||||||
|
CompositePropertySource compositePropertySource = new CompositePropertySource(polarisConfigPropertySourceName);
|
||||||
|
puller.initInternalConfigFiles(compositePropertySource, activeProfiles, testServiceName);
|
||||||
|
|
||||||
|
Assert.assertEquals("v11", compositePropertySource.getProperty("k1"));
|
||||||
|
Assert.assertEquals("v2", compositePropertySource.getProperty("k2"));
|
||||||
|
Assert.assertEquals("v3", compositePropertySource.getProperty("k3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPullCustomConfigFilesWithProfile() {
|
||||||
|
PolarisConfigFilePuller puller = PolarisConfigFilePuller.get(polarisContextProperties, configFileService,
|
||||||
|
polarisPropertySourceManager);
|
||||||
|
|
||||||
|
when(polarisContextProperties.getNamespace()).thenReturn(testNamespace);
|
||||||
|
|
||||||
|
List<ConfigFileGroup> customFiles = new LinkedList<>();
|
||||||
|
ConfigFileGroup configFileGroup = new ConfigFileGroup();
|
||||||
|
String customGroup = "group1";
|
||||||
|
configFileGroup.setName(customGroup);
|
||||||
|
String customFile1 = "file1.properties";
|
||||||
|
String customFile2 = "file2.properties";
|
||||||
|
configFileGroup.setFiles(Lists.newArrayList(customFile1, customFile2));
|
||||||
|
customFiles.add(configFileGroup);
|
||||||
|
|
||||||
|
// file1.properties
|
||||||
|
Map<String, Object> file1Map = new HashMap<>();
|
||||||
|
file1Map.put("k1", "v1");
|
||||||
|
file1Map.put("k2", "v2");
|
||||||
|
ConfigKVFile file1 = new MockedConfigKVFile(file1Map);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, customGroup, customFile1)).thenReturn(file1);
|
||||||
|
|
||||||
|
// file2.properties
|
||||||
|
Map<String, Object> file2Map = new HashMap<>();
|
||||||
|
file2Map.put("k1", "v11");
|
||||||
|
file2Map.put("k3", "v3");
|
||||||
|
ConfigKVFile file2 = new MockedConfigKVFile(file2Map);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, customGroup, customFile2)).thenReturn(file2);
|
||||||
|
|
||||||
|
CompositePropertySource compositePropertySource = new CompositePropertySource(polarisConfigPropertySourceName);
|
||||||
|
puller.initCustomPolarisConfigFiles(compositePropertySource, customFiles);
|
||||||
|
|
||||||
|
Assert.assertEquals("v1", compositePropertySource.getProperty("k1"));
|
||||||
|
Assert.assertEquals("v2", compositePropertySource.getProperty("k2"));
|
||||||
|
Assert.assertEquals("v3", compositePropertySource.getProperty("k3"));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,288 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.configdata;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.tencent.cloud.polaris.config.adapter.MockedConfigKVFile;
|
||||||
|
import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager;
|
||||||
|
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
|
||||||
|
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
|
||||||
|
import com.tencent.polaris.client.api.SDKContext;
|
||||||
|
import com.tencent.polaris.configuration.api.core.ConfigFileService;
|
||||||
|
import com.tencent.polaris.configuration.api.core.ConfigKVFile;
|
||||||
|
import com.tencent.polaris.configuration.factory.ConfigFileServiceFactory;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.MockedStatic;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import org.springframework.boot.ConfigurableBootstrapContext;
|
||||||
|
import org.springframework.boot.context.config.ConfigData;
|
||||||
|
import org.springframework.boot.context.config.ConfigDataLoaderContext;
|
||||||
|
import org.springframework.boot.context.config.Profiles;
|
||||||
|
import org.springframework.boot.logging.DeferredLogs;
|
||||||
|
import org.springframework.core.env.CompositePropertySource;
|
||||||
|
import org.springframework.core.env.PropertySource;
|
||||||
|
|
||||||
|
import static com.tencent.cloud.polaris.config.configdata.PolarisConfigDataLoader.CUSTOM_POLARIS_CONFIG_FILE_LOADED;
|
||||||
|
import static com.tencent.cloud.polaris.config.configdata.PolarisConfigDataLoader.INTERNAL_CONFIG_FILES_LOADED;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.mockStatic;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@link PolarisConfigDataLoader}.
|
||||||
|
*
|
||||||
|
* @author wlx
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class PolarisConfigDataLoaderTest {
|
||||||
|
|
||||||
|
private static final SDKContext sdkContext = SDKContext.initContext();
|
||||||
|
|
||||||
|
private final String testNamespace = "testNamespace";
|
||||||
|
private final String testServiceName = "testServiceName";
|
||||||
|
private final String polarisConfigPropertySourceName = "polaris-config";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadConfigDataInternalConfigFilesTest() {
|
||||||
|
try (MockedStatic<ConfigFileServiceFactory> mockedStatic = mockStatic(ConfigFileServiceFactory.class)) {
|
||||||
|
ConfigDataLoaderContext context = mock(ConfigDataLoaderContext.class);
|
||||||
|
PolarisConfigDataResource polarisConfigDataResource = mock(PolarisConfigDataResource.class);
|
||||||
|
ConfigurableBootstrapContext bootstrapContext = mock(ConfigurableBootstrapContext.class);
|
||||||
|
PolarisConfigProperties polarisConfigProperties = mock(PolarisConfigProperties.class);
|
||||||
|
PolarisContextProperties polarisContextProperties = mock(PolarisContextProperties.class);
|
||||||
|
ConfigFileService configFileService = mock(ConfigFileService.class);
|
||||||
|
Profiles profiles = mock(Profiles.class);
|
||||||
|
Map<String, Object> emptyMap = new HashMap<>();
|
||||||
|
ConfigKVFile emptyConfigFile = new MockedConfigKVFile(emptyMap);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application.yml")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "bootstrap.properties")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yml")).thenReturn(emptyConfigFile);
|
||||||
|
Map<String, Object> applicationProperties = new HashMap<>();
|
||||||
|
applicationProperties.put("k1", "v1");
|
||||||
|
applicationProperties.put("k2", "v2");
|
||||||
|
applicationProperties.put("k3", "v3");
|
||||||
|
ConfigKVFile propertiesFile = new MockedConfigKVFile(applicationProperties);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "application.properties"))
|
||||||
|
.thenReturn(propertiesFile);
|
||||||
|
when(context.getBootstrapContext()).thenReturn(bootstrapContext);
|
||||||
|
when(bootstrapContext.get(eq(SDKContext.class))).thenReturn(sdkContext);
|
||||||
|
|
||||||
|
when(bootstrapContext.get(eq(PolarisPropertySourceManager.class))).thenReturn(new PolarisPropertySourceManager());
|
||||||
|
|
||||||
|
when(polarisContextProperties.getNamespace()).thenReturn(testNamespace);
|
||||||
|
when(polarisContextProperties.getService()).thenReturn(testServiceName);
|
||||||
|
|
||||||
|
when(polarisConfigProperties.getGroups()).thenReturn(null);
|
||||||
|
when(profiles.getActive()).thenReturn(Lists.newArrayList());
|
||||||
|
|
||||||
|
PolarisConfigDataLoader polarisConfigDataLoader = new PolarisConfigDataLoader(new DeferredLogs());
|
||||||
|
if (INTERNAL_CONFIG_FILES_LOADED.get()) {
|
||||||
|
INTERNAL_CONFIG_FILES_LOADED.compareAndSet(true, false);
|
||||||
|
}
|
||||||
|
if (CUSTOM_POLARIS_CONFIG_FILE_LOADED.get()) {
|
||||||
|
CUSTOM_POLARIS_CONFIG_FILE_LOADED.compareAndSet(true, false);
|
||||||
|
}
|
||||||
|
when(polarisConfigDataResource.getPolarisConfigProperties()).thenReturn(polarisConfigProperties);
|
||||||
|
when(polarisConfigDataResource.getPolarisContextProperties()).thenReturn(polarisContextProperties);
|
||||||
|
when(polarisConfigDataResource.getServiceName()).thenReturn(testServiceName);
|
||||||
|
when(polarisConfigDataResource.getProfiles()).thenReturn(profiles);
|
||||||
|
|
||||||
|
mockedStatic.when(() -> {
|
||||||
|
ConfigFileServiceFactory.createConfigFileService(sdkContext);
|
||||||
|
}).thenReturn(configFileService);
|
||||||
|
|
||||||
|
ConfigData configData = polarisConfigDataLoader.load(context, polarisConfigDataResource);
|
||||||
|
List<PropertySource<?>> propertySources = configData.getPropertySources();
|
||||||
|
CompositePropertySource compositePropertySource = new CompositePropertySource(polarisConfigPropertySourceName);
|
||||||
|
propertySources.forEach(compositePropertySource::addPropertySource);
|
||||||
|
Assert.assertEquals("v1", compositePropertySource.getProperty("k1"));
|
||||||
|
Assert.assertEquals("v2", compositePropertySource.getProperty("k2"));
|
||||||
|
Assert.assertEquals("v3", compositePropertySource.getProperty("k3"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadConfigDataInternalConfigFilesTestWithProfile() {
|
||||||
|
try (MockedStatic<ConfigFileServiceFactory> mockedStatic = mockStatic(ConfigFileServiceFactory.class)) {
|
||||||
|
ConfigDataLoaderContext context = mock(ConfigDataLoaderContext.class);
|
||||||
|
PolarisConfigDataResource polarisConfigDataResource = mock(PolarisConfigDataResource.class);
|
||||||
|
ConfigurableBootstrapContext bootstrapContext = mock(ConfigurableBootstrapContext.class);
|
||||||
|
PolarisConfigProperties polarisConfigProperties = mock(PolarisConfigProperties.class);
|
||||||
|
PolarisContextProperties polarisContextProperties = mock(PolarisContextProperties.class);
|
||||||
|
ConfigFileService configFileService = mock(ConfigFileService.class);
|
||||||
|
Profiles profiles = mock(Profiles.class);
|
||||||
|
Map<String, Object> applicationProperties = new HashMap<>();
|
||||||
|
applicationProperties.put("k1", "v1");
|
||||||
|
applicationProperties.put("k2", "v2");
|
||||||
|
applicationProperties.put("k3", "v3");
|
||||||
|
ConfigKVFile propertiesFile = new MockedConfigKVFile(applicationProperties);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "application.properties"))
|
||||||
|
.thenReturn(propertiesFile);
|
||||||
|
|
||||||
|
// application-dev.properties
|
||||||
|
Map<String, Object> devProperties = new HashMap<>();
|
||||||
|
devProperties.put("k1", "v11");
|
||||||
|
ConfigKVFile devFile = new MockedConfigKVFile(devProperties);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "application-dev.properties"))
|
||||||
|
.thenReturn(devFile);
|
||||||
|
|
||||||
|
Map<String, Object> emptyMap = new HashMap<>();
|
||||||
|
ConfigKVFile emptyConfigFile = new MockedConfigKVFile(emptyMap);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application.yml")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application-dev.yml")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "bootstrap.properties")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "bootstrap-dev.properties")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yml")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap-dev.yml")).thenReturn(emptyConfigFile);
|
||||||
|
|
||||||
|
when(polarisConfigProperties.getGroups()).thenReturn(null);
|
||||||
|
when(polarisConfigProperties.getGroups()).thenReturn(null);
|
||||||
|
List<String> active = new ArrayList<>();
|
||||||
|
active.add("dev");
|
||||||
|
when(profiles.getActive()).thenReturn(active);
|
||||||
|
|
||||||
|
when(context.getBootstrapContext()).thenReturn(bootstrapContext);
|
||||||
|
when(bootstrapContext.get(eq(SDKContext.class))).thenReturn(sdkContext);
|
||||||
|
when(bootstrapContext.get(eq(PolarisPropertySourceManager.class))).thenReturn(new PolarisPropertySourceManager());
|
||||||
|
|
||||||
|
when(polarisContextProperties.getNamespace()).thenReturn(testNamespace);
|
||||||
|
when(polarisContextProperties.getService()).thenReturn(testServiceName);
|
||||||
|
|
||||||
|
when(polarisConfigProperties.getGroups()).thenReturn(null);
|
||||||
|
|
||||||
|
PolarisConfigDataLoader polarisConfigDataLoader = new PolarisConfigDataLoader(new DeferredLogs());
|
||||||
|
if (INTERNAL_CONFIG_FILES_LOADED.get()) {
|
||||||
|
INTERNAL_CONFIG_FILES_LOADED.compareAndSet(true, false);
|
||||||
|
}
|
||||||
|
if (CUSTOM_POLARIS_CONFIG_FILE_LOADED.get()) {
|
||||||
|
CUSTOM_POLARIS_CONFIG_FILE_LOADED.compareAndSet(true, false);
|
||||||
|
}
|
||||||
|
when(polarisConfigDataResource.getPolarisConfigProperties()).thenReturn(polarisConfigProperties);
|
||||||
|
when(polarisConfigDataResource.getPolarisContextProperties()).thenReturn(polarisContextProperties);
|
||||||
|
when(polarisConfigDataResource.getServiceName()).thenReturn(testServiceName);
|
||||||
|
when(polarisConfigDataResource.getProfiles()).thenReturn(profiles);
|
||||||
|
|
||||||
|
mockedStatic.when(() -> {
|
||||||
|
ConfigFileServiceFactory.createConfigFileService(sdkContext);
|
||||||
|
}).thenReturn(configFileService);
|
||||||
|
|
||||||
|
ConfigData configData = polarisConfigDataLoader.load(context, polarisConfigDataResource);
|
||||||
|
List<PropertySource<?>> propertySources = configData.getPropertySources();
|
||||||
|
|
||||||
|
CompositePropertySource compositePropertySource = new CompositePropertySource(polarisConfigPropertySourceName);
|
||||||
|
propertySources.forEach(compositePropertySource::addPropertySource);
|
||||||
|
|
||||||
|
Assert.assertEquals("v11", compositePropertySource.getProperty("k1"));
|
||||||
|
Assert.assertEquals("v2", compositePropertySource.getProperty("k2"));
|
||||||
|
Assert.assertEquals("v3", compositePropertySource.getProperty("k3"));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadConfigDataCustomConfigFilesTestWithProfile() {
|
||||||
|
try (MockedStatic<ConfigFileServiceFactory> mockedStatic = mockStatic(ConfigFileServiceFactory.class)) {
|
||||||
|
ConfigDataLoaderContext context = mock(ConfigDataLoaderContext.class);
|
||||||
|
PolarisConfigDataResource polarisConfigDataResource = mock(PolarisConfigDataResource.class);
|
||||||
|
ConfigurableBootstrapContext bootstrapContext = mock(ConfigurableBootstrapContext.class);
|
||||||
|
PolarisConfigProperties polarisConfigProperties = mock(PolarisConfigProperties.class);
|
||||||
|
PolarisContextProperties polarisContextProperties = mock(PolarisContextProperties.class);
|
||||||
|
ConfigFileService configFileService = mock(ConfigFileService.class);
|
||||||
|
Profiles profiles = mock(Profiles.class);
|
||||||
|
Map<String, Object> emptyMap = new HashMap<>();
|
||||||
|
ConfigKVFile emptyConfigFile = new MockedConfigKVFile(emptyMap);
|
||||||
|
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "application.properties")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "application.yml")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, testServiceName, "bootstrap.properties")).thenReturn(emptyConfigFile);
|
||||||
|
when(configFileService.getConfigYamlFile(testNamespace, testServiceName, "bootstrap.yml")).thenReturn(emptyConfigFile);
|
||||||
|
|
||||||
|
String customGroup = "group1";
|
||||||
|
String customFile1 = "file1.properties";
|
||||||
|
when(polarisConfigDataResource.getFileName()).thenReturn(customFile1);
|
||||||
|
when(polarisConfigDataResource.getGroupName()).thenReturn(customGroup);
|
||||||
|
|
||||||
|
when(polarisConfigProperties.getGroups()).thenReturn(null);
|
||||||
|
when(profiles.getActive()).thenReturn(Lists.newArrayList());
|
||||||
|
|
||||||
|
// file1.properties
|
||||||
|
Map<String, Object> file1Map = new HashMap<>();
|
||||||
|
file1Map.put("k1", "v1");
|
||||||
|
file1Map.put("k2", "v2");
|
||||||
|
file1Map.put("k3", "v3");
|
||||||
|
ConfigKVFile file1 = new MockedConfigKVFile(file1Map);
|
||||||
|
when(configFileService.getConfigPropertiesFile(testNamespace, customGroup, customFile1)).thenReturn(file1);
|
||||||
|
|
||||||
|
when(context.getBootstrapContext()).thenReturn(bootstrapContext);
|
||||||
|
when(bootstrapContext.get(eq(SDKContext.class))).thenReturn(sdkContext);
|
||||||
|
|
||||||
|
when(bootstrapContext.get(eq(PolarisPropertySourceManager.class))).thenReturn(new PolarisPropertySourceManager());
|
||||||
|
|
||||||
|
when(polarisContextProperties.getNamespace()).thenReturn(testNamespace);
|
||||||
|
when(polarisContextProperties.getService()).thenReturn(testServiceName);
|
||||||
|
|
||||||
|
when(polarisConfigProperties.getGroups()).thenReturn(null);
|
||||||
|
when(profiles.getActive()).thenReturn(Lists.newArrayList());
|
||||||
|
|
||||||
|
PolarisConfigDataLoader polarisConfigDataLoader = new PolarisConfigDataLoader(new DeferredLogs());
|
||||||
|
|
||||||
|
if (INTERNAL_CONFIG_FILES_LOADED.get()) {
|
||||||
|
INTERNAL_CONFIG_FILES_LOADED.compareAndSet(true, false);
|
||||||
|
}
|
||||||
|
if (CUSTOM_POLARIS_CONFIG_FILE_LOADED.get()) {
|
||||||
|
CUSTOM_POLARIS_CONFIG_FILE_LOADED.compareAndSet(true, false);
|
||||||
|
}
|
||||||
|
when(polarisConfigDataResource.getPolarisConfigProperties()).thenReturn(polarisConfigProperties);
|
||||||
|
when(polarisConfigDataResource.getPolarisContextProperties()).thenReturn(polarisContextProperties);
|
||||||
|
when(polarisConfigDataResource.getServiceName()).thenReturn(testServiceName);
|
||||||
|
when(polarisConfigDataResource.getProfiles()).thenReturn(profiles);
|
||||||
|
|
||||||
|
mockedStatic.when(() -> {
|
||||||
|
ConfigFileServiceFactory.createConfigFileService(sdkContext);
|
||||||
|
}).thenReturn(configFileService);
|
||||||
|
|
||||||
|
ConfigData configData = polarisConfigDataLoader.load(context, polarisConfigDataResource);
|
||||||
|
List<PropertySource<?>> propertySources = configData.getPropertySources();
|
||||||
|
CompositePropertySource compositePropertySource = new CompositePropertySource(polarisConfigPropertySourceName);
|
||||||
|
propertySources.forEach(compositePropertySource::addPropertySource);
|
||||||
|
|
||||||
|
Assert.assertEquals("v1", compositePropertySource.getProperty("k1"));
|
||||||
|
Assert.assertEquals("v2", compositePropertySource.getProperty("k2"));
|
||||||
|
Assert.assertEquals("v3", compositePropertySource.getProperty("k3"));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void afterAll() {
|
||||||
|
if (sdkContext != null) {
|
||||||
|
sdkContext.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.configdata;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.config.ConfigDataLocation;
|
||||||
|
import org.springframework.boot.context.config.ConfigDataLocationResolverContext;
|
||||||
|
import org.springframework.boot.context.properties.bind.Binder;
|
||||||
|
import org.springframework.boot.logging.DeferredLogs;
|
||||||
|
import org.springframework.mock.env.MockEnvironment;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@link PolarisConfigDataLocationResolver}.
|
||||||
|
*
|
||||||
|
* @author wlx
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class PolarisConfigDataLocationResolverTest {
|
||||||
|
|
||||||
|
private final PolarisConfigDataLocationResolver resolver = new PolarisConfigDataLocationResolver(new DeferredLogs());
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ConfigDataLocationResolverContext context;
|
||||||
|
|
||||||
|
private final MockEnvironment environment = new MockEnvironment();
|
||||||
|
|
||||||
|
private final Binder environmentBinder = Binder.get(this.environment);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsResolvable() {
|
||||||
|
when(context.getBinder()).thenReturn(environmentBinder);
|
||||||
|
assertThat(
|
||||||
|
this.resolver.isResolvable(this.context, ConfigDataLocation.of("configserver:")))
|
||||||
|
.isFalse();
|
||||||
|
assertThat(
|
||||||
|
this.resolver.isResolvable(this.context, ConfigDataLocation.of("polaris:")))
|
||||||
|
.isTrue();
|
||||||
|
assertThat(
|
||||||
|
this.resolver.isResolvable(this.context, ConfigDataLocation.of("polaris")))
|
||||||
|
.isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unEnabledPolarisConfigData() {
|
||||||
|
environment.setProperty("spring.cloud.polaris.config.enabled", "false");
|
||||||
|
when(context.getBinder()).thenReturn(environmentBinder);
|
||||||
|
assertThat(
|
||||||
|
this.resolver.isResolvable(this.context, ConfigDataLocation.of("polaris:")))
|
||||||
|
.isFalse();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.configdata;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.mock.env.MockEnvironment;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@link PolarisConfigDataMissingEnvironmentPostProcessor}.
|
||||||
|
*
|
||||||
|
* @author wlx
|
||||||
|
*/
|
||||||
|
public class PolarisConfigDataMissingEnvironmentPostProcessorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void missConfigData() {
|
||||||
|
MockEnvironment environment = new MockEnvironment();
|
||||||
|
SpringApplication app = mock(SpringApplication.class);
|
||||||
|
PolarisConfigDataMissingEnvironmentPostProcessor processor = new PolarisConfigDataMissingEnvironmentPostProcessor();
|
||||||
|
assertThatThrownBy(() -> processor.postProcessEnvironment(environment, app))
|
||||||
|
.isInstanceOf(PolarisConfigDataMissingEnvironmentPostProcessor.ImportException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bootstrapEnabledTest() {
|
||||||
|
MockEnvironment environment = new MockEnvironment();
|
||||||
|
environment.setProperty("spring.cloud.bootstrap.enabled", "true");
|
||||||
|
SpringApplication app = mock(SpringApplication.class);
|
||||||
|
PolarisConfigDataMissingEnvironmentPostProcessor processor = new PolarisConfigDataMissingEnvironmentPostProcessor();
|
||||||
|
// if bootstrap enabled,don't throw ImportException
|
||||||
|
assertThatCode(() -> processor.postProcessEnvironment(environment, app)).doesNotThrowAnyException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void legacyProcessingTest() {
|
||||||
|
MockEnvironment environment = new MockEnvironment();
|
||||||
|
environment.setProperty("spring.config.use-legacy-processing", "true");
|
||||||
|
SpringApplication app = mock(SpringApplication.class);
|
||||||
|
PolarisConfigDataMissingEnvironmentPostProcessor processor = new PolarisConfigDataMissingEnvironmentPostProcessor();
|
||||||
|
// if use-legacy-processing,don't throw ImportException
|
||||||
|
assertThatCode(() -> processor.postProcessEnvironment(environment, app)).doesNotThrowAnyException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void closeImportCheck() {
|
||||||
|
MockEnvironment environment = new MockEnvironment();
|
||||||
|
environment.setProperty("spring.cloud.polaris.config.import-check.enabled", "false");
|
||||||
|
SpringApplication app = mock(SpringApplication.class);
|
||||||
|
PolarisConfigDataMissingEnvironmentPostProcessor processor = new PolarisConfigDataMissingEnvironmentPostProcessor();
|
||||||
|
// if import-check.enabled is false,don't throw ImportException
|
||||||
|
assertThatCode(() -> processor.postProcessEnvironment(environment, app)).doesNotThrowAnyException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void closePolarisConfig() {
|
||||||
|
MockEnvironment environment = new MockEnvironment();
|
||||||
|
environment.setProperty("spring.cloud.polaris.config.enabled", "false");
|
||||||
|
SpringApplication app = mock(SpringApplication.class);
|
||||||
|
PolarisConfigDataMissingEnvironmentPostProcessor processor = new PolarisConfigDataMissingEnvironmentPostProcessor();
|
||||||
|
// if polaris.config is false,don't throw ImportException
|
||||||
|
assertThatCode(() -> processor.postProcessEnvironment(environment, app)).doesNotThrowAnyException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void normalConfigDataImport() {
|
||||||
|
MockEnvironment environment = new MockEnvironment();
|
||||||
|
environment.setProperty("spring.config.import", "polaris");
|
||||||
|
SpringApplication app = mock(SpringApplication.class);
|
||||||
|
PolarisConfigDataMissingEnvironmentPostProcessor processor = new PolarisConfigDataMissingEnvironmentPostProcessor();
|
||||||
|
// config polaris config import ,don't throw ImportException
|
||||||
|
assertThatCode(() -> processor.postProcessEnvironment(environment, app)).doesNotThrowAnyException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void importOtherConfigDataWithoutPolaris() {
|
||||||
|
MockEnvironment environment = new MockEnvironment();
|
||||||
|
environment.setProperty("spring.config.import", "file:application.properties");
|
||||||
|
SpringApplication app = mock(SpringApplication.class);
|
||||||
|
PolarisConfigDataMissingEnvironmentPostProcessor processor = new PolarisConfigDataMissingEnvironmentPostProcessor();
|
||||||
|
assertThatThrownBy(() -> processor.postProcessEnvironment(environment, app))
|
||||||
|
.isInstanceOf(PolarisConfigDataMissingEnvironmentPostProcessor.ImportException.class);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.configdata;
|
||||||
|
|
||||||
|
import com.tencent.polaris.api.utils.StringUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.diagnostics.FailureAnalysis;
|
||||||
|
import org.springframework.mock.env.MockEnvironment;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@link PolarisImportExceptionFailureAnalyzer}.
|
||||||
|
*
|
||||||
|
* @author wlx
|
||||||
|
*/
|
||||||
|
public class PolarisImportExceptionFailureAnalyzerTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void failureAnalyzerTest() {
|
||||||
|
SpringApplication app = mock(SpringApplication.class);
|
||||||
|
MockEnvironment environment = new MockEnvironment();
|
||||||
|
PolarisConfigDataMissingEnvironmentPostProcessor processor = new PolarisConfigDataMissingEnvironmentPostProcessor();
|
||||||
|
assertThatThrownBy(() -> processor.postProcessEnvironment(environment, app))
|
||||||
|
.isInstanceOf(PolarisConfigDataMissingEnvironmentPostProcessor.ImportException.class);
|
||||||
|
Throwable throwable = catchThrowable(() -> processor.postProcessEnvironment(environment, app));
|
||||||
|
PolarisImportExceptionFailureAnalyzer failureAnalyzer = new PolarisImportExceptionFailureAnalyzer();
|
||||||
|
FailureAnalysis analyze = failureAnalyzer.analyze(throwable);
|
||||||
|
assertThat(StringUtils.isNotBlank(analyze.getAction())).isTrue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>spring-cloud-tencent-examples</artifactId>
|
||||||
|
<groupId>com.tencent.cloud</groupId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>polaris-config-data-example</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Cloud Tencent dependency -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.tencent.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-tencent-polaris-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-sources</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.example;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the endpoint for get config.
|
||||||
|
*
|
||||||
|
* @author lepdou 2022-03-10
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RefreshScope
|
||||||
|
public class ConfigController {
|
||||||
|
|
||||||
|
@Value("${timeout:1000}")
|
||||||
|
private int timeout;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Person person;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Environment environment;
|
||||||
|
|
||||||
|
@GetMapping("/timeout")
|
||||||
|
public int timeout() {
|
||||||
|
environment.getProperty("timeout", "1000");
|
||||||
|
return timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/person")
|
||||||
|
public String person() {
|
||||||
|
return person.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.example;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* example property object.
|
||||||
|
*
|
||||||
|
* @author lepdou 2022-03-28
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "teacher")
|
||||||
|
public class Person {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private int age;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAge(int age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "User{" + "name='" + name + '\'' + ", age=" + age + '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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.config.example;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.tencent.cloud.polaris.config.annotation.PolarisConfigKVFileChangeListener;
|
||||||
|
import com.tencent.cloud.polaris.config.listener.ConfigChangeEvent;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom Config Listener Example .
|
||||||
|
*
|
||||||
|
* @author Palmer Xu 2022-06-06
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public final class PersonConfigChangeListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PolarisConfigKVFileChangeListener Example .
|
||||||
|
* @param event instance of {@link ConfigChangeEvent}
|
||||||
|
*/
|
||||||
|
@PolarisConfigKVFileChangeListener(interestedKeyPrefixes = "teacher")
|
||||||
|
public void onChange(ConfigChangeEvent event) {
|
||||||
|
Set<String> changedKeys = event.changedKeys();
|
||||||
|
|
||||||
|
for (String changedKey : changedKeys) {
|
||||||
|
System.out.printf("%s = %s \n", changedKey, event.getChange(changedKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.tencent.cloud.polaris.config.example;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wlx
|
||||||
|
* @date 2022/7/6 9:15 下午
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class PolarisConfigDataExampleApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(PolarisConfigDataExampleApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
server:
|
||||||
|
port: 48085
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: polaris-config-data-example
|
||||||
|
cloud:
|
||||||
|
polaris:
|
||||||
|
address: grpc://183.47.111.80:8091
|
||||||
|
namespace: default
|
||||||
|
config:
|
||||||
|
auto-refresh: true # auto refresh when config file changed
|
||||||
|
groups:
|
||||||
|
- name: ${spring.application.name} # group name
|
||||||
|
files: [ "config/application.properties", "config/bootstrap.yml" ]
|
||||||
|
config:
|
||||||
|
import:
|
||||||
|
- optional:polaris
|
||||||
|
- optional:polaris:test.yml
|
||||||
|
- optional:polaris:configdataexample:test.yml
|
||||||
|
- optional:polaris:config/bootstrap.yml
|
||||||
|
management:
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
exposure:
|
||||||
|
include:
|
||||||
|
- polaris-config
|
Loading…
Reference in new issue