me.ahoo.govern.config.spring.cloud.GovernPropertySourceLocator Maven / Gradle / Ivy
The newest version!
package me.ahoo.govern.config.spring.cloud;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import me.ahoo.govern.config.Config;
import me.ahoo.govern.config.ConfigService;
import me.ahoo.govern.core.Consts;
import me.ahoo.govern.core.NamespacedContext;
import me.ahoo.govern.core.util.Futures;
import org.apache.logging.log4j.util.Strings;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.boot.env.PropertySourceLoader;
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.util.CollectionUtils;
import java.util.*;
/**
* @author ahoo wang
*/
@Slf4j
public class GovernPropertySourceLocator implements PropertySourceLocator {
private final List propertySourceLoaders;
private final ConfigService configService;
private final GovernConfigProperties configProperties;
public GovernPropertySourceLocator(GovernConfigProperties configProperties, ConfigService configService) {
this.configService = configService;
this.configProperties = configProperties;
propertySourceLoaders = SpringFactoriesLoader
.loadFactories(PropertySourceLoader.class, GovernPropertySourceLocator.class.getClassLoader());
}
/**
* @param environment The current Environment.
* @return A PropertySource, or null if there is none.
* @throws IllegalStateException if there is a fail-fast condition.
*/
@Override
public PropertySource> locate(Environment environment) {
var configId = configProperties.getConfigId();
var fileExt = Files.getFileExtension(configId);
if (Strings.isBlank(fileExt)) {
fileExt = configProperties.getFileExtension();
}
var namespace = NamespacedContext.GLOBAL.getNamespace();
log.info("locate - configId:[{}] @ namespace:[{}]", configId, namespace);
var config = Futures.getUnChecked(configService.getConfig(configId), configProperties.getTimeout());
if (Objects.isNull(config)) {
log.warn("locate - can not find configId:[{}] @ namespace:[{}]", configId, namespace);
return new OriginTrackedMapPropertySource(getNameOfConfigId(configId), Collections.emptyMap());
}
var sourceLoader = ensureSourceLoader(fileExt);
var governPropertySource = getGovernPropertySourceOfConfig(sourceLoader, config);
return governPropertySource;
}
public PropertySourceLoader ensureSourceLoader(String fileExtension) {
var sourceLoaderOptional = propertySourceLoaders
.stream()
.filter(propertySourceLoader ->
Arrays.stream(propertySourceLoader.getFileExtensions())
.anyMatch(fileExt -> fileExt.equals(fileExtension)))
.findFirst();
if (!sourceLoaderOptional.isPresent()) {
throw new IllegalArgumentException(String.format("can not find fileExtension:[%s] PropertySourceLoader.", fileExtension));
}
return sourceLoaderOptional.get();
}
/**
* @param sourceLoader
* @param config
* @return
*/
@SneakyThrows
public OriginTrackedMapPropertySource getGovernPropertySourceOfConfig(PropertySourceLoader sourceLoader, Config config) {
ByteArrayResource byteArrayResource = new ByteArrayResource(config.getData().getBytes(Charsets.UTF_8));
List> propertySourceList = sourceLoader.load(config.getConfigId(), byteArrayResource);
Map source = getMapSource(config.getConfigId(), propertySourceList);
return new OriginTrackedMapPropertySource(getNameOfConfigId(config.getConfigId()), source);
}
private Map getMapSource(String configId, List> propertySourceList) {
if (CollectionUtils.isEmpty(propertySourceList)) {
return Collections.emptyMap();
}
if (propertySourceList.size() == 1) {
PropertySource propertySource = propertySourceList.get(0);
if (propertySource != null && propertySource.getSource() instanceof Map) {
return (Map) propertySource.getSource();
}
}
return Collections.singletonMap(
getNameOfConfigId(configId),
propertySourceList);
}
public static String getNameOfConfigId(String configId) {
return Consts.GOVERN + ":" + configId;
}
}