dubbo Environment 源码

  • 2022-10-20
  • 浏览 (474)

dubbo Environment 代码

文件路径:/dubbo-common/src/main/java/org/apache/dubbo/common/config/Environment.java

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.dubbo.common.config;

import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.context.ApplicationExt;
import org.apache.dubbo.common.context.LifecycleAdapter;
import org.apache.dubbo.common.extension.DisableInject;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.ConfigUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.AbstractConfig;
import org.apache.dubbo.config.context.ConfigConfigurationAdapter;
import org.apache.dubbo.rpc.model.ScopeModel;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;

public class Environment extends LifecycleAdapter implements ApplicationExt {
    private static final Logger logger = LoggerFactory.getLogger(Environment.class);

    public static final String NAME = "environment";

    // dubbo properties in classpath
    private PropertiesConfiguration propertiesConfiguration;

    // java system props (-D)
    private SystemConfiguration systemConfiguration;

    // java system environment
    private EnvironmentConfiguration environmentConfiguration;

    // external config, such as config-center global/default config
    private InmemoryConfiguration externalConfiguration;

    // external app config, such as config-center app config
    private InmemoryConfiguration appExternalConfiguration;

    // local app config , such as Spring Environment/PropertySources/application.properties
    private InmemoryConfiguration appConfiguration;

    protected CompositeConfiguration globalConfiguration;

    protected List<Map<String, String>> globalConfigurationMaps;

    private CompositeConfiguration defaultDynamicGlobalConfiguration;

    private DynamicConfiguration defaultDynamicConfiguration;

    private String localMigrationRule;

    private AtomicBoolean initialized = new AtomicBoolean(false);
    private ScopeModel scopeModel;

    public Environment(ScopeModel scopeModel) {
        this.scopeModel = scopeModel;
    }

    @Override
    public void initialize() throws IllegalStateException {
        if (initialized.compareAndSet(false, true)) {
            this.propertiesConfiguration = new PropertiesConfiguration(scopeModel);
            this.systemConfiguration = new SystemConfiguration();
            this.environmentConfiguration = new EnvironmentConfiguration();
            this.externalConfiguration = new InmemoryConfiguration("ExternalConfig");
            this.appExternalConfiguration = new InmemoryConfiguration("AppExternalConfig");
            this.appConfiguration = new InmemoryConfiguration("AppConfig");

            loadMigrationRule();
        }
    }

    /**
     * @deprecated MigrationRule will be removed in 3.1
     */
    @Deprecated
    private void loadMigrationRule() {
        if (Boolean.parseBoolean(System.getProperty(CommonConstants.DUBBO_MIGRATION_FILE_ENABLE, "false"))) {
            String path = System.getProperty(CommonConstants.DUBBO_MIGRATION_KEY);
            if (StringUtils.isEmpty(path)) {
                path = System.getenv(CommonConstants.DUBBO_MIGRATION_KEY);
                if (StringUtils.isEmpty(path)) {
                    path = CommonConstants.DEFAULT_DUBBO_MIGRATION_FILE;
                }
            }
            this.localMigrationRule = ConfigUtils.loadMigrationRule(scopeModel.getClassLoaders(), path);
        } else {
            this.localMigrationRule = null;
        }
    }

    /**
     * @deprecated only for ut
     */
    @Deprecated
    @DisableInject
    public void setLocalMigrationRule(String localMigrationRule) {
        this.localMigrationRule = localMigrationRule;
    }

    @DisableInject
    public void setExternalConfigMap(Map<String, String> externalConfiguration) {
        if (externalConfiguration != null) {
            this.externalConfiguration.setProperties(externalConfiguration);
        }
    }

    @DisableInject
    public void setAppExternalConfigMap(Map<String, String> appExternalConfiguration) {
        if (appExternalConfiguration != null) {
            this.appExternalConfiguration.setProperties(appExternalConfiguration);
        }
    }

