package com.xxx.commons.configuration;
/**
* @created 2021-12-20 4:48 PM
* @description:
*/
public interface Configuration {
/**
* Get a string associated with the given configuration key.
*
* @param key The configuration key.
* @return The associated string.
*/
String getString(String key);
/**
* Get a string associated with the given configuration key.
* If the key doesn't map to an existing object, the default value
* is returned.
*
* @param key The configuration key.
* @param defaultValue The default value.
* @return The associated string if key is found and has valid
* format, default value otherwise.
*/
String getString(String key, String defaultValue);
/**
* Gets a property from the configuration. This is the most basic get
* method for retrieving values of properties. In a typical implementation
* of the {@code Configuration} interface the other get methods (that
* return specific data types) will internally make use of this method. On
* this level variable substitution is not yet performed. The returned
* object is an internal representation of the property value for the passed
* in key. It is owned by the {@code Configuration} object. So a caller
* should not modify this object. It cannot be guaranteed that this object
* will stay constant over time (i.e. further update operations on the
* configuration may change its internal state).
*
* @param key property to retrieve
* @return the value to which this configuration maps the specified key, or
* null if the configuration contains no mapping for this key.
*/
Object getProperty(String key);
/**
* Gets a property from the configuration. The default value will return if the configuration doesn't contain
* the mapping for the specified key.
*
* @param key property to retrieve
* @param defaultValue default value
* @return the value to which this configuration maps the specified key, or default value if the configuration
* contains no mapping for this key.
*/
Object getProperty(String key, Object defaultValue);
Object getInternalProperty(String key);
/**
* Check if the configuration contains the specified key.
*
* @param key the key whose presence in this configuration is to be tested
* @return {@code true} if the configuration contains a value for this
* key, {@code false} otherwise
*/
boolean containsKey(String key);
T convert(Class cls, String key, T defaultValue);
}
package com.xxx.commons.configuration;
/**
* @created 2021-12-20 4:48 PM
* @description:
*/
public abstract class AbstractConfiguration implements Configuration {
@Override
public String getString(String key) {
return convert(String.class, key, null);
}
@Override
public String getString(String key, String defaultValue) {
return convert(String.class, key, defaultValue);
}
@Override
public Object getProperty(String key) {
return getProperty(key, null);
}
@Override
public Object getProperty(String key, Object defaultValue) {
Object value = getInternalProperty(key);
return value != null ? value : defaultValue;
}
@Override
public boolean containsKey(String key) {
return getProperty(key) != null;
}
@Override
public T convert(Class cls, String key, T defaultValue) {
// we only process String properties for now
String value = (String) getProperty(key);
if (value == null) {
return defaultValue;
}
Object obj = value;
if (cls.isInstance(value)) {
return cls.cast(value);
}
if (Boolean.class.equals(cls) || Boolean.TYPE.equals(cls)) {
obj = Boolean.valueOf(value);
} else if (Number.class.isAssignableFrom(cls) || cls.isPrimitive()) {
if (Integer.class.equals(cls) || Integer.TYPE.equals(cls)) {
obj = Integer.valueOf(value);
} else if (Long.class.equals(cls) || Long.TYPE.equals(cls)) {
obj = Long.valueOf(value);
} else if (Byte.class.equals(cls) || Byte.TYPE.equals(cls)) {
obj = Byte.valueOf(value);
} else if (Short.class.equals(cls) || Short.TYPE.equals(cls)) {
obj = Short.valueOf(value);
} else if (Float.class.equals(cls) || Float.TYPE.equals(cls)) {
obj = Float.valueOf(value);
} else if (Double.class.equals(cls) || Double.TYPE.equals(cls)) {
obj = Double.valueOf(value);
}
} else if (cls.isEnum()) {
obj = Enum.valueOf(cls.asSubclass(Enum.class), value);
}
return cls.cast(obj);
}
}
package com.xxx.commons.configuration;
/**
* @created 2021-12-20 4:49 PM
* @description:
*/
public abstract class AbstractPrefixConfiguration extends AbstractConfiguration {
protected String id;
protected String prefix;
public AbstractPrefixConfiguration(String prefix, String id) {
if (prefix != null && prefix.length() > 0 && !prefix.endsWith(".")) {
this.prefix = prefix + ".";
} else {
this.prefix = prefix;
}
this.id = id;
}
@Override
public Object getProperty(String key, Object defaultValue) {
Object value = null;
if (prefix != null && prefix.length() > 0) {
if (id != null && id.length() > 0) {
value = getInternalProperty(prefix + id + "." + key);
}
if (value == null) {
value = getInternalProperty(prefix + key);
}
} else {
value = getInternalProperty(key);
}
return value != null ? value : defaultValue;
}
}
package com.xxx.commons.configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.LinkedList;
import java.util.List;
/**
* @created 2021-12-20 4:49 PM
* @description:
*/
public class CompositeConfiguration extends AbstractConfiguration {
private Logger logger = LoggerFactory.getLogger(CompositeConfiguration.class);
/**
* List holding all the configuration
*/
private List configList = new LinkedList();
public CompositeConfiguration() {
}
public CompositeConfiguration(Configuration... configurations) {
if (configurations != null && configurations.length > 0) {
for (Configuration configuration : configurations) {
if (!configList.contains(configuration)) {
configList.add(configuration);
}
}
}
}
public void addConfiguration(Configuration configuration) {
if (configList.contains(configuration)) {
return;
}
this.configList.add(configuration);
}
public void addConfigurationFirst(Configuration configuration) {
this.addConfiguration(0, configuration);
}
public void addConfiguration(int pos, Configuration configuration) {
this.configList.add(pos, configuration);
}
@Override
public Object getInternalProperty(String key) {
Configuration firstMatchingConfiguration = null;
for (Configuration config : configList) {
try {
if (config.containsKey(key)) {
firstMatchingConfiguration = config;
break;
}
} catch (Exception e) {
logger.error("Error when trying to get value for key " + key + " from " + config
+ ", will continue to try the next one.");
}
}
if (firstMatchingConfiguration != null) {
return firstMatchingConfiguration.getProperty(key);
} else {
return null;
}
}
@Override
public boolean containsKey(String key) {
for (Configuration configuration : configList) {
if (configuration.containsKey(key)) {
return true;
}
}
return false;
}
}
package com.xxx.commons.configuration;
import com.xxx.commons.data.constant.CommonConstants;
/**
* @created 2021-12-20 4:54 PM
* @description:
*/
public class EnvironmentConfiguration extends AbstractPrefixConfiguration {
public EnvironmentConfiguration(String prefix, String id) {
super(prefix, id);
}
public EnvironmentConfiguration() {
this(null, null);
}
@Override
public Object getInternalProperty(String key) {
String value = System.getenv(key);
if (value == null || value.length() == 0) {
value = System.getenv(toOSStyleKey(key));
}
return value;
}
public static String toOSStyleKey(String key) {
key = key.toUpperCase().replaceAll(CommonConstants.DOT_REGEX, CommonConstants.UNDERLINE_SEPARATOR);
if (!key.startsWith(CommonConstants.OS_STYLE_REST_PREFIX)) {
key = CommonConstants.OS_STYLE_REST_PREFIX + key;
}
return key;
}
}
package com.xxx.commons.configuration;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @created 2021-12-20 4:55 PM
* @description:
*/
public class InmemoryConfiguration extends AbstractPrefixConfiguration {
// stores the configuration key-value pairs
private Map store = new LinkedHashMap();
public InmemoryConfiguration(String prefix, String id) {
super(prefix, id);
}
public InmemoryConfiguration() {
this(null, null);
}
@Override
public Object getInternalProperty(String key) {
return store.get(key);
}
/**
* Add one property into the store, the previous value will be replaced if the key exists
*/
public void addProperty(String key, String value) {
store.put(key, value);
}
/**
* Add a set of properties into the store
*/
public void addProperties(Map properties) {
if (properties != null) {
this.store.putAll(properties);
}
}
/**
* set store
*/
public void setProperties(Map properties) {
if (properties != null) {
this.store = properties;
}
}
}
package com.xxx.commons.configuration;
/**
* @created 2021-12-20 4:56 PM
* @description:
*/
public class SystemConfiguration extends AbstractPrefixConfiguration {
public SystemConfiguration(String prefix, String id) {
super(prefix, id);
}
public SystemConfiguration() {
this(null, null);
}
@Override
public Object getInternalProperty(String key) {
return System.getProperty(key);
}
}
package com.xxx.commons.configuration;
import com.xxx.commons.data.constant.CommonConstants;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @created 2021-12-20 4:53 PM
* @description:
*/
public class Environment {
private static final Environment INSTANCE = new Environment();
private Map systemConfigs = new ConcurrentHashMap();
private Map environmentConfigs = new ConcurrentHashMap();
public static Environment getInstance() {
return INSTANCE;
}
public SystemConfiguration getSystemConfig(String prefix, String id) {
final String key = toKey(prefix, id);
SystemConfiguration configuration = systemConfigs.get(key);
if (configuration == null) {
configuration = new SystemConfiguration(prefix, id);
systemConfigs.put(key, configuration);
}
return configuration;
}
public EnvironmentConfiguration getEnvironmentConfig(String prefix, String id) {
final String key = toKey(prefix, id);
EnvironmentConfiguration configuration = environmentConfigs.get(key);
if (configuration == null) {
configuration = new EnvironmentConfiguration(prefix, id);
environmentConfigs.put(key, configuration);
}
return configuration;
}
/**
* Create new instance for each call, since it will be called only at startup, I think there's no big deal of the potential cost.
* Otherwise, if use cache, we should make sure each MrpcConfig has a unique id which is difficult to guarantee because is on the user's side,
* especially when it comes to ServiceConfig and ReferenceConfig.
*
* @param prefix
* @param id
* @return
*/
public CompositeConfiguration getConfiguration(String prefix, String id) {
CompositeConfiguration compositeConfiguration = new CompositeConfiguration();
compositeConfiguration.addConfiguration(this.getEnvironmentConfig(CommonConstants.MOCK_PREFIX, id));
compositeConfiguration.addConfiguration(this.getEnvironmentConfig(prefix, id));
compositeConfiguration.addConfiguration(this.getSystemConfig(CommonConstants.MOCK_PREFIX, id));
compositeConfiguration.addConfiguration(this.getSystemConfig(prefix, id));
return compositeConfiguration;
}
public Configuration getConfiguration(String id) {
return getConfiguration(null, id);
}
public Configuration getConfiguration() {
return getConfiguration(null, null);
}
private static String toKey(String prefix, String id) {
StringBuilder sb = new StringBuilder();
if (prefix != null && prefix.length() > 0) {
sb.append(prefix);
}
if (id != null && id.length() > 0) {
sb.append(id);
}
if (sb.length() > 0 && sb.charAt(sb.length() - 1) != '.') {
sb.append(".");
}
if (sb.length() > 0) {
return sb.toString();
}
return CommonConstants.XXX;
}
}
package com.xxx.commons.configuration;
/**
* @created 2021-12-20 5:04 PM
* @description:
*/
public class ConfigurationUtils {
public static String getProperty(String property) {
return getProperty(property, null);
}
public static String getProperty(String property, String defaultValue) {
return Environment.getInstance().getConfiguration().getString(property, defaultValue);
}
public static String getProperty(String id, String property, String defaultValue) {
return Environment.getInstance().getConfiguration(id).getString(property, defaultValue);
}
public static Integer getPropertyByInteger(String property, String defaultValue) {
return Integer.parseInt(Environment.getInstance().getConfiguration().getString(property, defaultValue));
}
public static Integer getPropertyByInteger(String id, String property, String defaultValue) {
return Integer.parseInt(Environment.getInstance().getConfiguration(id).getString(property, defaultValue));
}
public static Long getPropertyByLong(String property, String defaultValue) {
return Long.parseLong(Environment.getInstance().getConfiguration().getString(property, defaultValue));
}
public static Long getPropertyByLong(String id, String property, String defaultValue) {
return Long.parseLong(Environment.getInstance().getConfiguration(id).getString(property, defaultValue));
}
public static String getTheProperty(String id, String property, String defaultValue) {
String value = null;
if (id != null && id.length() > 0) {
value = getProperty(id, property, null);
}
return value != null ? value : getProperty(property, defaultValue);
}
}