* [ISSUE #8622] 移除 environment 概念 * [ISSUE #8622] 使用尾递归优化循环 - SYS更名为ENV - SHARED更改为PROTOTYPE * [ISSUE #8622] rename lookingForProperties * [ISSUE #8622] NProperties is renamed SearchableProperties and add some comments * [ISSUE #8622] update some comments
This commit is contained in:
parent
b37d100eb3
commit
6278e7eadb
@ -35,7 +35,7 @@ public class Constants {
|
|||||||
|
|
||||||
public static final String JM_SNAPSHOT_PATH = "JM.SNAPSHOT.PATH";
|
public static final String JM_SNAPSHOT_PATH = "JM.SNAPSHOT.PATH";
|
||||||
|
|
||||||
public static final String NACOS_ENVS_SEARCH = "nacos.envs.search";
|
public static final String NACOS_ENV_FIRST = "nacos.env.first";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.client.env;
|
package com.alibaba.nacos.client.env;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
abstract class AbstractPropertySource {
|
abstract class AbstractPropertySource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,4 +33,17 @@ abstract class AbstractPropertySource {
|
|||||||
*/
|
*/
|
||||||
abstract String getProperty(String key);
|
abstract String getProperty(String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if the specified object is a key in this propertySource.
|
||||||
|
* @param key key – possible key
|
||||||
|
* @return true if and only if the specified object is a key in this propertySource, false otherwise.
|
||||||
|
*/
|
||||||
|
abstract boolean containsKey(String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* to properties.
|
||||||
|
* @return properties
|
||||||
|
*/
|
||||||
|
abstract Properties asProperties();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
class DefaultSettingPropertySource extends AbstractPropertySource {
|
class DefaultSettingPropertySource extends AbstractPropertySource {
|
||||||
@ -33,12 +32,10 @@ class DefaultSettingPropertySource extends AbstractPropertySource {
|
|||||||
private final Properties defaultSetting = new Properties();
|
private final Properties defaultSetting = new Properties();
|
||||||
|
|
||||||
DefaultSettingPropertySource() {
|
DefaultSettingPropertySource() {
|
||||||
try {
|
try (final InputStream inputStream = ResourceUtils.getResourceUrl(DEFAULT_SETTING_PATH).openStream()) {
|
||||||
final URL resourceUrl = ResourceUtils.getResourceUrl(DEFAULT_SETTING_PATH);
|
|
||||||
final InputStream inputStream = resourceUrl.openStream();
|
|
||||||
defaultSetting.load(inputStream);
|
defaultSetting.load(inputStream);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.warn("load default setting failed");
|
LOGGER.error("load default setting failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,4 +48,16 @@ class DefaultSettingPropertySource extends AbstractPropertySource {
|
|||||||
String getProperty(String key) {
|
String getProperty(String key) {
|
||||||
return defaultSetting.getProperty(key);
|
return defaultSetting.getProperty(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean containsKey(String key) {
|
||||||
|
return defaultSetting.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Properties asProperties() {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.putAll(defaultSetting);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,4 +35,16 @@ class JvmArgsPropertySource extends AbstractPropertySource {
|
|||||||
String getProperty(String key) {
|
String getProperty(String key) {
|
||||||
return properties.getProperty(key);
|
return properties.getProperty(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean containsKey(String key) {
|
||||||
|
return properties.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Properties asProperties() {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.putAll(this.properties);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,12 +16,27 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.client.env;
|
package com.alibaba.nacos.client.env;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nacos env interface.
|
* NacosClientProperties interface.
|
||||||
*
|
* include all the properties from jvm args, system environment, default setting.
|
||||||
|
* more details you can see https://github.com/alibaba/nacos/issues/8622
|
||||||
* @author onewe
|
* @author onewe
|
||||||
*/
|
*/
|
||||||
public interface NacosEnvironment {
|
public interface NacosClientProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* all the NacosClientProperties object must be created by PROTOTYPE,
|
||||||
|
* so child NacosClientProperties can read properties from the PROTOTYPE.
|
||||||
|
* it looks like this:
|
||||||
|
* |-PROTOTYPE----------------> ip=127.0.0.1
|
||||||
|
* |---|-child1---------------> port=6379
|
||||||
|
* if you search key called "port" from child1, certainly you will get 6379
|
||||||
|
* if you search key called "ip" from child1, you will get 127.0.0.1.
|
||||||
|
* because the child can read properties from parent NacosClientProperties
|
||||||
|
*/
|
||||||
|
NacosClientProperties PROTOTYPE = SearchableProperties.INSTANCE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get property, if the value can not be got by the special key, the null will be returned.
|
* get property, if the value can not be got by the special key, the null will be returned.
|
||||||
@ -87,4 +102,42 @@ public interface NacosEnvironment {
|
|||||||
*/
|
*/
|
||||||
Long getLong(String key, Long defaultValue);
|
Long getLong(String key, Long defaultValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set property.
|
||||||
|
* @param key key
|
||||||
|
* @param value value
|
||||||
|
*/
|
||||||
|
void setProperty(String key, String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add properties.
|
||||||
|
* @param properties properties
|
||||||
|
*/
|
||||||
|
void addProperties(Properties properties);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if the specified object is a key in this NacosClientProperties.
|
||||||
|
* @param key key – possible key
|
||||||
|
* @return true if and only if the specified object is a key in this NacosClientProperties, false otherwise.
|
||||||
|
*/
|
||||||
|
boolean containsKey(String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get properties from NacosClientProperties.
|
||||||
|
* @return properties
|
||||||
|
*/
|
||||||
|
Properties asProperties();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new NacosClientProperties which scope is itself.
|
||||||
|
* @return NacosClientProperties
|
||||||
|
*/
|
||||||
|
NacosClientProperties derive();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new NacosClientProperties from NacosClientProperties#PROTOTYPE and init.
|
||||||
|
* @param properties properties
|
||||||
|
* @return NacosClientProperties
|
||||||
|
*/
|
||||||
|
NacosClientProperties derive(Properties properties);
|
||||||
}
|
}
|
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2022 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed 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.alibaba.nacos.client.env;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
class NacosEnvironmentFactory {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* create nacos environment.
|
|
||||||
* @return NacosEnvironment's proxy object, it contains a SearchableEnvironment object.
|
|
||||||
* @see SearchableEnvironment
|
|
||||||
*/
|
|
||||||
static NacosEnvironment createEnvironment() {
|
|
||||||
|
|
||||||
return (NacosEnvironment) Proxy.newProxyInstance(NacosEnvironmentFactory.class.getClassLoader(), new Class[] {NacosEnvironment.class},
|
|
||||||
new NacosEnvironmentDelegate() {
|
|
||||||
volatile NacosEnvironment environment;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Properties properties) {
|
|
||||||
if (environment == null) {
|
|
||||||
synchronized (NacosEnvironmentFactory.class) {
|
|
||||||
if (environment == null) {
|
|
||||||
environment = new SearchableEnvironment(properties);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
|
||||||
if (environment == null) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Nacos environment doesn't init, please call NacosEnvs#init method then try it again.");
|
|
||||||
}
|
|
||||||
return method.invoke(environment, args);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
interface NacosEnvironmentDelegate extends InvocationHandler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* init environment.
|
|
||||||
* @param properties user customize properties
|
|
||||||
*/
|
|
||||||
void init(Properties properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2022 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed 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.alibaba.nacos.client.env;
|
|
||||||
|
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* environment utils.
|
|
||||||
* @author onewe
|
|
||||||
*/
|
|
||||||
public class NacosEnvs {
|
|
||||||
|
|
||||||
private static final NacosEnvironment ENVIRONMENT = NacosEnvironmentFactory.createEnvironment();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* init environment.
|
|
||||||
* @param properties properties
|
|
||||||
*/
|
|
||||||
public static void init(Properties properties) {
|
|
||||||
NacosEnvironmentFactory.NacosEnvironmentDelegate warrper = (NacosEnvironmentFactory.NacosEnvironmentDelegate) Proxy.getInvocationHandler(
|
|
||||||
ENVIRONMENT);
|
|
||||||
warrper.init(properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getProperty(String key, String defaultValue) {
|
|
||||||
return ENVIRONMENT.getProperty(key, defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get property, if the value can not be got by the special key, the null will be returned.
|
|
||||||
*
|
|
||||||
* @param key special key
|
|
||||||
* @return string value or null.
|
|
||||||
*/
|
|
||||||
public static String getProperty(String key) {
|
|
||||||
return ENVIRONMENT.getProperty(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get boolean, if the value can not be got by the special key, the null will be returned.
|
|
||||||
*
|
|
||||||
* @param key special key
|
|
||||||
* @return boolean value or null.
|
|
||||||
*/
|
|
||||||
public static Boolean getBoolean(String key) {
|
|
||||||
return ENVIRONMENT.getBoolean(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get boolean, if the value can not be got by the special key, the default value will be returned.
|
|
||||||
*
|
|
||||||
* @param key special key
|
|
||||||
* @param defaultValue default value
|
|
||||||
* @return boolean value or defaultValue.
|
|
||||||
*/
|
|
||||||
public static Boolean getBoolean(String key, Boolean defaultValue) {
|
|
||||||
return ENVIRONMENT.getBoolean(key, defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get integer, if the value can not be got by the special key, the null will be returned.
|
|
||||||
*
|
|
||||||
* @param key special key
|
|
||||||
* @return integer value or null
|
|
||||||
*/
|
|
||||||
public static Integer getInteger(String key) {
|
|
||||||
return ENVIRONMENT.getInteger(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get integer, if the value can not be got by the special key, the default value will be returned.
|
|
||||||
*
|
|
||||||
* @param key special key
|
|
||||||
* @param defaultValue default value
|
|
||||||
* @return integer value or default value
|
|
||||||
*/
|
|
||||||
public static Integer getInteger(String key, Integer defaultValue) {
|
|
||||||
return ENVIRONMENT.getInteger(key, defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get long, if the value can not be got by the special key, the null will be returned.
|
|
||||||
*
|
|
||||||
* @param key special key
|
|
||||||
* @return long value or null
|
|
||||||
*/
|
|
||||||
public static Long getLong(String key) {
|
|
||||||
return ENVIRONMENT.getLong(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get long, if the value can not be got by the special key, the default value will be returned.
|
|
||||||
*
|
|
||||||
* @param key special key
|
|
||||||
* @param defaultValue default value
|
|
||||||
* @return long value or default value
|
|
||||||
*/
|
|
||||||
public static Long getLong(String key, Long defaultValue) {
|
|
||||||
return ENVIRONMENT.getLong(key, defaultValue);
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,14 +16,23 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.client.env;
|
package com.alibaba.nacos.client.env;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ListIterator;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
class PropertiesPropertySource extends AbstractPropertySource {
|
class PropertiesPropertySource extends AbstractPropertySource {
|
||||||
|
|
||||||
private final Properties properties;
|
private final Properties properties = new Properties();
|
||||||
|
|
||||||
PropertiesPropertySource(Properties properties) {
|
private final PropertiesPropertySource parent;
|
||||||
this.properties = properties;
|
|
||||||
|
PropertiesPropertySource() {
|
||||||
|
this.parent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertiesPropertySource(PropertiesPropertySource parent) {
|
||||||
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -33,6 +42,67 @@ class PropertiesPropertySource extends AbstractPropertySource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
String getProperty(String key) {
|
String getProperty(String key) {
|
||||||
return properties.getProperty(key);
|
return getProperty(this, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getProperty(PropertiesPropertySource propertiesPropertySource, String key) {
|
||||||
|
final String value = propertiesPropertySource.properties.getProperty(key);
|
||||||
|
if (value != null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
final PropertiesPropertySource parent = propertiesPropertySource.parent;
|
||||||
|
if (parent == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getProperty(parent, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean containsKey(String key) {
|
||||||
|
return containsKey(this, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean containsKey(PropertiesPropertySource propertiesPropertySource, String key) {
|
||||||
|
final boolean exist = propertiesPropertySource.properties.containsKey(key);
|
||||||
|
if (exist) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
final PropertiesPropertySource parent = propertiesPropertySource.parent;
|
||||||
|
if (parent == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return containsKey(parent, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Properties asProperties() {
|
||||||
|
List<Properties> propertiesList = new ArrayList<>(8);
|
||||||
|
|
||||||
|
propertiesList = lookForProperties(this, propertiesList);
|
||||||
|
|
||||||
|
Properties ret = new Properties();
|
||||||
|
final ListIterator<Properties> iterator = propertiesList.listIterator(propertiesList.size());
|
||||||
|
while (iterator.hasPrevious()) {
|
||||||
|
final Properties properties = iterator.previous();
|
||||||
|
ret.putAll(properties);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Properties> lookForProperties(PropertiesPropertySource propertiesPropertySource, List<Properties> propertiesList) {
|
||||||
|
propertiesList.add(propertiesPropertySource.properties);
|
||||||
|
final PropertiesPropertySource parent = propertiesPropertySource.parent;
|
||||||
|
if (parent == null) {
|
||||||
|
return propertiesList;
|
||||||
|
}
|
||||||
|
return lookForProperties(parent, propertiesList);
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized void setProperty(String key, String value) {
|
||||||
|
properties.setProperty(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized void addProperties(Properties source) {
|
||||||
|
properties.putAll(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2022 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed 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.alibaba.nacos.client.env;
|
|
||||||
|
|
||||||
import com.alibaba.nacos.client.constant.Constants;
|
|
||||||
import com.alibaba.nacos.client.env.convert.CompositeConverter;
|
|
||||||
import com.alibaba.nacos.common.utils.StringUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
class PropertySourceSearch {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(PropertySourceSearch.class);
|
|
||||||
|
|
||||||
private static final List<SourceType> DEFAULT_ORDER = Arrays.asList(SourceType.PROPERTIES, SourceType.JVM,
|
|
||||||
SourceType.SYS);
|
|
||||||
|
|
||||||
private final List<AbstractPropertySource> propertySources;
|
|
||||||
|
|
||||||
private final CompositeConverter converter;
|
|
||||||
|
|
||||||
private PropertySourceSearch(List<AbstractPropertySource> propertySources) {
|
|
||||||
this.propertySources = propertySources;
|
|
||||||
this.propertySources.add(new DefaultSettingPropertySource());
|
|
||||||
this.converter = new CompositeConverter();
|
|
||||||
}
|
|
||||||
|
|
||||||
static PropertySourceSearch build(Properties properties) {
|
|
||||||
if (properties == null) {
|
|
||||||
properties = new Properties();
|
|
||||||
}
|
|
||||||
PropertiesPropertySource customizePropertySource = new PropertiesPropertySource(properties);
|
|
||||||
JvmArgsPropertySource jvmArgsPropertySource = new JvmArgsPropertySource();
|
|
||||||
SystemEnvPropertySource systemEnvPropertySource = new SystemEnvPropertySource();
|
|
||||||
|
|
||||||
String searchPattern = jvmArgsPropertySource.getProperty(Constants.SysEnv.NACOS_ENVS_SEARCH);
|
|
||||||
if (StringUtils.isBlank(searchPattern)) {
|
|
||||||
searchPattern = systemEnvPropertySource.getProperty(Constants.SysEnv.NACOS_ENVS_SEARCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolve(searchPattern, customizePropertySource, jvmArgsPropertySource, systemEnvPropertySource);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static PropertySourceSearch resolve(String pattern, AbstractPropertySource... propertySources) {
|
|
||||||
|
|
||||||
if (StringUtils.isBlank(pattern)) {
|
|
||||||
return createPropertySourceSearchWithDefaultOrder(propertySources);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final SourceType sourceType = SourceType.valueOf(pattern.toUpperCase());
|
|
||||||
return createPropertySourceSearchByFirstType(sourceType, propertySources);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.error("first source type parse error, it will be use default order!");
|
|
||||||
return createPropertySourceSearchWithDefaultOrder(propertySources);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static PropertySourceSearch createPropertySourceSearchWithDefaultOrder(AbstractPropertySource... propertySources) {
|
|
||||||
final Map<SourceType, AbstractPropertySource> sourceMap = Arrays.stream(propertySources)
|
|
||||||
.collect(Collectors.toMap(AbstractPropertySource::getType, propertySource -> propertySource));
|
|
||||||
final List<AbstractPropertySource> collect = DEFAULT_ORDER.stream().map(sourceMap::get).collect(Collectors.toList());
|
|
||||||
return new PropertySourceSearch(collect);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static PropertySourceSearch createPropertySourceSearchByFirstType(SourceType firstType,
|
|
||||||
AbstractPropertySource... propertySources) {
|
|
||||||
|
|
||||||
List<SourceType> tempList = new ArrayList<>(4);
|
|
||||||
tempList.add(firstType);
|
|
||||||
|
|
||||||
final Map<SourceType, AbstractPropertySource> sourceMap = Arrays.stream(propertySources)
|
|
||||||
.collect(Collectors.toMap(AbstractPropertySource::getType, propertySource -> propertySource));
|
|
||||||
final List<AbstractPropertySource> collect = DEFAULT_ORDER.stream().filter(sourceType -> !sourceType.equals(firstType))
|
|
||||||
.collect(() -> tempList, List::add, List::addAll).stream().map(sourceMap::get)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
return new PropertySourceSearch(collect);
|
|
||||||
}
|
|
||||||
|
|
||||||
<T> Optional<T> search(String key, Class<T> targetType) {
|
|
||||||
if (targetType == null) {
|
|
||||||
throw new IllegalArgumentException("target type must be not null!");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (AbstractPropertySource propertySource : propertySources) {
|
|
||||||
final String value = propertySource.getProperty(key);
|
|
||||||
if (value != null) {
|
|
||||||
if (String.class.isAssignableFrom(targetType)) {
|
|
||||||
return (Optional<T>) Optional.of(value);
|
|
||||||
}
|
|
||||||
return Optional.ofNullable(converter.convert(value, targetType));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2022 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed 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.alibaba.nacos.client.env;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Searchable environment.
|
|
||||||
*
|
|
||||||
* @author onewe
|
|
||||||
*/
|
|
||||||
class SearchableEnvironment implements NacosEnvironment {
|
|
||||||
|
|
||||||
private final PropertySourceSearch sourceSearch;
|
|
||||||
|
|
||||||
SearchableEnvironment(Properties properties) {
|
|
||||||
this.sourceSearch = PropertySourceSearch.build(properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getProperty(String key) {
|
|
||||||
return getProperty(key, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getProperty(String key, String defaultValue) {
|
|
||||||
return sourceSearch.search(key, String.class).orElse(defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean getBoolean(String key) {
|
|
||||||
return getBoolean(key, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean getBoolean(String key, Boolean defaultValue) {
|
|
||||||
return sourceSearch.search(key, Boolean.class).orElse(defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getInteger(String key) {
|
|
||||||
return getInteger(key, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getInteger(String key, Integer defaultValue) {
|
|
||||||
return sourceSearch.search(key, Integer.class).orElse(defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long getLong(String key) {
|
|
||||||
return getLong(key, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long getLong(String key, Long defaultValue) {
|
|
||||||
return sourceSearch.search(key, Long.class).orElse(defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
236
client/src/main/java/com/alibaba/nacos/client/env/SearchableProperties.java
vendored
Normal file
236
client/src/main/java/com/alibaba/nacos/client/env/SearchableProperties.java
vendored
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2022 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed 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.alibaba.nacos.client.env;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.client.constant.Constants;
|
||||||
|
import com.alibaba.nacos.client.env.convert.CompositeConverter;
|
||||||
|
import com.alibaba.nacos.common.utils.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searchable NacosClientProperties.
|
||||||
|
* the SearchableProperties that it can be specified search order by
|
||||||
|
* nacos.env.first
|
||||||
|
* @author onewe
|
||||||
|
*/
|
||||||
|
class SearchableProperties implements NacosClientProperties {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(SearchableProperties.class);
|
||||||
|
|
||||||
|
private static final JvmArgsPropertySource JVM_ARGS_PROPERTY_SOURCE = new JvmArgsPropertySource();
|
||||||
|
|
||||||
|
private static final SystemEnvPropertySource SYSTEM_ENV_PROPERTY_SOURCE = new SystemEnvPropertySource();
|
||||||
|
|
||||||
|
private static final DefaultSettingPropertySource DEFAULT_SETTING_PROPERTY_SOURCE = new DefaultSettingPropertySource();
|
||||||
|
|
||||||
|
private static final List<SourceType> DEFAULT_ORDER = Arrays.asList(SourceType.PROPERTIES, SourceType.JVM,
|
||||||
|
SourceType.ENV, SourceType.DEFAULT_SETTING);
|
||||||
|
|
||||||
|
private static final CompositeConverter CONVERTER = new CompositeConverter();
|
||||||
|
|
||||||
|
static final SearchableProperties INSTANCE = new SearchableProperties();
|
||||||
|
|
||||||
|
private final List<AbstractPropertySource> propertySources;
|
||||||
|
|
||||||
|
private final PropertiesPropertySource propertiesPropertySource;
|
||||||
|
|
||||||
|
private SearchableProperties() {
|
||||||
|
this(new PropertiesPropertySource());
|
||||||
|
}
|
||||||
|
|
||||||
|
private SearchableProperties(PropertiesPropertySource propertiesPropertySource) {
|
||||||
|
this.propertiesPropertySource = propertiesPropertySource;
|
||||||
|
this.propertySources = build(propertiesPropertySource,
|
||||||
|
JVM_ARGS_PROPERTY_SOURCE, SYSTEM_ENV_PROPERTY_SOURCE, DEFAULT_SETTING_PROPERTY_SOURCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProperty(String key) {
|
||||||
|
return getProperty(key, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProperty(String key, String defaultValue) {
|
||||||
|
return this.search(key, String.class).orElse(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean getBoolean(String key) {
|
||||||
|
return getBoolean(key, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean getBoolean(String key, Boolean defaultValue) {
|
||||||
|
return this.search(key, Boolean.class).orElse(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getInteger(String key) {
|
||||||
|
return getInteger(key, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getInteger(String key, Integer defaultValue) {
|
||||||
|
return this.search(key, Integer.class).orElse(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getLong(String key) {
|
||||||
|
return getLong(key, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getLong(String key, Long defaultValue) {
|
||||||
|
return this.search(key, Long.class).orElse(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperty(String key, String value) {
|
||||||
|
propertiesPropertySource.setProperty(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addProperties(Properties properties) {
|
||||||
|
propertiesPropertySource.addProperties(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Properties asProperties() {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
final ListIterator<AbstractPropertySource> iterator = propertySources.listIterator(
|
||||||
|
propertySources.size());
|
||||||
|
while (iterator.hasPrevious()) {
|
||||||
|
final AbstractPropertySource previous = iterator.previous();
|
||||||
|
properties.putAll(previous.asProperties());
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsKey(String key) {
|
||||||
|
for (AbstractPropertySource propertySource : propertySources) {
|
||||||
|
final boolean containing = propertySource.containsKey(key);
|
||||||
|
if (containing) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Optional<T> search(String key, Class<T> targetType) {
|
||||||
|
if (targetType == null) {
|
||||||
|
throw new IllegalArgumentException("target type must not be null!");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (AbstractPropertySource propertySource : propertySources) {
|
||||||
|
final String value = propertySource.getProperty(key);
|
||||||
|
if (value != null) {
|
||||||
|
if (String.class.isAssignableFrom(targetType)) {
|
||||||
|
try {
|
||||||
|
return (Optional<T>) Optional.of(value);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("target type convert error", e);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return Optional.ofNullable(CONVERTER.convert(value, targetType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AbstractPropertySource> build(AbstractPropertySource... propertySources) {
|
||||||
|
|
||||||
|
String firstEnv = JVM_ARGS_PROPERTY_SOURCE.getProperty(Constants.SysEnv.NACOS_ENV_FIRST);
|
||||||
|
if (StringUtils.isBlank(firstEnv)) {
|
||||||
|
firstEnv = SYSTEM_ENV_PROPERTY_SOURCE.getProperty(Constants.SysEnv.NACOS_ENV_FIRST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(firstEnv)) {
|
||||||
|
return sortPropertySourceDefaultOrder(propertySources);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final SourceType sourceType = SourceType.valueOf(firstEnv.toUpperCase());
|
||||||
|
if (SourceType.DEFAULT_SETTING.equals(sourceType) || SourceType.PROPERTIES.equals(sourceType)) {
|
||||||
|
return sortPropertySourceDefaultOrder(propertySources);
|
||||||
|
}
|
||||||
|
return sortPropertySource(sourceType, propertySources);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("first source type parse error, it will be used default order!", e);
|
||||||
|
return sortPropertySourceDefaultOrder(propertySources);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AbstractPropertySource> sortPropertySourceDefaultOrder(
|
||||||
|
AbstractPropertySource... propertySources) {
|
||||||
|
final Map<SourceType, AbstractPropertySource> sourceMap = Arrays.stream(propertySources)
|
||||||
|
.collect(Collectors.toMap(AbstractPropertySource::getType, propertySource -> propertySource));
|
||||||
|
final List<AbstractPropertySource> collect = DEFAULT_ORDER.stream().map(sourceMap::get)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
LOGGER.info("properties search order:PROPERTIES->JVM->ENV->DEFAULT_SETTING");
|
||||||
|
return collect;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AbstractPropertySource> sortPropertySource(SourceType firstType,
|
||||||
|
AbstractPropertySource... propertySources) {
|
||||||
|
List<SourceType> tempList = new ArrayList<>(4);
|
||||||
|
tempList.add(firstType);
|
||||||
|
|
||||||
|
final Map<SourceType, AbstractPropertySource> sourceMap = Arrays.stream(propertySources)
|
||||||
|
.collect(Collectors.toMap(AbstractPropertySource::getType, propertySource -> propertySource));
|
||||||
|
final List<AbstractPropertySource> collect = DEFAULT_ORDER.stream()
|
||||||
|
.filter(sourceType -> !sourceType.equals(firstType)).collect(() -> tempList, List::add, List::addAll)
|
||||||
|
.stream().map(sourceMap::get).filter(Objects::nonNull).collect(Collectors.toList());
|
||||||
|
|
||||||
|
StringBuilder orderInfo = new StringBuilder("properties search order:");
|
||||||
|
for (int i = 0; i < collect.size(); i++) {
|
||||||
|
final AbstractPropertySource abstractPropertySource = collect.get(i);
|
||||||
|
orderInfo.append(abstractPropertySource.getType().toString());
|
||||||
|
if (i < collect.size() - 1) {
|
||||||
|
orderInfo.append("->");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOGGER.info(orderInfo.toString());
|
||||||
|
|
||||||
|
return collect;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NacosClientProperties derive() {
|
||||||
|
return new SearchableProperties(new PropertiesPropertySource(this.propertiesPropertySource));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NacosClientProperties derive(Properties properties) {
|
||||||
|
final NacosClientProperties nacosClientProperties = this.derive();
|
||||||
|
nacosClientProperties.addProperties(properties);
|
||||||
|
return nacosClientProperties;
|
||||||
|
}
|
||||||
|
}
|
@ -18,17 +18,17 @@ package com.alibaba.nacos.client.env;
|
|||||||
|
|
||||||
enum SourceType {
|
enum SourceType {
|
||||||
/**
|
/**
|
||||||
* get value from system environment.
|
* get value from properties.
|
||||||
*/
|
*/
|
||||||
SYS,
|
PROPERTIES,
|
||||||
/**
|
/**
|
||||||
* get value from jvm args.
|
* get value from jvm args.
|
||||||
*/
|
*/
|
||||||
JVM,
|
JVM,
|
||||||
/**
|
/**
|
||||||
* get value from properties.
|
* get value from system environment.
|
||||||
*/
|
*/
|
||||||
PROPERTIES,
|
ENV,
|
||||||
/**
|
/**
|
||||||
* get value from default setting.
|
* get value from default setting.
|
||||||
*/
|
*/
|
||||||
|
@ -17,18 +17,15 @@
|
|||||||
package com.alibaba.nacos.client.env;
|
package com.alibaba.nacos.client.env;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
class SystemEnvPropertySource extends AbstractPropertySource {
|
class SystemEnvPropertySource extends AbstractPropertySource {
|
||||||
|
|
||||||
private final Map<String, String> env;
|
private final Map<String, String> env = System.getenv();
|
||||||
|
|
||||||
SystemEnvPropertySource() {
|
|
||||||
this.env = System.getenv();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
SourceType getType() {
|
SourceType getType() {
|
||||||
return SourceType.SYS;
|
return SourceType.ENV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -78,7 +75,15 @@ class SystemEnvPropertySource extends AbstractPropertySource {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean containsKey(String name) {
|
@Override
|
||||||
|
boolean containsKey(String name) {
|
||||||
return this.env.containsKey(name);
|
return this.env.containsKey(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Properties asProperties() {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.putAll(this.env);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
308
client/src/test/java/com/alibaba/nacos/client/env/NacosClientPropertiesTest.java
vendored
Normal file
308
client/src/test/java/com/alibaba/nacos/client/env/NacosClientPropertiesTest.java
vendored
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2022 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed 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.alibaba.nacos.client.env;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class NacosClientPropertiesTest {
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void init() {
|
||||||
|
System.setProperty("nacos.env.first", "jvm");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void teardown() {
|
||||||
|
System.clearProperty("nacos.env.first");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetProperty() {
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("nacos.home", "/home/nacos");
|
||||||
|
final String value = NacosClientProperties.PROTOTYPE.getProperty("nacos.home");
|
||||||
|
Assert.assertEquals("/home/nacos", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetPropertyMultiLayer() {
|
||||||
|
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("top.layer", "top");
|
||||||
|
|
||||||
|
final NacosClientProperties layerAEnv = NacosClientProperties.PROTOTYPE.derive();
|
||||||
|
layerAEnv.setProperty("a.layer", "a");
|
||||||
|
|
||||||
|
final NacosClientProperties layerBEnv = layerAEnv.derive();
|
||||||
|
layerBEnv.setProperty("b.layer", "b");
|
||||||
|
|
||||||
|
final NacosClientProperties layerCEnv = layerBEnv.derive();
|
||||||
|
layerCEnv.setProperty("c.layer", "c");
|
||||||
|
|
||||||
|
String value = layerCEnv.getProperty("c.layer");
|
||||||
|
Assert.assertEquals("c", value);
|
||||||
|
|
||||||
|
value = layerCEnv.getProperty("b.layer");
|
||||||
|
Assert.assertEquals("b", value);
|
||||||
|
|
||||||
|
value = layerCEnv.getProperty("a.layer");
|
||||||
|
Assert.assertEquals("a", value);
|
||||||
|
|
||||||
|
value = layerCEnv.getProperty("top.layer");
|
||||||
|
Assert.assertEquals("top", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetPropertyDefaultValue() {
|
||||||
|
final String value = NacosClientProperties.PROTOTYPE.getProperty("nacos.home.default", "/home/default_value");
|
||||||
|
Assert.assertEquals("/home/default_value", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetBoolean() {
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("use.cluster", "true");
|
||||||
|
final Boolean value = NacosClientProperties.PROTOTYPE.getBoolean("use.cluster");
|
||||||
|
Assert.assertTrue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetBooleanDefaultValue() {
|
||||||
|
final Boolean value = NacosClientProperties.PROTOTYPE.getBoolean("use.cluster.default", false);
|
||||||
|
Assert.assertFalse(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetInteger() {
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("max.timeout", "200");
|
||||||
|
final Integer value = NacosClientProperties.PROTOTYPE.getInteger("max.timeout");
|
||||||
|
Assert.assertEquals(200, value.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetIntegerDefaultValue() {
|
||||||
|
final Integer value = NacosClientProperties.PROTOTYPE.getInteger("max.timeout.default", 400);
|
||||||
|
Assert.assertEquals(400, value.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetLong() {
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("connection.timeout", "200");
|
||||||
|
final Long value = NacosClientProperties.PROTOTYPE.getLong("connection.timeout");
|
||||||
|
Assert.assertEquals(200L, value.longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetLongDefault() {
|
||||||
|
final Long value = NacosClientProperties.PROTOTYPE.getLong("connection.timeout.default", 400L);
|
||||||
|
Assert.assertEquals(400L, value.longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetPropertyDefaultSetting() {
|
||||||
|
|
||||||
|
final String value = NacosClientProperties.PROTOTYPE.getProperty("nacos.home.default.test");
|
||||||
|
Assert.assertEquals("/home/default_setting", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setProperty() {
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("nacos.set.property", "true");
|
||||||
|
final String ret = NacosClientProperties.PROTOTYPE.getProperty("nacos.set.property");
|
||||||
|
Assert.assertEquals("true", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setPropertyWithScope() {
|
||||||
|
|
||||||
|
final NacosClientProperties properties = NacosClientProperties.PROTOTYPE.derive();
|
||||||
|
properties.setProperty("nacos.set.property.scope", "config");
|
||||||
|
|
||||||
|
String ret = NacosClientProperties.PROTOTYPE.getProperty("nacos.set.property.scope");
|
||||||
|
Assert.assertNull(ret);
|
||||||
|
|
||||||
|
ret = properties.getProperty("nacos.set.property.scope");
|
||||||
|
Assert.assertEquals("config", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddProperties() {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty("nacos.add.properties", "true");
|
||||||
|
|
||||||
|
NacosClientProperties.PROTOTYPE.addProperties(properties);
|
||||||
|
|
||||||
|
final String ret = NacosClientProperties.PROTOTYPE.getProperty("nacos.add.properties");
|
||||||
|
|
||||||
|
Assert.assertEquals("true", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddPropertiesWithScope() {
|
||||||
|
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty("nacos.add.properties.scope", "config");
|
||||||
|
|
||||||
|
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive();
|
||||||
|
nacosClientProperties.addProperties(properties);
|
||||||
|
|
||||||
|
String ret = NacosClientProperties.PROTOTYPE.getProperty("nacos.add.properties.scope");
|
||||||
|
Assert.assertNull(ret);
|
||||||
|
|
||||||
|
ret = nacosClientProperties.getProperty("nacos.add.properties.scope");
|
||||||
|
Assert.assertEquals("config", ret);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTestDerive() {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.setProperty("nacos.derive.properties.scope", "derive");
|
||||||
|
|
||||||
|
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
|
||||||
|
|
||||||
|
final String value = nacosClientProperties.getProperty("nacos.derive.properties.scope");
|
||||||
|
|
||||||
|
Assert.assertEquals("derive", value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContainsKey() {
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("nacos.contains.key", "true");
|
||||||
|
|
||||||
|
boolean ret = NacosClientProperties.PROTOTYPE.containsKey("nacos.contains.key");
|
||||||
|
Assert.assertTrue(ret);
|
||||||
|
|
||||||
|
ret = NacosClientProperties.PROTOTYPE.containsKey("nacos.contains.key.in.sys");
|
||||||
|
Assert.assertFalse(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContainsKeyMultiLayers() {
|
||||||
|
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("top.layer", "top");
|
||||||
|
|
||||||
|
final NacosClientProperties layerAEnv = NacosClientProperties.PROTOTYPE.derive();
|
||||||
|
layerAEnv.setProperty("a.layer", "a");
|
||||||
|
|
||||||
|
final NacosClientProperties layerBEnv = layerAEnv.derive();
|
||||||
|
layerBEnv.setProperty("b.layer", "b");
|
||||||
|
|
||||||
|
final NacosClientProperties layerCEnv = layerBEnv.derive();
|
||||||
|
layerCEnv.setProperty("c.layer", "c");
|
||||||
|
|
||||||
|
boolean exist = layerCEnv.containsKey("c.layer");
|
||||||
|
Assert.assertTrue(exist);
|
||||||
|
|
||||||
|
exist = layerCEnv.containsKey("b.layer");
|
||||||
|
Assert.assertTrue(exist);
|
||||||
|
|
||||||
|
exist = layerCEnv.containsKey("a.layer");
|
||||||
|
Assert.assertTrue(exist);
|
||||||
|
|
||||||
|
exist = layerCEnv.containsKey("top.layer");
|
||||||
|
Assert.assertTrue(exist);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContainsKeyWithScope() {
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("nacos.contains.global.scope", "global");
|
||||||
|
final NacosClientProperties namingProperties = NacosClientProperties.PROTOTYPE.derive();
|
||||||
|
namingProperties.setProperty("nacos.contains.naming.scope", "naming");
|
||||||
|
|
||||||
|
boolean ret = NacosClientProperties.PROTOTYPE.containsKey("nacos.contains.global.scope");
|
||||||
|
Assert.assertTrue(ret);
|
||||||
|
|
||||||
|
ret = NacosClientProperties.PROTOTYPE.containsKey("nacos.contains.naming.scope");
|
||||||
|
Assert.assertFalse(ret);
|
||||||
|
|
||||||
|
ret = namingProperties.containsKey("nacos.contains.naming.scope");
|
||||||
|
Assert.assertTrue(ret);
|
||||||
|
|
||||||
|
ret = namingProperties.containsKey("nacos.contains.global.scope");
|
||||||
|
Assert.assertTrue(ret);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAsProperties() {
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("nacos.as.properties", "true");
|
||||||
|
final Properties properties = NacosClientProperties.PROTOTYPE.asProperties();
|
||||||
|
Assert.assertNotNull(properties);
|
||||||
|
Assert.assertEquals("true", properties.getProperty("nacos.as.properties"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAsPropertiesWithScope() {
|
||||||
|
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("nacos.as.properties.global.scope", "global");
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("nacos.server.addr.scope", "global");
|
||||||
|
|
||||||
|
final NacosClientProperties configProperties = NacosClientProperties.PROTOTYPE.derive();
|
||||||
|
configProperties.setProperty("nacos.server.addr.scope", "config");
|
||||||
|
|
||||||
|
final Properties properties = configProperties.asProperties();
|
||||||
|
Assert.assertNotNull(properties);
|
||||||
|
|
||||||
|
String ret = properties.getProperty("nacos.as.properties.global.scope");
|
||||||
|
Assert.assertEquals("global", ret);
|
||||||
|
|
||||||
|
ret = properties.getProperty("nacos.server.addr.scope");
|
||||||
|
Assert.assertEquals("config", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetPropertyWithScope() {
|
||||||
|
|
||||||
|
NacosClientProperties.PROTOTYPE.setProperty("nacos.global.scope", "global");
|
||||||
|
|
||||||
|
final NacosClientProperties configProperties = NacosClientProperties.PROTOTYPE.derive();
|
||||||
|
configProperties.setProperty("nacos.config.scope", "config");
|
||||||
|
|
||||||
|
final NacosClientProperties namingProperties = NacosClientProperties.PROTOTYPE.derive();
|
||||||
|
namingProperties.setProperty("nacos.naming.scope", "naming");
|
||||||
|
|
||||||
|
String ret = NacosClientProperties.PROTOTYPE.getProperty("nacos.global.scope");
|
||||||
|
Assert.assertEquals("global", ret);
|
||||||
|
|
||||||
|
ret = NacosClientProperties.PROTOTYPE.getProperty("nacos.config.scope");
|
||||||
|
Assert.assertNull(ret);
|
||||||
|
|
||||||
|
ret = NacosClientProperties.PROTOTYPE.getProperty("nacos.naming.scope");
|
||||||
|
Assert.assertNull(ret);
|
||||||
|
|
||||||
|
ret = configProperties.getProperty("nacos.config.scope");
|
||||||
|
Assert.assertEquals("config", ret);
|
||||||
|
ret = configProperties.getProperty("nacos.global.scope");
|
||||||
|
Assert.assertEquals("global", ret);
|
||||||
|
ret = configProperties.getProperty("nacos.naming.scope");
|
||||||
|
Assert.assertNull(ret);
|
||||||
|
|
||||||
|
ret = namingProperties.getProperty("nacos.naming.scope");
|
||||||
|
Assert.assertEquals("naming", ret);
|
||||||
|
ret = namingProperties.getProperty("nacos.global.scope");
|
||||||
|
Assert.assertEquals("global", ret);
|
||||||
|
ret = namingProperties.getProperty("nacos.config.scope");
|
||||||
|
Assert.assertNull(ret);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2022 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed 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.alibaba.nacos.client.env;
|
|
||||||
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
public class NacosEnvironmentFactoryTest {
|
|
||||||
|
|
||||||
@Test(expected = IllegalStateException.class)
|
|
||||||
public void testCreateEnvironment() {
|
|
||||||
final NacosEnvironment environment = NacosEnvironmentFactory.createEnvironment();
|
|
||||||
Assert.assertNotNull(environment);
|
|
||||||
Assert.assertTrue(Proxy.isProxyClass(environment.getClass()));
|
|
||||||
environment.getProperty("test.exception");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNacosEnvInit() {
|
|
||||||
final NacosEnvironment environment = NacosEnvironmentFactory.createEnvironment();
|
|
||||||
final NacosEnvironmentFactory.NacosEnvironmentDelegate invocationHandler =
|
|
||||||
(NacosEnvironmentFactory.NacosEnvironmentDelegate) Proxy.getInvocationHandler(
|
|
||||||
environment);
|
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.setProperty("init.nacos", "true");
|
|
||||||
|
|
||||||
invocationHandler.init(properties);
|
|
||||||
|
|
||||||
final String property = environment.getProperty("init.nacos");
|
|
||||||
Assert.assertEquals("true", property);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,174 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 1999-2022 Alibaba Group Holding Ltd.
|
|
||||||
*
|
|
||||||
* Licensed 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.alibaba.nacos.client.env;
|
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.MockedStatic;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
public class NacosEnvsTest {
|
|
||||||
|
|
||||||
static MockedStatic<NacosEnvironmentFactory> mockedStatic;
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void before() {
|
|
||||||
mockedStatic = Mockito.mockStatic(NacosEnvironmentFactory.class);
|
|
||||||
mockedStatic.when(NacosEnvironmentFactory::createEnvironment).thenReturn(createProxy());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
public static void teardown() {
|
|
||||||
if (mockedStatic != null) {
|
|
||||||
mockedStatic.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static NacosEnvironment createProxy() {
|
|
||||||
return (NacosEnvironment) Proxy.newProxyInstance(NacosEnvironmentFactory.class.getClassLoader(),
|
|
||||||
new Class[] {NacosEnvironment.class}, new NacosEnvironmentFactory.NacosEnvironmentDelegate() {
|
|
||||||
volatile NacosEnvironment environment;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Properties properties) {
|
|
||||||
environment = new SearchableEnvironment(properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
|
||||||
if (environment == null) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Nacos environment doesn't init, please call NEnvs#init method then try it again.");
|
|
||||||
}
|
|
||||||
return method.invoke(environment, args);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetProperty() {
|
|
||||||
|
|
||||||
final Properties properties = new Properties();
|
|
||||||
properties.setProperty("nacos.home", "/home/nacos");
|
|
||||||
NacosEnvs.init(properties);
|
|
||||||
final String value = NacosEnvs.getProperty("nacos.home");
|
|
||||||
|
|
||||||
Assert.assertEquals("/home/nacos", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetPropertyDefaultValue() {
|
|
||||||
|
|
||||||
final Properties properties = new Properties();
|
|
||||||
NacosEnvs.init(properties);
|
|
||||||
final String value = NacosEnvs.getProperty("nacos.home", "/home/default_value");
|
|
||||||
|
|
||||||
Assert.assertEquals("/home/default_value", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetBoolean() {
|
|
||||||
final Properties properties = new Properties();
|
|
||||||
properties.setProperty("use.cluster", "true");
|
|
||||||
NacosEnvs.init(properties);
|
|
||||||
|
|
||||||
final Boolean value = NacosEnvs.getBoolean("use.cluster");
|
|
||||||
Assert.assertTrue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetBooleanDefaultValue() {
|
|
||||||
final Properties properties = new Properties();
|
|
||||||
NacosEnvs.init(properties);
|
|
||||||
|
|
||||||
final Boolean value = NacosEnvs.getBoolean("use.cluster", false);
|
|
||||||
Assert.assertFalse(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetInteger() {
|
|
||||||
final Properties properties = new Properties();
|
|
||||||
properties.setProperty("max.timeout", "200");
|
|
||||||
NacosEnvs.init(properties);
|
|
||||||
|
|
||||||
final Integer value = NacosEnvs.getInteger("max.timeout");
|
|
||||||
|
|
||||||
Assert.assertEquals(200, value.intValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetIntegerDefaultValue() {
|
|
||||||
final Properties properties = new Properties();
|
|
||||||
NacosEnvs.init(properties);
|
|
||||||
|
|
||||||
final Integer value = NacosEnvs.getInteger("max.timeout", 400);
|
|
||||||
Assert.assertEquals(400, value.intValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetLong() {
|
|
||||||
final Properties properties = new Properties();
|
|
||||||
properties.setProperty("connection.timeout", "200");
|
|
||||||
NacosEnvs.init(properties);
|
|
||||||
|
|
||||||
final Long value = NacosEnvs.getLong("connection.timeout");
|
|
||||||
Assert.assertEquals(200L, value.longValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetLongDefault() {
|
|
||||||
final Properties properties = new Properties();
|
|
||||||
NacosEnvs.init(properties);
|
|
||||||
final Long value = NacosEnvs.getLong("connection.timeout", 400L);
|
|
||||||
Assert.assertEquals(400L, value.longValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetPropertyJvmFirst() {
|
|
||||||
System.setProperty("nacos.envs.search", "jvm");
|
|
||||||
System.setProperty("nacos.home", "/home/jvm_first");
|
|
||||||
|
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.setProperty("nacos.home", "/home/properties_first");
|
|
||||||
|
|
||||||
NacosEnvs.init(properties);
|
|
||||||
final String value = NacosEnvs.getProperty("nacos.home");
|
|
||||||
|
|
||||||
Assert.assertEquals("/home/jvm_first", value);
|
|
||||||
System.clearProperty("nacos.envs.search");
|
|
||||||
System.clearProperty("nacos.home");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetPropertyDefaultSetting() {
|
|
||||||
Properties properties = new Properties();
|
|
||||||
|
|
||||||
NacosEnvs.init(properties);
|
|
||||||
final String value = NacosEnvs.getProperty("nacos.home.default.test");
|
|
||||||
|
|
||||||
Assert.assertEquals("/home/default_setting", value);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user