diff options
Diffstat (limited to 'flags/src/main/java/com/yahoo/vespa/flags/json')
5 files changed, 71 insertions, 17 deletions
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/json/Condition.java b/flags/src/main/java/com/yahoo/vespa/flags/json/Condition.java index 46961fbd8cc..f73e0033773 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/json/Condition.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/json/Condition.java @@ -52,6 +52,16 @@ public interface Condition extends Predicate<FetchVector> { public FetchVector.Dimension dimension() { return dimension; } public List<String> values() { return values; } public Optional<String> predicate() { return predicate; } + + public Condition createAs(Condition.Type type) { + switch (type) { + case WHITELIST: return WhitelistCondition.create(this); + case BLACKLIST: return BlacklistCondition.create(this); + case RELATIONAL: return RelationalCondition.create(this); + } + + throw new IllegalArgumentException("Unknown type '" + type + "'"); + } } static Condition fromWire(WireCondition wireCondition) { @@ -70,14 +80,14 @@ public interface Condition extends Predicate<FetchVector> { params.withPredicate(wireCondition.predicate); } - switch (type) { - case WHITELIST: return WhitelistCondition.create(params); - case BLACKLIST: return BlacklistCondition.create(params); - case RELATIONAL: return RelationalCondition.create(params); - } - - throw new IllegalArgumentException("Unknown type '" + type + "'"); + return params.createAs(type); } + Condition.Type type(); + + FetchVector.Dimension dimension(); + + CreateParams toCreateParams(); + WireCondition toWire(); } diff --git a/flags/src/main/java/com/yahoo/vespa/flags/json/FlagData.java b/flags/src/main/java/com/yahoo/vespa/flags/json/FlagData.java index c4079380a8c..eea61eb71ef 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/json/FlagData.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/json/FlagData.java @@ -14,9 +14,6 @@ import com.yahoo.vespa.flags.json.wire.WireRule; import javax.annotation.concurrent.Immutable; import java.io.InputStream; import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -35,16 +32,16 @@ public class FlagData { private final FetchVector defaultFetchVector; public FlagData(FlagId id) { - this(id, new FetchVector(), Collections.emptyList()); + this(id, new FetchVector(), List.of()); } public FlagData(FlagId id, FetchVector defaultFetchVector, Rule... rules) { - this(id, defaultFetchVector, Arrays.asList(rules)); + this(id, defaultFetchVector, List.of(rules)); } public FlagData(FlagId id, FetchVector defaultFetchVector, List<Rule> rules) { this.id = id; - this.rules = Collections.unmodifiableList(new ArrayList<>(rules)); + this.rules = List.copyOf(rules); this.defaultFetchVector = defaultFetchVector; } @@ -52,6 +49,10 @@ public class FlagData { return id; } + public List<Rule> rules() { + return rules; + } + public boolean isEmpty() { return rules.isEmpty() && defaultFetchVector.isEmpty(); } public Optional<RawFlag> resolve(FetchVector fetchVector) { @@ -136,7 +137,7 @@ public class FlagData { } private static List<Rule> rulesFromWire(List<WireRule> wireRules) { - if (wireRules == null) return Collections.emptyList(); + if (wireRules == null) return List.of(); return wireRules.stream().map(Rule::fromWire).collect(Collectors.toList()); } diff --git a/flags/src/main/java/com/yahoo/vespa/flags/json/ListCondition.java b/flags/src/main/java/com/yahoo/vespa/flags/json/ListCondition.java index c2c76529833..136857bea5f 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/json/ListCondition.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/json/ListCondition.java @@ -27,6 +27,21 @@ public abstract class ListCondition implements Condition { } @Override + public Type type() { + return type; + } + + @Override + public FetchVector.Dimension dimension() { + return dimension; + } + + @Override + public CreateParams toCreateParams() { + return new CreateParams(dimension).withValues(values); + } + + @Override public boolean test(FetchVector fetchVector) { boolean listContainsValue = fetchVector.getValue(dimension).map(values::contains).orElse(false); return isWhitelist == listContainsValue; diff --git a/flags/src/main/java/com/yahoo/vespa/flags/json/RelationalCondition.java b/flags/src/main/java/com/yahoo/vespa/flags/json/RelationalCondition.java index db2f0a3a197..4ed3e49029f 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/json/RelationalCondition.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/json/RelationalCondition.java @@ -48,6 +48,21 @@ public class RelationalCondition implements Condition { } @Override + public Type type() { + return Type.RELATIONAL; + } + + @Override + public FetchVector.Dimension dimension() { + return dimension; + } + + @Override + public CreateParams toCreateParams() { + return new CreateParams(dimension).withPredicate(relationalPredicate.toWire()); + } + + @Override public boolean test(FetchVector fetchVector) { return fetchVector.getValue(dimension).map(predicate::test).orElse(false); } diff --git a/flags/src/main/java/com/yahoo/vespa/flags/json/Rule.java b/flags/src/main/java/com/yahoo/vespa/flags/json/Rule.java index b7d60889419..0d50f1e283f 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/json/Rule.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/json/Rule.java @@ -6,7 +6,6 @@ import com.yahoo.vespa.flags.JsonNodeRawFlag; import com.yahoo.vespa.flags.RawFlag; import com.yahoo.vespa.flags.json.wire.WireRule; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -20,18 +19,32 @@ public class Rule { private final Optional<RawFlag> valueToApply; public Rule(Optional<RawFlag> valueToApply, Condition... andConditions) { - this(valueToApply, Arrays.asList(andConditions)); + this(valueToApply, List.of(andConditions)); } public Rule(Optional<RawFlag> valueToApply, List<Condition> andConditions) { - this.andConditions = andConditions; + this.andConditions = List.copyOf(andConditions); this.valueToApply = valueToApply; } + public List<Condition> conditions() { + return andConditions; + } + + /** Returns true if all the conditions satisfy the given fetch vector */ public boolean match(FetchVector fetchVector) { return andConditions.stream().allMatch(condition -> condition.test(fetchVector)); } + /** + * Returns true if all the conditions on dimensions set in the fetch vector are satisfied. + * Conditions on dimensions not specified in the given fetch vector are ignored. + */ + public boolean partialMatch(FetchVector fetchVector) { + return andConditions.stream() + .allMatch(condition -> !fetchVector.hasDimension(condition.dimension()) || condition.test(fetchVector)); + } + public Optional<RawFlag> getValueToApply() { return valueToApply; } |