Skip to content

Commit

Permalink
Merge pull request #985 from lilai23/bootstrap
Browse files Browse the repository at this point in the history
【fix】启动参数支持索引环境变量
  • Loading branch information
robotLJW authored Nov 26, 2022
2 parents 1a0f899 + a931abd commit 50d147e
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 9 deletions.
5 changes: 5 additions & 0 deletions sermant-agentcore/sermant-agentcore-premain/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@
<artifactId>sermant-agentcore-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<profiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import com.huaweicloud.sermant.core.common.CommonConstant;
import com.huaweicloud.sermant.core.common.LoggerFactory;
import com.huaweicloud.sermant.core.utils.FieldUtils;
import com.huaweicloud.sermant.core.utils.StringUtils;

import java.io.FileInputStream;
import java.io.IOException;
Expand Down Expand Up @@ -85,7 +85,7 @@ private static Properties loadConfig() {
properties.load(configStream);
} catch (IOException ioException) {
LOGGER.severe(String.format(Locale.ROOT, "Exception occurs when close config InputStream , %s .",
ioException.getMessage()));
ioException.getMessage()));
}
return properties;
}
Expand All @@ -98,9 +98,8 @@ private static Properties loadConfig() {
* @return 参数值
*/
private static String getCommonValue(String key, Properties configMap) {
String value = configMap.getProperty(FieldUtils.toUnderline(key, '.', false));
value = value == null ? System.getProperty(key) : value;
return value;
String value = configMap.getProperty(key);
return getActualValue(value);
}

/**
Expand Down Expand Up @@ -135,23 +134,51 @@ private static void addNotNullEntries(Map<String, Object> argsMap, Properties co
*/
private static void addNormalEntries(Map<String, Object> argsMap, Properties configMap) {
for (Object key : configMap.keySet()) {
if (!argsMap.containsKey((String)key)) {
final String value = configMap.getProperty((String)key);
if (!argsMap.containsKey((String) key)) {
final String value = configMap.getProperty((String) key);
if (value != null) {
argsMap.put((String)key, value);
argsMap.put((String) key, getActualValue(value));
}
}
}
}

/**
* 获取形如"${}"的配置,环境变量或系统变量
*
* @param configVal 配置值
* @return 真实配置
*/
private static String getActualValue(String configVal) {
if (configVal != null && configVal.matches("^.*\\$\\{[\\w.]+(:.*)?}.*$")) {
final int startIndex = configVal.indexOf("${") + 2;
final int endIndex = configVal.indexOf('}', startIndex);
final String envKey = configVal.substring(startIndex, endIndex);
final int separatorIndex = envKey.indexOf(':');
final String key = separatorIndex >= 0 ? envKey.substring(0, separatorIndex) : envKey;
final String defaultValue = separatorIndex >= 0 ? envKey.substring(separatorIndex + 1) : "";

// 优先级为环境变量 > 系统变量
if (!StringUtils.isBlank(System.getenv(key))) {
return System.getenv(key);
}
if (!StringUtils.isBlank(System.getProperty(key))) {
return System.getProperty(key);
}
return defaultValue;

}
return configVal;
}

/**
* 添加路径键值对
*
* @param argsMap 参数集
*/
private static void addPathEntries(Map<String, Object> argsMap) {
argsMap.put(CommonConstant.AGENT_ROOT_DIR_KEY, PathDeclarer.getAgentPath());
argsMap.put(CommonConstant.CORE_IMPLEMENT_DIR_KEY,PathDeclarer.getImplementPath());
argsMap.put(CommonConstant.CORE_IMPLEMENT_DIR_KEY, PathDeclarer.getImplementPath());
argsMap.put(CommonConstant.CORE_CONFIG_FILE_KEY, PathDeclarer.getConfigPath());
argsMap.put(CommonConstant.PLUGIN_SETTING_FILE_KEY, PathDeclarer.getPluginSettingPath());
argsMap.put(CommonConstant.PLUGIN_PACKAGE_DIR_KEY, PathDeclarer.getPluginPackagePath());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.huawei.sermant.premain.common;


import static org.junit.Assert.assertEquals;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
* BootArgsBuilder单元
*
* @author lilai
* @since 2022-11-26
*/
public class BootArgsBuilderTest {
private static final Map<String, String> envMap = new HashMap<>();

/**
* 单元测试前设置环境变量
*
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
@BeforeClass
public static void setUp() throws NoSuchFieldException, IllegalAccessException {
envMap.put("serviceAName", "demo");
envMap.put("serviceAVersion", "1.0");
envMap.put("serviceBName", "");
envMap.put("serviceBVersion", "");
setEnv(envMap);
}

/**
* 单元测试结束后清理环境变量
*
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
@AfterClass
public static void tearDown() throws NoSuchFieldException, IllegalAccessException {
envMap.put("serviceAName", "");
envMap.put("serviceAVersion", "");
setEnv(envMap);
}

/**
* 测试getActualValue方法
*
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws NoSuchFieldException
*/
@Test
public void testGetActualValue() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
Method method = BootArgsBuilder.class.getDeclaredMethod("getActualValue", String.class);
method.setAccessible(true);
assertEquals("demo", method.invoke(BootArgsBuilder.class, "${serviceAName:A}"));
assertEquals("1.0", method.invoke(BootArgsBuilder.class, "${serviceAVersion:2.0}"));
assertEquals("B", method.invoke(BootArgsBuilder.class, "${serviceBName:B}"));
assertEquals("2.0", method.invoke(BootArgsBuilder.class, "${serviceBVersion:2.0}"));
}

/**
* 设置环境变量
*
* @param envMap
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
private static void setEnv(Map envMap) throws NoSuchFieldException, IllegalAccessException {
try {
// win系统
Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
theEnvironmentField.setAccessible(true);
Map env1 = (Map) theEnvironmentField.get(null);
env1.putAll(envMap);

// linux/macos系统
Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
theCaseInsensitiveEnvironmentField.setAccessible(true);
Map env2 = (Map) theCaseInsensitiveEnvironmentField.get(null);
env2.putAll(envMap);
} catch (NoSuchFieldException | ClassNotFoundException | IllegalAccessException e) {
Class[] classes = Collections.class.getDeclaredClasses();
Map env = System.getenv();
for (Class cl : classes) {
if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Object obj = field.get(env);
Map map = (Map) obj;
map.clear();
map.putAll(envMap);
}
}
}
}
}

0 comments on commit 50d147e

Please sign in to comment.