io.servicecomb.config.ConfigUtil.java Source code

Java tutorial

Introduction

Here is the source code for io.servicecomb.config.ConfigUtil.java

Source

/*
 * Copyright 2017 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 io.servicecomb.config;

import static io.servicecomb.foundation.common.base.ServiceCombConstants.CONFIG_CSE_PREFIX;
import static io.servicecomb.foundation.common.base.ServiceCombConstants.CONFIG_SERVICECOMB_PREFIX;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.configuration.AbstractConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.EnvironmentConfiguration;
import org.apache.commons.configuration.SystemConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.netflix.config.ConcurrentCompositeConfiguration;
import com.netflix.config.ConcurrentMapConfiguration;
import com.netflix.config.ConfigurationManager;
import com.netflix.config.DynamicConfiguration;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicWatchedConfiguration;
import com.netflix.config.WatchedUpdateListener;
import com.netflix.config.WatchedUpdateResult;

import io.servicecomb.config.archaius.scheduler.NeverStartPollingScheduler;
import io.servicecomb.config.archaius.sources.ConfigModel;
import io.servicecomb.config.archaius.sources.MicroserviceConfigLoader;
import io.servicecomb.config.archaius.sources.MicroserviceConfigurationSource;
import io.servicecomb.config.spi.ConfigCenterConfigurationSource;
import io.servicecomb.foundation.common.utils.SPIServiceUtils;

public final class ConfigUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(ConfigUtil.class);

    protected static final String configCenterUrlKey = "cse.config.client.serverUri";

    private static final String MICROSERVICE_CONFIG_LOADER_KEY = "cse-microservice-config-loader";

    private ConfigUtil() {
    }

    public static Object getProperty(String key) {
        Object config = DynamicPropertyFactory.getBackingConfigurationSource();
        return getProperty(config, key);
    }

    public static Object getProperty(Object config, String key) {
        if (null != config && Configuration.class.isInstance(config)) {
            Configuration configuration = (Configuration) config;
            return configuration.getProperty(key);
        }
        return null;
    }

    private static void setMicroserviceConfigLoader(Configuration config, MicroserviceConfigLoader loader) {
        config.setProperty(MICROSERVICE_CONFIG_LOADER_KEY, loader);
    }

    public static MicroserviceConfigLoader getMicroserviceConfigLoader() {
        return (MicroserviceConfigLoader) getProperty(MICROSERVICE_CONFIG_LOADER_KEY);
    }

    public static MicroserviceConfigLoader getMicroserviceConfigLoader(Configuration config) {
        return (MicroserviceConfigLoader) getProperty(config, MICROSERVICE_CONFIG_LOADER_KEY);
    }

    public static ConcurrentCompositeConfiguration createLocalConfig() {
        MicroserviceConfigLoader loader = new MicroserviceConfigLoader();
        loader.loadAndSort();

        LOGGER.info("create local config:");
        for (ConfigModel configModel : loader.getConfigModels()) {
            LOGGER.info(" {}.", configModel.getUrl());
        }

        ConcurrentCompositeConfiguration config = ConfigUtil.createLocalConfig(loader.getConfigModels());
        ConfigUtil.setMicroserviceConfigLoader(config, loader);
        return config;
    }

    public static ConcurrentCompositeConfiguration createLocalConfig(List<ConfigModel> configModelList) {
        ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration();

        duplicateServiceCombConfigToCse(config, new ConcurrentMapConfiguration(new SystemConfiguration()),
                "configFromSystem");
        duplicateServiceCombConfigToCse(config, new ConcurrentMapConfiguration(new EnvironmentConfiguration()),
                "configFromEnvironment");
        duplicateServiceCombConfigToCse(config,
                new DynamicConfiguration(new MicroserviceConfigurationSource(configModelList),
                        new NeverStartPollingScheduler()),
                "configFromYamlFile");

        return config;
    }

    //inject a copy of cse.xxx for servicecomb.xxx
    private static void duplicateServiceCombConfigToCse(AbstractConfiguration source) {
        Iterator<String> keys = source.getKeys();
        while (keys.hasNext()) {
            String key = keys.next();
            if (!key.startsWith(CONFIG_SERVICECOMB_PREFIX)) {
                continue;
            }

            String cseKey = CONFIG_CSE_PREFIX + key.substring(key.indexOf(".") + 1);
            source.addProperty(cseKey, source.getProperty(key));
        }
    }

    private static void duplicateServiceCombConfigToCse(ConcurrentCompositeConfiguration compositeConfiguration,
            AbstractConfiguration source, String sourceName) {
        duplicateServiceCombConfigToCse(source);

        compositeConfiguration.addConfiguration(source, sourceName);
    }

    public static DynamicWatchedConfiguration createConfigFromConfigCenter(Configuration localConfiguration) {
        if (localConfiguration.getProperty(configCenterUrlKey) == null) {
            LOGGER.info("config center URL is missing, skip to load configuration from config center");
            return null;
        }

        ConfigCenterConfigurationSource configCenterConfigurationSource = SPIServiceUtils
                .getTargetService(ConfigCenterConfigurationSource.class);
        if (null == configCenterConfigurationSource) {
            LOGGER.info("config center SPI service can not find, skip to load configuration from config center");
            return null;
        }

        configCenterConfigurationSource.init(localConfiguration);
        return new DynamicWatchedConfiguration(configCenterConfigurationSource);
    }

    public static AbstractConfiguration createDynamicConfig() {
        LOGGER.info("create dynamic config:");
        ConcurrentCompositeConfiguration config = ConfigUtil.createLocalConfig();
        DynamicWatchedConfiguration configFromConfigCenter = createConfigFromConfigCenter(config);
        if (configFromConfigCenter != null) {
            ConcurrentMapConfiguration injectConfig = new ConcurrentMapConfiguration();
            config.addConfigurationAtFront(injectConfig, "extraInjectConfig");

            duplicateServiceCombConfigToCse(configFromConfigCenter);
            config.addConfigurationAtFront(configFromConfigCenter, "configCenterConfig");

            configFromConfigCenter.getSource()
                    .addUpdateListener(new ServiceCombPropertyUpdateListener(injectConfig));
        }

        return config;
    }

    public static void installDynamicConfig() {
        if (ConfigurationManager.isConfigurationInstalled()) {
            LOGGER.warn("Configuration installed by others, will ignore this configuration.");
            return;
        }

        AbstractConfiguration dynamicConfig = ConfigUtil.createDynamicConfig();
        ConfigurationManager.install(dynamicConfig);
    }

    private static class ServiceCombPropertyUpdateListener implements WatchedUpdateListener {

        private final ConcurrentMapConfiguration injectConfig;

        ServiceCombPropertyUpdateListener(ConcurrentMapConfiguration injectConfig) {
            this.injectConfig = injectConfig;
        }

        @Override
        public void updateConfiguration(WatchedUpdateResult watchedUpdateResult) {
            Map<String, Object> adds = watchedUpdateResult.getAdded();
            if (adds != null) {
                for (String add : adds.keySet()) {
                    if (add.startsWith(CONFIG_SERVICECOMB_PREFIX)) {
                        String key = CONFIG_CSE_PREFIX + add.substring(add.indexOf(".") + 1);
                        injectConfig.addProperty(key, adds.get(add));
                    }
                }
            }

            Map<String, Object> deletes = watchedUpdateResult.getDeleted();
            if (deletes != null) {
                for (String delete : deletes.keySet()) {
                    if (delete.startsWith(CONFIG_SERVICECOMB_PREFIX)) {
                        injectConfig.clearProperty(CONFIG_CSE_PREFIX + delete.substring(delete.indexOf(".") + 1));
                    }
                }
            }

            Map<String, Object> changes = watchedUpdateResult.getChanged();
            if (changes != null) {
                for (String change : changes.keySet()) {
                    if (change.startsWith(CONFIG_SERVICECOMB_PREFIX)) {
                        String key = CONFIG_CSE_PREFIX + change.substring(change.indexOf(".") + 1);
                        injectConfig.setProperty(key, changes.get(change));
                    }
                }
            }
        }
    }
}