    @DisableInject
    public void setAppConfigMap(Map<String, String> appConfiguration) {
        if (appConfiguration != null) {
            this.appConfiguration.setProperties(appConfiguration);
        }
    }

    public Map<String, String> getExternalConfigMap() {
        return externalConfiguration.getProperties();
    }

    public Map<String, String> getAppExternalConfigMap() {
        return appExternalConfiguration.getProperties();
    }

    public Map<String, String> getAppConfigMap() {
        return appConfiguration.getProperties();
    }

    public void updateExternalConfigMap(Map<String, String> externalMap) {
        this.externalConfiguration.addProperties(externalMap);
    }

    public void updateAppExternalConfigMap(Map<String, String> externalMap) {
        this.appExternalConfiguration.addProperties(externalMap);
    }

    /**
     * Merge target map properties into app configuration
     * @param map
     */
    public void updateAppConfigMap(Map<String, String> map) {
        this.appConfiguration.addProperties(map);
    }

    /**
     * At start-up, Dubbo is driven by various configuration, such as Application, Registry, Protocol, etc.
     * All configurations will be converged into a data bus - URL, and then drive the subsequent process.
     * <p>
     * At present, there are many configuration sources, including AbstractConfig (API, XML, annotation), - D, config center, etc.
     * This method helps us t filter out the most priority values from various configuration sources.
     *
     * @param config
     * @param prefix
     * @return
     */
    public Configuration getPrefixedConfiguration(AbstractConfig config, String prefix) {

        // The sequence would be: SystemConfiguration -> EnvironmentConfiguration -> AppExternalConfiguration -> ExternalConfiguration  -> AppConfiguration -> AbstractConfig -> PropertiesConfiguration
        Configuration instanceConfiguration = new ConfigConfigurationAdapter(config, prefix);
        CompositeConfiguration compositeConfiguration = new CompositeConfiguration();
        compositeConfiguration.addConfiguration(systemConfiguration);
        compositeConfiguration.addConfiguration(environmentConfiguration);
        compositeConfiguration.addConfiguration(appExternalConfiguration);
        compositeConfiguration.addConfiguration(externalConfiguration);
        compositeConfiguration.addConfiguration(appConfiguration);
        compositeConfiguration.addConfiguration(instanceConfiguration);
        compositeConfiguration.addConfiguration(propertiesConfiguration);

        return new PrefixedConfiguration(compositeConfiguration, prefix);
    }

    /**
     * There are two ways to get configuration during exposure / reference or at runtime:
     * 1. URL, The value in the URL is relatively fixed. we can get value directly.
     * 2. The configuration exposed in this method is convenient for us to query the latest values from multiple
     * prioritized sources, it also guarantees that configs changed dynamically can take effect on the fly.
     */
    public CompositeConfiguration getConfiguration() {
        if (globalConfiguration == null) {
            CompositeConfiguration configuration = new CompositeConfiguration();
            configuration.addConfiguration(systemConfiguration);
            configuration.addConfiguration(environmentConfiguration);
            configuration.addConfiguration(appExternalConfiguration);
            configuration.addConfiguration(externalConfiguration);
            configuration.addConfiguration(appConfiguration);
            configuration.addConfiguration(propertiesConfiguration);
            globalConfiguration = configuration;
        }
        return globalConfiguration;
    }

    /**
     * Get configuration map list for target instance
     * @param config
     * @param prefix
     * @return
     */
    public List<Map<String, String>> getConfigurationMaps(AbstractConfig config, String prefix) {
        // The sequence would be: SystemConfiguration -> EnvironmentConfiguration -> AppExternalConfiguration -> ExternalConfiguration  -> AppConfiguration -> AbstractConfig -> PropertiesConfiguration

        List<Map<String, String>> maps = new ArrayList<>();
        maps.add(systemConfiguration.getProperties());
        maps.add(environmentConfiguration.getProperties());
        maps.add(appExternalConfiguration.getProperties());
        maps.add(externalConfiguration.getProperties());
        maps.add(appConfiguration.getProperties());
        if (config != null) {
            ConfigConfigurationAdapter configurationAdapter = new ConfigConfigurationAdapter(config, prefix);
            maps.add(configurationAdapter.getProperties());
        }
        maps.add(propertiesConfiguration.getProperties());
        return maps;
    }

