diff options
Diffstat (limited to 'flags')
6 files changed, 43 insertions, 16 deletions
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java index 20ce7fe2578..527d53dc830 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java @@ -52,7 +52,7 @@ public class Flags { HOSTNAME); public static final UnboundListFlag<String> DISABLED_HOST_ADMIN_TASKS = defineListFlag( - "disabled-host-admin-tasks", List.of(), + "disabled-host-admin-tasks", List.of(), String.class, "List of host-admin task names (as they appear in the log, e.g. root>main>UpgradeTask) that should be skipped", "Takes effect on next host admin tick", HOSTNAME, NODE_TYPE); @@ -112,7 +112,7 @@ public class Flags { APPLICATION_ID); public static final UnboundListFlag<String> DISABLED_DYNAMIC_PROVISIONING_FLAVORS = defineListFlag( - "disabled-dynamic-provisioning-flavors", List.of(), + "disabled-dynamic-provisioning-flavors", List.of(), String.class, "List of disabled Vespa flavor names that cannot be used for dynamic provisioning", "Takes effect on next provisioning"); @@ -195,9 +195,10 @@ public class Flags { } /** WARNING: public for testing: All flags should be defined in {@link Flags}. */ - public static <T> UnboundListFlag<T> defineListFlag(String flagId, List<T> defaultValue, String description, - String modificationEffect, FetchVector.Dimension... dimensions) { - return define(UnboundListFlag::new, flagId, defaultValue, description, modificationEffect, dimensions); + public static <T> UnboundListFlag<T> defineListFlag(String flagId, List<T> defaultValue, Class<T> elementClass, + String description, String modificationEffect, FetchVector.Dimension... dimensions) { + return define((fid, dval, fvec) -> new UnboundListFlag<>(fid, dval, elementClass, fvec), + flagId, defaultValue, description, modificationEffect, dimensions); } @FunctionalInterface diff --git a/flags/src/main/java/com/yahoo/vespa/flags/InMemoryFlagSource.java b/flags/src/main/java/com/yahoo/vespa/flags/InMemoryFlagSource.java index b6e716fc912..6565ada98b0 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/InMemoryFlagSource.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/InMemoryFlagSource.java @@ -41,8 +41,14 @@ public class InMemoryFlagSource implements FlagSource { return withRawFlag(flagId, new UnboundJacksonFlag<>(flagId, value, jacksonClass).serializer().serialize(value)); } - public <T> InMemoryFlagSource withListFlag(FlagId flagId, List<T> value) { - return withRawFlag(flagId, new UnboundListFlag<T>(flagId, value).serializer().serialize(value)); + /** use {@link #withListFlag(FlagId, List, Class)} instead */ + @Deprecated + public InMemoryFlagSource withListFlag(FlagId flagId, List<String> value) { + return withListFlag(flagId, value, String.class); + } + + public <T> InMemoryFlagSource withListFlag(FlagId flagId, List<T> value, Class<T> elementClass) { + return withRawFlag(flagId, new UnboundListFlag<T>(flagId, value, elementClass).serializer().serialize(value)); } public InMemoryFlagSource removeFlag(FlagId flagId) { diff --git a/flags/src/main/java/com/yahoo/vespa/flags/JacksonArraySerializer.java b/flags/src/main/java/com/yahoo/vespa/flags/JacksonArraySerializer.java index 5716582e0aa..3c509703668 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/JacksonArraySerializer.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/JacksonArraySerializer.java @@ -1,17 +1,23 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.flags; +import com.fasterxml.jackson.databind.JavaType; + import java.util.List; /** * @author freva */ public class JacksonArraySerializer<T> implements FlagSerializer<List<T>> { + private final JavaType type; + + public JacksonArraySerializer(Class<T> clazz) { + type = JsonNodeRawFlag.constructCollectionType(List.class, clazz); + } - @SuppressWarnings("unchecked") @Override public List<T> deserialize(RawFlag rawFlag) { - return (List<T>) JsonNodeRawFlag.fromJsonNode(rawFlag.asJsonNode()).toJacksonClass(List.class); + return JsonNodeRawFlag.fromJsonNode(rawFlag.asJsonNode()).toJacksonClass(type); } @Override diff --git a/flags/src/main/java/com/yahoo/vespa/flags/JsonNodeRawFlag.java b/flags/src/main/java/com/yahoo/vespa/flags/JsonNodeRawFlag.java index f41dd9f9e5c..92b7b3bc04d 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/JsonNodeRawFlag.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/JsonNodeRawFlag.java @@ -1,9 +1,12 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.flags; +import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.Collection; + import static com.yahoo.yolean.Exceptions.uncheck; /** @@ -36,6 +39,15 @@ public class JsonNodeRawFlag implements RawFlag { return uncheck(() -> mapper.treeToValue(jsonNode, jacksonClass)); } + public <T> T toJacksonClass(JavaType jacksonClass) { + return uncheck(() -> mapper.readValue(jsonNode.toString(), jacksonClass)); + } + + @SuppressWarnings("rawtypes") + public static JavaType constructCollectionType(Class<? extends Collection> collectionClass, Class<?> elementClass) { + return mapper.getTypeFactory().constructCollectionType(collectionClass, elementClass); + } + @Override public JsonNode asJsonNode() { return jsonNode; diff --git a/flags/src/main/java/com/yahoo/vespa/flags/UnboundListFlag.java b/flags/src/main/java/com/yahoo/vespa/flags/UnboundListFlag.java index f5150604231..a2230171454 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/UnboundListFlag.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/UnboundListFlag.java @@ -9,14 +9,14 @@ import java.util.List; */ @Immutable public class UnboundListFlag<T> extends UnboundFlagImpl<List<T>, ListFlag<T>, UnboundListFlag<T>> { - public UnboundListFlag(FlagId id, List<T> defaultValue) { - this(id, defaultValue, new FetchVector()); + public UnboundListFlag(FlagId id, List<T> defaultValue, Class<T> clazz) { + this(id, defaultValue, clazz, new FetchVector()); } - public UnboundListFlag(FlagId id, List<T> defaultValue, FetchVector defaultFetchVector) { + public UnboundListFlag(FlagId id, List<T> defaultValue, Class<T> clazz, FetchVector defaultFetchVector) { super(id, defaultValue, defaultFetchVector, - new JacksonArraySerializer<T>(), - UnboundListFlag::new, + new JacksonArraySerializer<T>(clazz), + (flagId, defVal, fetchVector) -> new UnboundListFlag<>(flagId, defVal, clazz, fetchVector), ListFlag::new); } } diff --git a/flags/src/test/java/com/yahoo/vespa/flags/FlagsTest.java b/flags/src/test/java/com/yahoo/vespa/flags/FlagsTest.java index 284a4324a9e..750f0f414f9 100644 --- a/flags/src/test/java/com/yahoo/vespa/flags/FlagsTest.java +++ b/flags/src/test/java/com/yahoo/vespa/flags/FlagsTest.java @@ -8,7 +8,6 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -90,7 +89,7 @@ public class FlagsTest { @Test public void testList() { - testGeneric(Flags.defineListFlag("list-id", List.of("a"), "desc", "mod"), List.of("a", "b", "c")); + testGeneric(Flags.defineListFlag("list-id", List.of("a"), String.class, "desc", "mod"), List.of("a", "b", "c")); } @Test @@ -103,6 +102,9 @@ public class FlagsTest { testGeneric(Flags.defineJacksonFlag("jackson-id", defaultInstance, ExampleJacksonClass.class, "description", "modification effect", FetchVector.Dimension.HOSTNAME), instance); + + testGeneric(Flags.defineListFlag("jackson-list-id", List.of(defaultInstance), ExampleJacksonClass.class, "desc", "mod"), + List.of(instance)); } private <T> void testGeneric(UnboundFlag<T, ?, ?> unboundFlag, T value) { |