com.tencent.polaris.configuration.client.internal.ConfigPropertiesFile Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of polaris-all Show documentation
Show all versions of polaris-all Show documentation
All in one project for polaris-java
/*
* Tencent is pleased to support the open source community by making Polaris available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* 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.tencent.polaris.configuration.client.internal;
import com.google.common.base.Function;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tencent.polaris.api.config.configuration.ConfigFileConfig;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.configuration.api.core.ChangeType;
import com.tencent.polaris.configuration.api.core.ConfigFileMetadata;
import com.tencent.polaris.configuration.api.core.ConfigKVFile;
import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeEvent;
import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeListener;
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
import com.tencent.polaris.configuration.client.util.ConvertFunctions;
import com.tencent.polaris.logging.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import org.slf4j.Logger;
/**
* The properties file.
*
* @author lepdou 2022-03-04
*/
public class ConfigPropertiesFile extends DefaultConfigFile implements ConfigKVFile {
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigPropertiesFile.class);
private final List listeners = Lists.newCopyOnWriteArrayList();
private AtomicReference properties;
private volatile Cache integerCache;
private volatile Cache longCache;
private volatile Cache shortCache;
private volatile Cache floatCache;
private volatile Cache doubleCache;
private volatile Cache byteCache;
private volatile Cache booleanCache;
private final Map> arrayCache;
private final List allCaches;
private final AtomicLong cacheVersion;
public ConfigPropertiesFile(String namespace, String fileGroup, String fileName,
ConfigFileRepo configFileRepo, ConfigFileConfig configFileConfig) {
super(namespace, fileGroup, fileName, configFileRepo, configFileConfig);
arrayCache = Maps.newConcurrentMap();
allCaches = Lists.newArrayList();
cacheVersion = new AtomicLong();
}
@Override
protected void initialize() {
properties = new AtomicReference<>();
super.initialize();
Properties properties = convertToProperties(getContent());
this.properties.set(properties);
}
@Override
public String getProperty(String key, String defaultValue) {
String value = properties.get().getProperty(key);
if (value == null) {
return defaultValue;
}
return value;
}
@Override
public Integer getIntProperty(String key, Integer defaultValue) {
try {
if (integerCache == null) {
synchronized (this) {
if (integerCache == null) {
integerCache = newCache();
}
}
}
return getValueFromCache(key, ConvertFunctions.TO_INT_FUNCTION, integerCache, defaultValue);
} catch (Throwable ex) {
LOGGER.error("[Config] convert to int error. return default value.", ex);
}
return defaultValue;
}
@Override
public Long getLongProperty(String key, Long defaultValue) {
try {
if (longCache == null) {
synchronized (this) {
if (longCache == null) {
longCache = newCache();
}
}
}
return getValueFromCache(key, ConvertFunctions.TO_LONG_FUNCTION, longCache, defaultValue);
} catch (Throwable ex) {
LOGGER.error("[Config] convert to long error. return default value.", ex);
}
return defaultValue;
}
@Override
public Short getShortProperty(String key, Short defaultValue) {
try {
if (shortCache == null) {
synchronized (this) {
if (shortCache == null) {
shortCache = newCache();
}
}
}
return getValueFromCache(key, ConvertFunctions.TO_SHORT_FUNCTION, shortCache, defaultValue);
} catch (Throwable ex) {
LOGGER.error("[Config] convert to short error. return default value.", ex);
}
return defaultValue;
}
@Override
public Float getFloatProperty(String key, Float defaultValue) {
try {
if (floatCache == null) {
synchronized (this) {
if (floatCache == null) {
floatCache = newCache();
}
}
}
return getValueFromCache(key, ConvertFunctions.TO_FLOAT_FUNCTION, floatCache, defaultValue);
} catch (Throwable ex) {
LOGGER.error("[Config] convert to float error. return default value.", ex);
}
return defaultValue;
}
@Override
public Double getDoubleProperty(String key, Double defaultValue) {
try {
if (doubleCache == null) {
synchronized (this) {
if (doubleCache == null) {
doubleCache = newCache();
}
}
}
return getValueFromCache(key, ConvertFunctions.TO_DOUBLE_FUNCTION, doubleCache, defaultValue);
} catch (Throwable ex) {
LOGGER.error("[Config] convert to double error. return default value.", ex);
}
return defaultValue;
}
@Override
public Byte getByteProperty(String key, Byte defaultValue) {
try {
if (byteCache == null) {
synchronized (this) {
if (byteCache == null) {
byteCache = newCache();
}
}
}
return getValueFromCache(key, ConvertFunctions.TO_BYTE_FUNCTION, byteCache, defaultValue);
} catch (Throwable ex) {
LOGGER.error("[Config] convert to byte error. return default value.", ex);
}
return defaultValue;
}
@Override
public Boolean getBooleanProperty(String key, Boolean defaultValue) {
try {
if (booleanCache == null) {
synchronized (this) {
if (booleanCache == null) {
booleanCache = newCache();
}
}
}
return getValueFromCache(key, ConvertFunctions.TO_BOOLEAN_FUNCTION, booleanCache, defaultValue);
} catch (Throwable ex) {
LOGGER.error("[Config] convert to boolean error. return default value.", ex);
}
return defaultValue;
}
@Override
public String[] getArrayProperty(String key, String delimiter, String[] defaultValue) {
try {
if (!arrayCache.containsKey(delimiter)) {
synchronized (this) {
if (!arrayCache.containsKey(delimiter)) {
arrayCache.put(delimiter, this.newCache());
}
}
}
Cache cache = arrayCache.get(delimiter);
String[] result = cache.getIfPresent(key);
if (result != null) {
return result;
}
return getValueAndStoreToCache(key, new Function() {
@Override
public String[] apply(String input) {
return input.split(delimiter);
}
}, cache, defaultValue);
} catch (Throwable ex) {
LOGGER.error("[Config] convert to array error. return default value.", ex);
}
return defaultValue;
}
@Override
public > T getEnumProperty(String key, Class enumType, T defaultValue) {
try {
String value = getProperty(key, null);
if (value != null) {
return Enum.valueOf(enumType, value);
}
} catch (Throwable ex) {
LOGGER.error("[Config] convert to enum error. return default value.", ex);
}
return defaultValue;
}
@Override
public T getJsonProperty(String key, Class clazz, T defaultValue) {
try {
String json = getProperty(key, null);
if (json != null) {
return convertToJson(key, json, null, clazz, defaultValue);
}
} catch (Throwable t) {
LOGGER.error("[Config] convert to json object error. return default value. clazz = {}", clazz.getTypeName(),
t);
}
return defaultValue;
}
@Override
public T getJsonProperty(String key, Type typeOfT, T defaultValue) {
try {
String json = getProperty(key, null);
if (json != null) {
return convertToJson(key, json, typeOfT, null, defaultValue);
}
} catch (Throwable t) {
LOGGER.error("[Config] convert to json object error. return default value. clazz = {}", typeOfT,
t);
}
return defaultValue;
}
@Override
public T asJson(Type typeOfT, T defaultValue) {
throw new IllegalStateException("Properties or yaml file can not convert to json");
}
@Override
public T asJson(Class objectType, T defaultValue) {
throw new IllegalStateException("Properties or yaml file can not convert to json");
}
@Override
public Set getPropertyNames() {
return stringPropertyNames(properties.get());
}
@Override
public void addChangeListener(ConfigKVFileChangeListener listener) {
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
@Override
public void removeChangeListener(ConfigKVFileChangeListener listener) {
listeners.remove(listener);
}
@Override
public void onChange(ConfigFileMetadata configFileMetadata, String newContent) {
super.onChange(configFileMetadata, newContent);
Properties oldProperties = this.properties.get();
if (oldProperties == null) {
oldProperties = new Properties();
}
Properties newProperties = convertToProperties(newContent);
//更新缓存的 properties 值
this.properties.set(newProperties);
Map changeInfos = Maps.newHashMap();
// 计算变更
for (Map.Entry
© 2015 - 2025 Weber Informatics LLC | Privacy Policy