    /**
     * Get global configuration as map list
     * @return
     */
    public List<Map<String, String>> getConfigurationMaps() {
        if (globalConfigurationMaps == null) {
            globalConfigurationMaps = getConfigurationMaps(null, null);
        }
        return globalConfigurationMaps;
    }

    @Override
    public void destroy() throws IllegalStateException {
        initialized.set(false);
        systemConfiguration = null;
        propertiesConfiguration = null;
        environmentConfiguration = null;
        externalConfiguration = null;
        appExternalConfiguration = null;
        appConfiguration = null;
        globalConfiguration = null;
        globalConfigurationMaps = null;
        defaultDynamicGlobalConfiguration = null;
        if (defaultDynamicConfiguration != null) {
            try {
                defaultDynamicConfiguration.close();
            } catch (Exception e) {
                logger.warn("close dynamic configuration failed: " + e.getMessage(), e);
            }
            defaultDynamicConfiguration = null;
        }
    }

    /**
     * Reset environment.
     * For test only.
     */
    public void reset() {
        destroy();
        initialize();
    }

    public String resolvePlaceholders(String str) {
        return ConfigUtils.replaceProperty(str, getConfiguration());
    }

    public PropertiesConfiguration getPropertiesConfiguration() {
        return propertiesConfiguration;
    }

    public SystemConfiguration getSystemConfiguration() {
        return systemConfiguration;
    }

    public EnvironmentConfiguration getEnvironmentConfiguration() {
        return environmentConfiguration;
    }

    public InmemoryConfiguration getExternalConfiguration() {
        return externalConfiguration;
    }

    public InmemoryConfiguration getAppExternalConfiguration() {
        return appExternalConfiguration;
    }

    public InmemoryConfiguration getAppConfiguration() {
        return appConfiguration;
    }

    public String getLocalMigrationRule() {
        return localMigrationRule;
    }

    public void refreshClassLoaders() {
        propertiesConfiguration.refresh();
        loadMigrationRule();
        this.globalConfiguration = null;
        this.globalConfigurationMaps = null;
        this.defaultDynamicGlobalConfiguration = null;
    }

    public Configuration getDynamicGlobalConfiguration() {
        if (defaultDynamicGlobalConfiguration == null) {
            if (defaultDynamicConfiguration == null) {
                if (logger.isWarnEnabled()) {
                    logger.warn("dynamicConfiguration is null , return globalConfiguration.");
                }
                return getConfiguration();
            }
            defaultDynamicGlobalConfiguration = new CompositeConfiguration();
            defaultDynamicGlobalConfiguration.addConfiguration(defaultDynamicConfiguration);
            defaultDynamicGlobalConfiguration.addConfiguration(getConfiguration());
        }
        return defaultDynamicGlobalConfiguration;
    }

    public Optional<DynamicConfiguration> getDynamicConfiguration() {
        return Optional.ofNullable(defaultDynamicConfiguration);
    }

    @DisableInject
    public void setDynamicConfiguration(DynamicConfiguration defaultDynamicConfiguration) {
        this.defaultDynamicConfiguration = defaultDynamicConfiguration;
    }
}

相关信息

dubbo 源码目录

相关文章

dubbo CompositeConfiguration 源码

dubbo Configuration 源码

dubbo ConfigurationCache 源码

dubbo ConfigurationUtils 源码

dubbo EnvironmentConfiguration 源码

dubbo InmemoryConfiguration 源码

dubbo ModuleEnvironment 源码

dubbo OrderedPropertiesConfiguration 源码

dubbo OrderedPropertiesProvider 源码

dubbo PrefixedConfiguration 源码

0  赞