All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy