
org.apache.dubbo.common.config.ConfigurationUtils Maven / Gradle / Ivy
Show all versions of dubbo Show documentation
/*
* 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.DynamicConfigurationFactory;
import org.apache.dubbo.common.extension.ExtensionAccessor;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModel;
import java.io.IOException;
import java.io.StringReader;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_SERVER_SHUTDOWN_TIMEOUT;
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SECONDS_KEY;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_PROPERTY_TYPE_MISMATCH;
/**
* Utilities for manipulating configurations from different sources
*/
public final class ConfigurationUtils {
/**
* Forbids instantiation.
*/
private ConfigurationUtils() {
throw new UnsupportedOperationException("No instance of 'ConfigurationUtils' for you! ");
}
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ConfigurationUtils.class);
private static final Set securityKey;
private static volatile long expectedShutdownTime = Long.MAX_VALUE;
static {
Set keys = new HashSet<>();
keys.add("accesslog");
keys.add("router");
keys.add("rule");
keys.add("runtime");
keys.add("type");
securityKey = Collections.unmodifiableSet(keys);
}
/**
* Used to get properties from the jvm
*
* @return
*/
public static Configuration getSystemConfiguration(ScopeModel scopeModel) {
return getScopeModelOrDefaultApplicationModel(scopeModel)
.modelEnvironment()
.getSystemConfiguration();
}
/**
* Used to get properties from the os environment
*
* @return
*/
public static Configuration getEnvConfiguration(ScopeModel scopeModel) {
return getScopeModelOrDefaultApplicationModel(scopeModel)
.modelEnvironment()
.getEnvironmentConfiguration();
}
/**
* Used to get a composite property value.
*
* Also see {@link Environment#getConfiguration()}
*
* @return
*/
public static Configuration getGlobalConfiguration(ScopeModel scopeModel) {
return getScopeModelOrDefaultApplicationModel(scopeModel)
.modelEnvironment()
.getConfiguration();
}
public static Configuration getDynamicGlobalConfiguration(ScopeModel scopeModel) {
return scopeModel.modelEnvironment().getDynamicGlobalConfiguration();
}
// FIXME
/**
* Server shutdown wait timeout mills
*
* @return
*/
@SuppressWarnings("deprecation")
public static int getServerShutdownTimeout(ScopeModel scopeModel) {
if (expectedShutdownTime < System.currentTimeMillis()) {
return 1;
}
int timeout = DEFAULT_SERVER_SHUTDOWN_TIMEOUT;
Configuration configuration = getGlobalConfiguration(scopeModel);
String value = StringUtils.trim(configuration.getString(SHUTDOWN_WAIT_KEY));
if (StringUtils.isNotEmpty(value)) {
try {
timeout = Integer.parseInt(value);
} catch (Exception e) {
// ignore
}
} else {
value = StringUtils.trim(configuration.getString(SHUTDOWN_WAIT_SECONDS_KEY));
if (StringUtils.isNotEmpty(value)) {
try {
timeout = Integer.parseInt(value) * 1000;
} catch (Exception e) {
// ignore
}
}
}
if (expectedShutdownTime - System.currentTimeMillis() < timeout) {
return (int) Math.max(1, expectedShutdownTime - System.currentTimeMillis());
}
return timeout;
}
public static int reCalShutdownTime(int expected) {
// already timeout
if (expectedShutdownTime < System.currentTimeMillis()) {
return 1;
}
if (expectedShutdownTime - System.currentTimeMillis() < expected) {
// the shutdown time rest is less than expected
return (int) Math.max(1, expectedShutdownTime - System.currentTimeMillis());
}
// return the expected
return expected;
}
public static void setExpectedShutdownTime(long expectedShutdownTime) {
ConfigurationUtils.expectedShutdownTime = expectedShutdownTime;
}
public static String getCachedDynamicProperty(ScopeModel realScopeModel, String key, String defaultValue) {
ScopeModel scopeModel = getScopeModelOrDefaultApplicationModel(realScopeModel);
ConfigurationCache configurationCache = scopeModel.getBeanFactory().getBean(ConfigurationCache.class);
String value = configurationCache.computeIfAbsent(
key, _k -> ConfigurationUtils.getDynamicProperty(scopeModel, _k, ""));
return StringUtils.isEmpty(value) ? defaultValue : value;
}
private static ScopeModel getScopeModelOrDefaultApplicationModel(ScopeModel realScopeModel) {
if (realScopeModel == null) {
return ApplicationModel.defaultModel();
}
return realScopeModel;
}
public static String getDynamicProperty(ScopeModel scopeModel, String property) {
return getDynamicProperty(scopeModel, property, null);
}
public static String getDynamicProperty(ScopeModel scopeModel, String property, String defaultValue) {
return StringUtils.trim(getDynamicGlobalConfiguration(scopeModel).getString(property, defaultValue));
}
public static String getProperty(ScopeModel scopeModel, String property) {
return getProperty(scopeModel, property, null);
}
public static String getProperty(ScopeModel scopeModel, String property, String defaultValue) {
return StringUtils.trim(getGlobalConfiguration(scopeModel).getString(property, defaultValue));
}
public static int get(ScopeModel scopeModel, String property, int defaultValue) {
return getGlobalConfiguration(scopeModel).getInt(property, defaultValue);
}
public static Map parseProperties(String content) throws IOException {
Map map = new HashMap<>();
if (StringUtils.isEmpty(content)) {
logger.info("Config center was specified, but no config item found.");
} else {
Properties properties = new Properties();
properties.load(new StringReader(content));
properties.stringPropertyNames().forEach(k -> {
boolean deny = false;
// check whether property name is safe or not based on the last fragment kebab-case comparison.
String[] fragments = k.split("\\.");
if (securityKey.contains(StringUtils.convertToSplitName(fragments[fragments.length - 1], "-"))) {
deny = true;
logger.warn(
COMMON_PROPERTY_TYPE_MISMATCH,
"security properties are not allowed to be set",
"",
String.format("'%s' is not allowed to be set as it is on the security key list.", k));
}
if (!deny) {
map.put(k, properties.getProperty(k));
}
});
}
return map;
}
public static boolean isEmptyValue(Object value) {
return value == null || value instanceof String && StringUtils.isBlank((String) value);
}
/**
* Search props and extract sub properties.
*
* # properties
* dubbo.protocol.name=dubbo
* dubbo.protocol.port=1234
*
* # extract protocol props
* Map props = getSubProperties("dubbo.protocol.");
*
* # result
* props: {"name": "dubbo", "port" : "1234"}
*
*
*
* @param configMaps
* @param prefix
* @param
* @return
*/
public static Map getSubProperties(
Collection