Refactor ConfigInitializer and improve map type config (#4321)
* Refactor ConfigInitializer * Rename some variable names and add some java docs Co-authored-by: kezhenxu94 <kezhenxu94@163.com> Co-authored-by: 吴晟 Wu Sheng <wu.sheng@foxmail.com>
This commit is contained in:
parent
69d238e613
commit
41c63672c0
|
|
@ -21,9 +21,13 @@ package org.apache.skywalking.apm.util;
|
|||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
|
@ -44,38 +48,36 @@ public class ConfigInitializer {
|
|||
for (Field field : recentConfigType.getFields()) {
|
||||
if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) {
|
||||
String configKey = (parentDesc + "." + field.getName()).toLowerCase();
|
||||
/**
|
||||
* Map config format is, config_key[map_key]=map_value
|
||||
* Such as plugin.opgroup.resttemplate.rule[abc]=/url/path
|
||||
*/
|
||||
if (field.getType().equals(Map.class)) {
|
||||
Map map = (Map)field.get(null);
|
||||
for (Object key : properties.keySet()) {
|
||||
String stringKey = key.toString();
|
||||
if (stringKey.startsWith(configKey + "[") && stringKey.endsWith("]")) {
|
||||
String itemKey = stringKey.substring(configKey.length() + 1, stringKey.length() - 1);
|
||||
map.put(itemKey, properties.getProperty(stringKey));
|
||||
}
|
||||
Class<?> type = field.getType();
|
||||
|
||||
if (type.equals(Map.class)) {
|
||||
/*
|
||||
* Map config format is, config_key[map_key]=map_value
|
||||
* Such as plugin.opgroup.resttemplate.rule[abc]=/url/path
|
||||
*/
|
||||
// Deduct two generic types of the map
|
||||
ParameterizedType genericType = (ParameterizedType)field.getGenericType();
|
||||
Type[] argumentTypes = genericType.getActualTypeArguments();
|
||||
|
||||
Type keyType = null;
|
||||
Type valueType = null;
|
||||
if (argumentTypes != null && argumentTypes.length == 2) {
|
||||
// Get key type and value type of the map
|
||||
keyType = argumentTypes[0];
|
||||
valueType = argumentTypes[1];
|
||||
}
|
||||
Map map = (Map)field.get(null);
|
||||
// Set the map from config key and properties
|
||||
setForMapType(configKey, map, properties, keyType, valueType);
|
||||
} else {
|
||||
/**
|
||||
/*
|
||||
* Others typical field type
|
||||
*/
|
||||
String value = properties.getProperty(configKey);
|
||||
if (value != null) {
|
||||
Class<?> type = field.getType();
|
||||
if (type.equals(int.class))
|
||||
field.set(null, Integer.valueOf(value));
|
||||
else if (type.equals(String.class))
|
||||
field.set(null, value);
|
||||
else if (type.equals(long.class))
|
||||
field.set(null, Long.valueOf(value));
|
||||
else if (type.equals(boolean.class))
|
||||
field.set(null, Boolean.valueOf(value));
|
||||
else if (type.equals(List.class))
|
||||
field.set(null, convert2List(value));
|
||||
else if (type.isEnum())
|
||||
field.set(null, Enum.valueOf((Class<Enum>)type, value.toUpperCase()));
|
||||
// Convert the value into real type
|
||||
Object convertedValue = convertToTypicalType(type, value);
|
||||
if (convertedValue != null) {
|
||||
field.set(null, convertedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -87,28 +89,108 @@ public class ConfigInitializer {
|
|||
}
|
||||
}
|
||||
|
||||
private static List convert2List(String value) {
|
||||
List result = new LinkedList();
|
||||
if (StringUtil.isEmpty(value)) {
|
||||
return result;
|
||||
/**
|
||||
* Convert string value to typical type.
|
||||
* @param type type to convert
|
||||
* @param value string value to be converted
|
||||
* @return converted value or null
|
||||
*/
|
||||
private static Object convertToTypicalType(Type type, String value) {
|
||||
if (value == null || type == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object result = null;
|
||||
if (String.class.equals(type)) {
|
||||
result = value;
|
||||
} else if (int.class.equals(type) || Integer.class.equals(type)) {
|
||||
result = Integer.valueOf(value);
|
||||
} else if (long.class.equals(type) || Long.class.equals(type)) {
|
||||
result = Long.valueOf(value);
|
||||
} else if (boolean.class.equals(type) || Boolean.class.equals(type)) {
|
||||
result = Boolean.valueOf(value);
|
||||
} else if (float.class.equals(type) || Float.class.equals(type)) {
|
||||
result = Boolean.valueOf(value);
|
||||
} else if (double.class.equals(type) || Double.class.equals(type)) {
|
||||
result = Double.valueOf(value);
|
||||
} else if (List.class.equals(type)) {
|
||||
result = convert2List(value);
|
||||
} else if (type instanceof Class) {
|
||||
Class<?> clazz = (Class<?>)type;
|
||||
if (clazz.isEnum()) {
|
||||
result = Enum.valueOf((Class<Enum>)type, value.toUpperCase());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set map items.
|
||||
* @param configKey config key must not be null
|
||||
* @param map map to set must not be null
|
||||
* @param properties properties must not be null
|
||||
* @param keyType key type of the map
|
||||
* @param valueType value type of the map
|
||||
*/
|
||||
private static void setForMapType(String configKey, Map<Object, Object> map, Properties properties,
|
||||
final Type keyType,
|
||||
final Type valueType) {
|
||||
|
||||
Objects.requireNonNull(configKey);
|
||||
Objects.requireNonNull(map);
|
||||
Objects.requireNonNull(properties);
|
||||
|
||||
String prefix = configKey + "[";
|
||||
String suffix = "]";
|
||||
|
||||
properties.forEach((propertyKey, propertyValue) -> {
|
||||
String propertyStringKey = propertyKey.toString();
|
||||
if (propertyStringKey.startsWith(prefix) && propertyStringKey.endsWith(suffix)) {
|
||||
String itemKey = propertyStringKey.substring(prefix.length(), propertyStringKey.length() - suffix.length());
|
||||
Object keyObj;
|
||||
Object valueObj;
|
||||
|
||||
keyObj = convertToTypicalType(keyType, itemKey);
|
||||
valueObj = convertToTypicalType(valueType, propertyValue.toString());
|
||||
|
||||
if (keyObj == null) {
|
||||
keyObj = itemKey;
|
||||
}
|
||||
|
||||
if (valueObj == null) {
|
||||
valueObj = propertyValue;
|
||||
}
|
||||
|
||||
map.put(keyObj, valueObj);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static List<String> convert2List(String value) {
|
||||
if (StringUtil.isEmpty(value)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<String> result = new LinkedList<>();
|
||||
|
||||
String[] segments = value.split(",");
|
||||
for (String segment : segments) {
|
||||
String trimmedSegment = segment.trim();
|
||||
if (!StringUtil.isEmpty(trimmedSegment)) {
|
||||
if (StringUtil.isNotEmpty(trimmedSegment)) {
|
||||
result.add(trimmedSegment);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ConfigDesc {
|
||||
private LinkedList<String> descs = new LinkedList<String>();
|
||||
private LinkedList<String> descs = new LinkedList<>();
|
||||
|
||||
void append(String currentDesc) {
|
||||
descs.addLast(currentDesc);
|
||||
if (StringUtil.isNotEmpty(currentDesc)) {
|
||||
descs.addLast(currentDesc);
|
||||
}
|
||||
}
|
||||
|
||||
void removeLastDesc() {
|
||||
|
|
@ -117,18 +199,6 @@ class ConfigDesc {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (descs.size() == 0) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder ret = new StringBuilder(descs.getFirst());
|
||||
boolean first = true;
|
||||
for (String desc : descs) {
|
||||
if (first) {
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
ret.append(".").append(desc);
|
||||
}
|
||||
return ret.toString();
|
||||
return String.join(".", descs);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,12 +66,16 @@ public class SnifferConfigInitializerTest {
|
|||
@Test
|
||||
public void testConfigOverriding() throws AgentPackageNotFoundException, ConfigNotFoundException {
|
||||
System.setProperty("skywalking.agent.service_name", "testAppFromSystem");
|
||||
System.setProperty("skywalking.agent.instance_properties[key1]", "value1");
|
||||
System.setProperty("skywalking.agent.instance_properties[key2]", "value2");
|
||||
System.setProperty("skywalking.collector.backend_service", "127.0.0.1:8090");
|
||||
String agentOptions = "agent.service_name=testAppFromAgentOptions,logging.level=debug";
|
||||
SnifferConfigInitializer.initialize(agentOptions);
|
||||
assertThat(Config.Agent.SERVICE_NAME, is("testAppFromAgentOptions"));
|
||||
assertThat(Config.Collector.BACKEND_SERVICE, is("127.0.0.1:8090"));
|
||||
assertThat(Config.Logging.LEVEL, is(LogLevel.DEBUG));
|
||||
assertThat(Config.Agent.INSTANCE_PROPERTIES.get("key1"), is("value1"));
|
||||
assertThat(Config.Agent.INSTANCE_PROPERTIES.get("key2"), is("value2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in New Issue