parent
1ce6336f51
commit
ae2974fc5a
@ -0,0 +1,224 @@
|
|||||||
|
package com.tencent.cloud.polaris.config.configdata;
|
||||||
|
|
||||||
|
import com.tencent.cloud.polaris.config.adapter.PolarisPropertySource;
|
||||||
|
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.cloud.polaris.config.enums.ConfigFileFormat;
|
||||||
|
import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
|
||||||
|
import com.tencent.polaris.client.api.SDKContext;
|
||||||
|
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 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.logging.DeferredLogFactory;
|
||||||
|
import org.springframework.core.env.CompositePropertySource;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
public PolarisConfigDataLoader(DeferredLogFactory logFactory) {
|
||||||
|
this.log = logFactory.getLog(getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigData load(ConfigDataLoaderContext context, PolarisConfigDataResource resource)
|
||||||
|
throws IOException, ConfigDataResourceNotFoundException {
|
||||||
|
ConfigurableBootstrapContext bootstrapContext = context.getBootstrapContext();
|
||||||
|
CompositePropertySource compositePropertySource = locate(bootstrapContext, resource);
|
||||||
|
return new ConfigData(compositePropertySource.getPropertySources(),
|
||||||
|
getOptions(context, resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompositePropertySource locate(ConfigurableBootstrapContext bootstrapContext,
|
||||||
|
PolarisConfigDataResource resource) {
|
||||||
|
CompositePropertySource compositePropertySource = new CompositePropertySource(
|
||||||
|
POLARIS_CONFIG_PROPERTY_SOURCE_NAME);
|
||||||
|
|
||||||
|
// load spring boot default config files
|
||||||
|
initInternalConfigFiles(compositePropertySource, bootstrapContext,resource);
|
||||||
|
|
||||||
|
PolarisConfigProperties polarisConfigProperties = bootstrapContext.get(PolarisConfigProperties.class);
|
||||||
|
|
||||||
|
// load custom config files
|
||||||
|
List<ConfigFileGroup> configFileGroups = polarisConfigProperties.getGroups();
|
||||||
|
if (CollectionUtils.isEmpty(configFileGroups)) {
|
||||||
|
return compositePropertySource;
|
||||||
|
}
|
||||||
|
initCustomPolarisConfigFiles(compositePropertySource, configFileGroups, bootstrapContext);
|
||||||
|
|
||||||
|
return compositePropertySource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigData.Option[] getOptions(ConfigDataLoaderContext context,
|
||||||
|
PolarisConfigDataResource resource) {
|
||||||
|
List<ConfigData.Option> options = new ArrayList<>();
|
||||||
|
options.add(IGNORE_IMPORTS);
|
||||||
|
options.add(IGNORE_PROFILES);
|
||||||
|
// mark it as 'PROFILE_SPECIFIC' config, it has higher priority,
|
||||||
|
// will override the none profile specific config.
|
||||||
|
// options.add(PROFILE_SPECIFIC);
|
||||||
|
return options.toArray(new ConfigData.Option[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initInternalConfigFiles(CompositePropertySource compositePropertySource,
|
||||||
|
ConfigurableBootstrapContext bootstrapContext,
|
||||||
|
PolarisConfigDataResource resource) {
|
||||||
|
PolarisPropertySourceManager polarisPropertySourceManager =
|
||||||
|
bootstrapContext.get(PolarisPropertySourceManager.class);
|
||||||
|
List<ConfigFileMetadata> internalConfigFiles = getInternalConfigFiles(bootstrapContext,resource);
|
||||||
|
|
||||||
|
for (ConfigFileMetadata configFile : internalConfigFiles) {
|
||||||
|
PolarisPropertySource polarisPropertySource = loadPolarisPropertySource(bootstrapContext,
|
||||||
|
configFile.getNamespace(), configFile.getFileGroup(), configFile.getFileName());
|
||||||
|
|
||||||
|
compositePropertySource.addPropertySource(polarisPropertySource);
|
||||||
|
|
||||||
|
polarisPropertySourceManager.addPropertySource(polarisPropertySource);
|
||||||
|
|
||||||
|
log.info("[SCT Config] Load and inject polaris config file. file = " + configFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ConfigFileMetadata> getInternalConfigFiles(ConfigurableBootstrapContext bootstrapContext,
|
||||||
|
PolarisConfigDataResource resource) {
|
||||||
|
PolarisContextProperties polarisContextProperties = bootstrapContext.get(PolarisContextProperties.class);
|
||||||
|
String namespace = polarisContextProperties.getNamespace();
|
||||||
|
String serviceName = polarisContextProperties.getService();
|
||||||
|
if (!StringUtils.hasText(serviceName)) {
|
||||||
|
serviceName = resource.getServiceName();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ConfigFileMetadata> internalConfigFiles = new LinkedList<>();
|
||||||
|
|
||||||
|
// priority: application-${profile} > application > boostrap-${profile} > boostrap
|
||||||
|
List<String> activeProfiles = resource.getProfiles().getActive();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initCustomPolarisConfigFiles(CompositePropertySource compositePropertySource,
|
||||||
|
List<ConfigFileGroup> configFileGroups,
|
||||||
|
ConfigurableBootstrapContext bootstrapContext
|
||||||
|
) {
|
||||||
|
PolarisContextProperties polarisContextProperties = bootstrapContext.get(PolarisContextProperties.class);
|
||||||
|
String namespace = polarisContextProperties.getNamespace();
|
||||||
|
PolarisPropertySourceManager polarisPropertySourceManager =
|
||||||
|
bootstrapContext.get(PolarisPropertySourceManager.class);
|
||||||
|
for (ConfigFileGroup configFileGroup : configFileGroups) {
|
||||||
|
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(bootstrapContext,
|
||||||
|
namespace, group, fileName);
|
||||||
|
|
||||||
|
compositePropertySource.addPropertySource(polarisPropertySource);
|
||||||
|
|
||||||
|
polarisPropertySourceManager.addPropertySource(polarisPropertySource);
|
||||||
|
|
||||||
|
String loggerFormat = "[SCT Config] Load and inject polaris config file success. " +
|
||||||
|
"namespace = %s, group = %s, fileName = %s";
|
||||||
|
log.info(String.format(loggerFormat,namespace, group, fileName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private PolarisPropertySource loadPolarisPropertySource(
|
||||||
|
ConfigurableBootstrapContext bootstrapContext,
|
||||||
|
String namespace, String group, String fileName) {
|
||||||
|
|
||||||
|
SDKContext sdkContext = bootstrapContext.get(SDKContext.class);
|
||||||
|
|
||||||
|
ConfigKVFile configKVFile;
|
||||||
|
ConfigFileService configFileService = ConfigFileServiceFactory.createConfigFileService(sdkContext);
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
String loggerFormat = "[SCT Config] Unsupported config file. namespace = %s, group = %s, fileName = %s";
|
||||||
|
log.warn(String.format(loggerFormat,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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,254 @@
|
|||||||
|
package com.tencent.cloud.polaris.config.configdata;
|
||||||
|
|
||||||
|
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.config.ConfigProvider;
|
||||||
|
import com.tencent.polaris.api.utils.CollectionUtils;
|
||||||
|
import com.tencent.polaris.api.utils.StringUtils;
|
||||||
|
import com.tencent.polaris.client.api.SDKContext;
|
||||||
|
import com.tencent.polaris.factory.ConfigAPIFactory;
|
||||||
|
import com.tencent.polaris.factory.config.ConfigurationImpl;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link ConfigDataLocationResolver}, used to resolve {@link ConfigDataLocation locations}
|
||||||
|
* into one or more {@link PolarisConfigDataResource polarisConfigDataResource}.
|
||||||
|
*
|
||||||
|
* @author wlx
|
||||||
|
* @date 2022/7/5 11:16 下午
|
||||||
|
*/
|
||||||
|
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";
|
||||||
|
|
||||||
|
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"
|
||||||
|
);
|
||||||
|
|
||||||
|
PolarisContextProperties polarisContextProperties = loadPolarisConfigProperties(
|
||||||
|
resolverContext,
|
||||||
|
PolarisContextProperties.class,
|
||||||
|
POLARIS_PREFIX
|
||||||
|
);
|
||||||
|
|
||||||
|
prepareAndInitPolaris(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()));
|
||||||
|
|
||||||
|
// stop sdkContext and register PolarisPropertySourceManager to context
|
||||||
|
bootstrapContext.addCloseListener(
|
||||||
|
event -> {
|
||||||
|
event.getApplicationContext().getBeanFactory().registerSingleton(
|
||||||
|
"sdkContext", event.getBootstrapContext().get(SDKContext.class)
|
||||||
|
|
||||||
|
);
|
||||||
|
event.getApplicationContext().getBeanFactory().registerSingleton(
|
||||||
|
"polarisPropertySourceManager",
|
||||||
|
event.getBootstrapContext().get(PolarisPropertySourceManager.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return loadConfigDataResources(resolverContext,
|
||||||
|
location, profiles, polarisConfigProperties, polarisContextProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public <T> T loadPolarisConfigProperties(
|
||||||
|
ConfigDataLocationResolverContext context,
|
||||||
|
Class<T> typeClass,
|
||||||
|
String prefix) {
|
||||||
|
Binder binder = context.getBinder();
|
||||||
|
BindHandler bindHandler = getBindHandler(context);
|
||||||
|
|
||||||
|
T instance;
|
||||||
|
if (context.getBootstrapContext().isRegistered(typeClass)) {
|
||||||
|
instance = context.getBootstrapContext()
|
||||||
|
.get(typeClass);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
instance = binder
|
||||||
|
.bind(POLARIS_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 fileName = location.getNonPrefixedValue(PREFIX);
|
||||||
|
String serviceName = loadPolarisConfigProperties(resolverContext,
|
||||||
|
String.class, "spring.application.name");
|
||||||
|
PolarisConfigDataResource polarisConfigDataResource = new PolarisConfigDataResource(
|
||||||
|
polarisConfigProperties,
|
||||||
|
polarisContextProperties,
|
||||||
|
profiles, optional,
|
||||||
|
fileName,serviceName
|
||||||
|
);
|
||||||
|
result.add(polarisConfigDataResource);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void prepareAndInitPolaris(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 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 SDKContext sdkContext(ConfigDataLocationResolverContext resolverContext,
|
||||||
|
PolarisConfigProperties polarisConfigProperties,
|
||||||
|
PolarisContextProperties polarisContextProperties) {
|
||||||
|
|
||||||
|
// 1. Read user-defined polaris.yml configuration
|
||||||
|
ConfigurationImpl configuration = (ConfigurationImpl) ConfigAPIFactory
|
||||||
|
.defaultConfig(ConfigProvider.DEFAULT_CONFIG);
|
||||||
|
|
||||||
|
// 2. Override user-defined polaris.yml configuration with SCT configuration
|
||||||
|
|
||||||
|
String defaultHost = polarisContextProperties.getLocalIpAddress();
|
||||||
|
if (StringUtils.isBlank(defaultHost)) {
|
||||||
|
defaultHost = loadPolarisConfigProperties(resolverContext, String.class, "spring.cloud.client.ip-address");
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration.getGlobal().getAPI().setBindIP(defaultHost);
|
||||||
|
|
||||||
|
Collection<PolarisConfigModifier> modifiers = modifierList(polarisConfigProperties, polarisContextProperties);
|
||||||
|
modifiers = modifiers.stream()
|
||||||
|
.sorted(Comparator.comparingInt(PolarisConfigModifier::getOrder))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (!CollectionUtils.isEmpty(modifiers)) {
|
||||||
|
for (PolarisConfigModifier modifier : modifiers) {
|
||||||
|
modifier.modify(configuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SDKContext.initContextByConfig(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,98 @@
|
|||||||
|
package com.tencent.cloud.polaris.config.configdata;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 serviceName;
|
||||||
|
|
||||||
|
public PolarisConfigDataResource(PolarisConfigProperties polarisConfigProperties,
|
||||||
|
PolarisContextProperties polarisContextProperties,
|
||||||
|
Profiles profiles,
|
||||||
|
boolean optional,
|
||||||
|
String fileName,
|
||||||
|
String serviceName) {
|
||||||
|
this.polarisConfigProperties = polarisConfigProperties;
|
||||||
|
this.polarisContextProperties = polarisContextProperties;
|
||||||
|
this.profiles = profiles;
|
||||||
|
this.optional = optional;
|
||||||
|
this.fileName = fileName;
|
||||||
|
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 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) &&
|
||||||
|
serviceName.equals(that.serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(polarisConfigProperties, polarisContextProperties, profiles, optional, fileName, serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PolarisConfigDataResource{" +
|
||||||
|
"polarisConfigProperties=" + polarisConfigProperties +
|
||||||
|
", polarisContextProperties=" + polarisContextProperties +
|
||||||
|
", profiles=" + profiles +
|
||||||
|
", optional=" + optional +
|
||||||
|
", fileName='" + fileName + '\'' +
|
||||||
|
", serviceName='" + serviceName + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
<?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>1.6.0-2021.0.3-SNAPSHOT</version>
|
||||||
|
</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,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,23 @@
|
|||||||
|
server:
|
||||||
|
port: 48084
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: polaris-config-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:test.yml
|
||||||
|
management:
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
exposure:
|
||||||
|
include:
|
||||||
|
- polaris-config
|
Loading…
Reference in new issue