diff --git a/CHANGES.md b/CHANGES.md index 97589016b..3394d9b14 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ Release Notes. 8.13.0 ------------------ +* Support set-type in the agent or plugin configurations #### Documentation diff --git a/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/ConfigInitializer.java b/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/ConfigInitializer.java index 4e400a0e1..912acbcf9 100644 --- a/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/ConfigInitializer.java +++ b/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/ConfigInitializer.java @@ -22,12 +22,17 @@ 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.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; /** * Init a class's static fields by a {@link Properties}, including static fields and static inner classes. @@ -64,6 +69,11 @@ public class ConfigInitializer { Map map = (Map) field.get(null); // Set the map from config key and properties setForMapType(configKey, map, properties, keyType, valueType); + } else if (Collection.class.isAssignableFrom(type)) { + ParameterizedType genericType = (ParameterizedType) field.getGenericType(); + Type argumentType = genericType.getActualTypeArguments()[0]; + Collection collection = convertToCollection(argumentType, type, properties.getProperty(configKey)); + field.set(null, collection); } else { /* * Others typical field type @@ -90,6 +100,29 @@ public class ConfigInitializer { } } + private static Collection convertToCollection(Type argumentType, Class type, String propertyValue) { + Collection collection; + if (type.equals(Set.class) || type.equals(HashSet.class)) { + collection = new HashSet<>(); + } else if (type.equals(TreeSet.class)) { + collection = new TreeSet<>(); + } else if (type.equals(List.class) || type.equals(LinkedList.class)) { + collection = new LinkedList<>(); + } else if (type.equals(ArrayList.class)) { + collection = new ArrayList<>(); + } else { + throw new UnsupportedOperationException("Config parameter type support Set,HashSet,TreeSet,List,LinkedList,ArrayList"); + } + if (StringUtil.isBlank(propertyValue)) { + return collection; + } + Arrays.stream(propertyValue.split(",")) + .map(v -> convertToTypicalType(argumentType, v)) + .forEach(collection::add); + return collection; + } + + /** * Convert string value to typical type. * @@ -115,8 +148,6 @@ public class ConfigInitializer { result = Float.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()) { @@ -137,7 +168,6 @@ public class ConfigInitializer { */ private static void setForMapType(String configKey, Map map, Properties properties, final Type keyType, final Type valueType) { - Objects.requireNonNull(configKey); Objects.requireNonNull(map); Objects.requireNonNull(properties); @@ -163,28 +193,11 @@ public class ConfigInitializer { if (valueObj == null) { valueObj = propertyValue; } - map.put(keyObj, valueObj); } }); } - private static List convert2List(String value) { - if (StringUtil.isEmpty(value)) { - return Collections.emptyList(); - } - List result = new LinkedList<>(); - - String[] segments = value.split(","); - for (String segment : segments) { - String trimmedSegment = segment.trim(); - if (StringUtil.isNotEmpty(trimmedSegment)) { - result.add(trimmedSegment); - } - } - return result; - } - } class ConfigDesc { diff --git a/apm-commons/apm-util/src/test/java/org/apache/skywalking/apm/util/ConfigInitializerTest.java b/apm-commons/apm-util/src/test/java/org/apache/skywalking/apm/util/ConfigInitializerTest.java index 2dbb590e1..1039c4b2d 100644 --- a/apm-commons/apm-util/src/test/java/org/apache/skywalking/apm/util/ConfigInitializerTest.java +++ b/apm-commons/apm-util/src/test/java/org/apache/skywalking/apm/util/ConfigInitializerTest.java @@ -24,6 +24,7 @@ import org.junit.Test; import java.util.List; import java.util.Properties; +import java.util.Set; public class ConfigInitializerTest { @Test @@ -33,17 +34,30 @@ public class ConfigInitializerTest { properties.put("Level1Object.Level2Object.INT_ATTR".toLowerCase(), "1000"); properties.put("Level1Object.Level2Object.LONG_ATTR".toLowerCase(), "1000"); properties.put("Level1Object.Level2Object.BOOLEAN_ATTR".toLowerCase(), "true"); - properties.put("Level1Object.LIST_ATTR".toLowerCase(), "1,2,3"); - properties.put("Level1Object.LIST_EMPTY_ATTR".toLowerCase(), ""); + properties.put("Level1Object.LIST_STR_ATTR".toLowerCase(), "a,b,c"); + properties.put("Level1Object.LIST_INT_ATTR".toLowerCase(), "1,2,3"); + properties.put("Level1Object.LIST_STR_EMPTY_ATTR".toLowerCase(), ""); + properties.put("Level1Object.LIST_BOOL_ATTR".toLowerCase(), "true,false"); properties.put("Level1Object.Level2Object.ENUM_ATTR".toLowerCase(), "RED"); + properties.put("Level1Object.SET_STR_ATTR".toLowerCase(), "a,b,c,d,b"); + properties.put("Level1Object.SET_STR_EMPTY_ATTR".toLowerCase(), ""); + properties.put("Level1Object.SET_INT_ATTR".toLowerCase(), "1,2,3,4,4"); + properties.put("Level1Object.SET_BOOL_ATTR".toLowerCase(), "true,true"); ConfigInitializer.initialize(properties, TestPropertiesObject.class); Assert.assertEquals("stringValue", TestPropertiesObject.Level1Object.STR_ATTR); Assert.assertEquals(1000, TestPropertiesObject.Level1Object.Level2Object.INT_ATTR); Assert.assertEquals(1000L, TestPropertiesObject.Level1Object.Level2Object.LONG_ATTR); - Assert.assertEquals(true, TestPropertiesObject.Level1Object.Level2Object.BOOLEAN_ATTR); - Assert.assertArrayEquals(new String[] {}, TestPropertiesObject.Level1Object.LIST_EMPTY_ATTR.toArray()); + Assert.assertTrue(TestPropertiesObject.Level1Object.Level2Object.BOOLEAN_ATTR); + Assert.assertArrayEquals(new String[]{}, TestPropertiesObject.Level1Object.LIST_STR_EMPTY_ATTR.toArray()); + Assert.assertArrayEquals(new String[]{"a", "b", "c"}, TestPropertiesObject.Level1Object.LIST_STR_ATTR.toArray()); + Assert.assertArrayEquals(new Integer[]{1, 2, 3}, TestPropertiesObject.Level1Object.LIST_INT_ATTR.toArray()); + Assert.assertArrayEquals(new String[]{}, TestPropertiesObject.Level1Object.SET_STR_EMPTY_ATTR.toArray()); + Assert.assertArrayEquals(new Boolean[]{true, false}, TestPropertiesObject.Level1Object.LIST_BOOL_ATTR.toArray()); + Assert.assertArrayEquals(new String[]{"a", "b", "c", "d"}, TestPropertiesObject.Level1Object.SET_STR_ATTR.toArray()); + Assert.assertArrayEquals(new Integer[]{1, 2, 3, 4}, TestPropertiesObject.Level1Object.SET_INT_ATTR.toArray()); + Assert.assertArrayEquals(new Boolean[]{true}, TestPropertiesObject.Level1Object.SET_BOOL_ATTR.toArray()); Assert.assertEquals(TestColorEnum.RED, TestPropertiesObject.Level1Object.Level2Object.ENUM_ATTR); //make sure that when descs is empty,toString() work right; Assert.assertEquals(new ConfigDesc().toString(), ""); @@ -62,7 +76,14 @@ public class ConfigInitializerTest { @Before public void clear() { TestPropertiesObject.Level1Object.STR_ATTR = null; - TestPropertiesObject.Level1Object.LIST_ATTR = null; + TestPropertiesObject.Level1Object.LIST_STR_ATTR = null; + TestPropertiesObject.Level1Object.LIST_STR_EMPTY_ATTR = null; + TestPropertiesObject.Level1Object.LIST_INT_ATTR = null; + TestPropertiesObject.Level1Object.LIST_BOOL_ATTR = null; + TestPropertiesObject.Level1Object.SET_STR_ATTR = null; + TestPropertiesObject.Level1Object.SET_STR_EMPTY_ATTR = null; + TestPropertiesObject.Level1Object.SET_INT_ATTR = null; + TestPropertiesObject.Level1Object.SET_BOOL_ATTR = null; TestPropertiesObject.Level1Object.Level2Object.INT_ATTR = 0; TestPropertiesObject.Level1Object.Level2Object.LONG_ATTR = 0; TestPropertiesObject.Level1Object.Level2Object.BOOLEAN_ATTR = false; @@ -72,8 +93,14 @@ public class ConfigInitializerTest { public static class TestPropertiesObject { public static class Level1Object { public static String STR_ATTR = null; - public static List LIST_ATTR = null; - public static List LIST_EMPTY_ATTR = null; + public static List LIST_STR_ATTR = null; + public static List LIST_STR_EMPTY_ATTR = null; + public static List LIST_INT_ATTR = null; + public static List LIST_BOOL_ATTR = null; + public static Set SET_STR_ATTR = null; + public static Set SET_STR_EMPTY_ATTR = null; + public static Set SET_INT_ATTR = null; + public static Set SET_BOOL_ATTR = null; public static class Level2Object { public static int INT_ATTR = 0;