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

com.alipay.sofa.common.config.DefaultConfigManager Maven / Gradle / Ivy

/*
 * 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 com.alipay.sofa.common.config;

import com.alipay.sofa.common.utils.OrderComparator;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.ExecutionError;
import com.google.common.util.concurrent.UncheckedExecutionException;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author zhaowang
 * @version : SofaCommonConfig.java, v 0.1 2020年10月20日 8:30 下午 zhaowang Exp $
 */
public class DefaultConfigManager implements ConfigManager {

    private final Object EMPTY = new Object();
    private final List configSources = new CopyOnWriteArrayList<>();
    private final List configListeners = new CopyOnWriteArrayList<>();
    private final LoadingCache cache;

    public DefaultConfigManager(long expireAfterSecond, long maximumSize) {
        this.cache = CacheBuilder.newBuilder()
                .expireAfterWrite(Duration.ofSeconds(expireAfterSecond))
                .maximumSize(maximumSize)
                .build(new CacheLoader<>() {
                    @Override
                    public Object load(ConfigKey key) {
                        Object config = getConfig(key, null);
                        if (config == null) {
                            return EMPTY;
                        }
                        return config;
                    }
                });
    }


    @Override
    public  T getOrDefault(ConfigKey key) {
        return getConfig(key, key.getDefaultValue());
    }

    @Override
    public  T getOrCustomDefault(ConfigKey key, T customDefault) {
        return getConfig(key, customDefault);
    }

    @Override
    public  T getOrDefaultWithCache(ConfigKey key) {
        return getConfigWithCache(key, key.getDefaultValue());
    }

    @Override
    public  T getOrCustomDefaultWithCache(ConfigKey key, T customDefault) {
        return getConfigWithCache(key, customDefault);
    }

    private  T getConfigWithCache(ConfigKey key, T defaultValue) {
        Object result = null;
        try {
            result = cache.getUnchecked(key);
        }catch (ExecutionError error){
            throw new IllegalStateException(error);
        } catch (UncheckedExecutionException e) {
            Throwable cause = e.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            }else{
                throw new IllegalStateException("Unexpected type of exception when getConfigWithCache:"+cause,cause);
            }
        }
        if (result == EMPTY) {
            return defaultValue;
        } else {
            return (T) result;
        }
    }

    public  T getConfig(ConfigKey key, T defaultValue) {
        T result;
        beforeConfigLoading(key);
        for (ConfigSource configSource : configSources) {
            result = configSource.getConfig(key);
            if (result != null) {
                onConfigLoaded(key, configSource);
                return result;
            }
        }


        onLoadDefaultValue(key, defaultValue);
        return defaultValue;
    }

    private  void onLoadDefaultValue(ConfigKey key, Object defaultValue) {
        for (ManagementListener configListener : configListeners) {
            configListener.onLoadDefaultValue(key, defaultValue);
        }
    }


    private  void beforeConfigLoading(ConfigKey key) {
        for (ManagementListener configListener : configListeners) {
            configListener.beforeConfigLoading(key, configSources);
        }
    }

    private  void onConfigLoaded(ConfigKey key, ConfigSource configSource) {
        for (ManagementListener configListener : configListeners) {
            configListener.afterConfigLoaded(key, configSource, configSources);
        }
    }


    @Override
    public void addConfigSource(ConfigSource configSource) {
        configSources.add(configSource);
        OrderComparator.sort(configSources);
    }

    @Override
    public void addConfigListener(ManagementListener configListener) {
        configListeners.add(configListener);
        OrderComparator.sort(configListeners);
    }

    //visible for test
    List getConfigSources() {
        return configSources;
    }

    //visible for test
    List getConfigListeners() {
        return configListeners;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy