You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2018/09/24 11:30:23 UTC
[1/7] brooklyn-server git commit: proper serialization and
deserialization for constraints
Repository: brooklyn-server
Updated Branches:
refs/heads/master e27cc7b6d -> a3d0ea06e
proper serialization and deserialization for constraints
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/bd34655c
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/bd34655c
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/bd34655c
Branch: refs/heads/master
Commit: bd34655c81400f8228c329ecec31ce6e378f78b0
Parents: e27cc7b
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Sep 20 22:34:25 2018 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Sep 20 22:34:25 2018 +0100
----------------------------------------------------------------------
.../brooklyn/core/config/ConfigConstraints.java | 25 ++
.../core/objs/ConstraintSerialization.java | 354 +++++++++++++++++++
.../core/objs/ConstraintSerializationTest.java | 84 +++++
.../brooklyn/rest/domain/ConfigSummary.java | 17 +-
.../brooklyn/util/text/StringPredicates.java | 11 +-
.../org/apache/brooklyn/util/text/Strings.java | 22 +-
.../org/apache/brooklyn/test/AssertsTest.java | 2 +-
7 files changed, 497 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/bd34655c/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java b/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
index 17b7c9d..35f672e 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
@@ -33,6 +33,7 @@ import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.objs.AbstractEntityAdjunct;
import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
import org.apache.brooklyn.core.objs.BrooklynObjectPredicate;
+import org.apache.brooklyn.core.objs.ConstraintSerialization;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.ReferenceWithError;
import org.apache.brooklyn.util.guava.Maybe;
@@ -185,6 +186,13 @@ public abstract class ConfigConstraints<T extends BrooklynObject> {
return brooklynObject;
}
+ /**
+ * Convenience method to get the serialization routines.
+ */
+ public static ConstraintSerialization serialization() {
+ return ConstraintSerialization.INSTANCE;
+ }
+
private static class EntityConfigConstraints extends ConfigConstraints<Entity> {
public EntityConfigConstraints(Entity brooklynObject) {
super(brooklynObject);
@@ -218,4 +226,21 @@ public abstract class ConfigConstraints<T extends BrooklynObject> {
}
}
+ public static <T> Predicate<T> required() {
+ return new RequiredPredicate<T>();
+ }
+
+ /** Predicate indicating a field is required: it must not be null and if a string it must not be empty */
+ public static class RequiredPredicate<T> implements Predicate<T> {
+ @Override
+ public boolean apply(T input) {
+ if (input==null) return false;
+ if (input instanceof CharSequence && ((CharSequence)input).length()==0) return false;
+ return true;
+ }
+ @Override
+ public String toString() {
+ return "required()";
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/bd34655c/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java b/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
new file mode 100644
index 0000000..a6b7039
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
@@ -0,0 +1,354 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.objs;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigConstraints;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.collections.MutableSet;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.text.StringEscapes.JavaStringEscapes;
+import org.apache.brooklyn.util.text.StringPredicates;
+import org.apache.brooklyn.util.text.Strings;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+public class ConstraintSerialization {
+
+ private final Map<String, String> predicateToStringToPreferredName = MutableMap.of();
+ private final Map<String, Function<List<?>,Predicate<?>>> predicatePreferredNameToConstructor = MutableMap.of();
+
+ public static class PredicateSerializationRuleAdder<T> {
+ private String preferredName;
+ private Function<List<?>, T> constructorArgsFromList;
+ private Function<T, Predicate<?>> constructor;
+ private Predicate<?> predicateSample;
+ private T constructorSampleInput;
+ private Set<String> equivalentNames = MutableSet.of();
+ private Set<Predicate<?>> equivalentPredicateSamples = MutableSet.of();
+
+ ConstraintSerialization serialization;
+
+ public PredicateSerializationRuleAdder(Function<T, Predicate<?>> constructor, Function<List<?>, T> constructorArgsFromList, T constructorSampleInput) {
+ this.constructorArgsFromList = constructorArgsFromList;
+ this.constructor = constructor;
+ this.constructorSampleInput = constructorSampleInput;
+ }
+
+ public static PredicateSerializationRuleAdder<List<Predicate<?>>> predicateListConstructor(Function<List<Predicate<?>>,Predicate<?>> constructor) {
+ PredicateSerializationRuleAdder<List<Predicate<?>>> result = new PredicateSerializationRuleAdder<List<Predicate<?>>>(constructor,
+ null, MutableList.of());
+ result.constructorArgsFromList = o -> result.serialization.toPredicateListFromJsonList(o);
+ return result;
+ }
+
+ public static PredicateSerializationRuleAdder<String> stringConstructor(Function<String,Predicate<?>> constructor) {
+ return new PredicateSerializationRuleAdder<String>(constructor,
+ o -> Strings.toString(Iterables.getOnlyElement(o)), "");
+ }
+
+ public static PredicateSerializationRuleAdder<Void> noArgConstructor(Supplier<Predicate<?>> constructor) {
+ return new PredicateSerializationRuleAdder<Void>(
+ (o) -> constructor.get(), o -> null, null);
+ }
+
+ /** Preferred name for predicate when serializing. Defaults to the predicate name in the output of the {@link #sample(Predicate)}. */
+ public PredicateSerializationRuleAdder<T> preferredName(String preferredName) {
+ this.preferredName = preferredName;
+ return this;
+ }
+
+ /** Other predicates which are different to the type indicated by {@link #sample(Predicate)} but equivalent,
+ * and after serialization will be represented by {@link #preferredName} and after deserialization
+ * will result in the {@link Predicate} produced by {@link #constructor}. */
+ public PredicateSerializationRuleAdder<T> equivalentNames(String ...equivs) {
+ for (String equiv: equivs) equivalentNames.add(equiv);
+ return this;
+ }
+
+ /** Sample of what the {@link #constructor} will produce, used to recognise this rule when parsing.
+ * Can be omitted if {@link #sampleArg(Object)} supplied or its default is accepted. */
+ public PredicateSerializationRuleAdder<T> sample(Predicate<?> samplePreferredPredicate) {
+ predicateSample = samplePreferredPredicate;
+ return this;
+ }
+
+ /** This should supply args accepted by {@link #constructor} to generate a {@link #sample(Predicate)}.
+ * At most one of this or {@link #sample(Predicate)} should be supplied.
+ * If the constructor accepts a default empty list/string/null then these can be omitted. */
+ public PredicateSerializationRuleAdder<T> sampleArg(T arg) {
+ constructorSampleInput = arg;
+ return this;
+ }
+
+ /** Other predicates which are different to the type indicated by {@link #sample(Predicate)} but equivalent,
+ * and after serialization will be represented by {@link #preferredName} and after deserialization
+ * will result in the {@link Predicate} produced by {@link #constructor}. */
+ public PredicateSerializationRuleAdder<T> equivalentPredicates(Predicate<?> ...equivs) {
+ for (Predicate<?> equiv: equivs) equivalentPredicateSamples.add(equiv);
+ return this;
+ }
+
+ public void add(ConstraintSerialization constraintSerialization) {
+ this.serialization = constraintSerialization;
+ if (predicateSample==null) predicateSample = constructor.apply(constructorSampleInput);
+ String toStringName = Strings.removeAfter(Preconditions.checkNotNull(predicateSample, "sample or sampleArg must be supplied").toString(), "(", false);
+ if (preferredName==null) {
+ preferredName = toStringName;
+ } else {
+ constraintSerialization.predicateToStringToPreferredName.put(preferredName, preferredName);
+ }
+ constraintSerialization.predicateToStringToPreferredName.put(toStringName, preferredName);
+
+ for (String equiv: equivalentNames) {
+ constraintSerialization.predicateToStringToPreferredName.put(equiv, preferredName);
+ }
+
+ constraintSerialization.predicatePreferredNameToConstructor.put(preferredName, constructor.compose(constructorArgsFromList));
+
+ for (Predicate<?> equiv: equivalentPredicateSamples) {
+ String equivToStringName = Strings.removeAfter(equiv.toString(), "(", false);
+ constraintSerialization.predicateToStringToPreferredName.put(equivToStringName, preferredName);
+ }
+ }
+ }
+
+ private static String GROUP(String in) { return "("+in+")"; }
+ private static String NOT_CHARSET(String ...in) { return "[^"+Strings.join(in, "")+"]"; }
+ private static String OR_GROUP(String ...in) { return GROUP(Strings.join(in, "|")); }
+ private static String ZERO_OR_MORE(String in) { return in + "*"; }
+
+ private static String DOUBLE_QUOTED_STRING = "\""+GROUP(ZERO_OR_MORE(OR_GROUP(NOT_CHARSET("\\", "\""), "\\.")))+"\"";
+ private static String SINGLE_QUOTED_STRING = "\'"+GROUP(ZERO_OR_MORE(OR_GROUP(NOT_CHARSET("\\", "\'"), "\\.")))+"\'";
+
+ private static String PREDICATE = "[A-Za-z0-9_\\-\\.]+";
+
+ private static Pattern PATTERN_START_WITH_QUOTED_STRING = Pattern.compile("^"+OR_GROUP(DOUBLE_QUOTED_STRING, SINGLE_QUOTED_STRING));
+ private static Pattern PATTERN_START_WITH_PREDICATE = Pattern.compile("^"+GROUP(PREDICATE));
+
+ {
+ init();
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private void init() {
+ PredicateSerializationRuleAdder.predicateListConstructor((o) -> ConfigConstraints.required()).
+ equivalentPredicates(Predicates.notNull(), StringPredicates.isNonBlank()).add(this);
+
+ PredicateSerializationRuleAdder.predicateListConstructor((o) -> Predicates.or((Iterable)o)).preferredName("any").equivalentNames("or").add(this);
+ PredicateSerializationRuleAdder.predicateListConstructor((o) -> /* and predicate is default when given list */ toPredicateFromJson(o)).preferredName("all").sample(Predicates.and(Collections.emptyList())).equivalentNames("and").add(this);
+ PredicateSerializationRuleAdder.noArgConstructor(() -> Predicates.alwaysFalse()).add(this);
+ PredicateSerializationRuleAdder.noArgConstructor(() -> Predicates.alwaysTrue()).add(this);
+
+ PredicateSerializationRuleAdder.stringConstructor(StringPredicates::matchesRegex).preferredName("regex").add(this);
+ PredicateSerializationRuleAdder.stringConstructor(StringPredicates::matchesGlob).preferredName("glob").add(this);
+ }
+
+ public static ConstraintSerialization INSTANCE = new ConstraintSerialization();
+
+ private ConstraintSerialization() {}
+
+ public List<Object> toJsonList(ConfigKey<?> config) {
+ return toJsonList(config.getConstraint());
+ }
+
+ public List<Object> toJsonList(Predicate<?> constraint) {
+ // map twice to clean it (flatten "and" lists, etc)
+ // but if not possible go with progressively simpler items
+ try {
+ return toExactJsonList(toPredicateFromJson(toExactJsonList(constraint)));
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ try {
+ return toExactJsonList(constraint);
+ } catch (Exception e2) {
+ Exceptions.propagateIfFatal(e);
+ return Collections.singletonList(constraint.toString());
+ }
+ }
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public List<Object> toExactJsonList(Predicate<?> constraint) {
+ StringConstraintParser parser = StringConstraintParser.forConstraint(this, Strings.toString(constraint));
+ if (!parser.parse()) throw new IllegalStateException("cannot match: "+constraint);
+ if (parser.result instanceof Map && ((Map)parser.result).size()==1 && ((Map)parser.result).containsKey("all")) {
+ return (List<Object>) ((Map)parser.result).get("all");
+ }
+ return ImmutableList.of(parser.result);
+ }
+
+ private static class StringConstraintParser {
+ ConstraintSerialization serialization;
+ String remaining;
+ Object result;
+ List<Object> resultList = MutableList.of();
+ boolean list = false;
+
+ static StringConstraintParser forConstraint(ConstraintSerialization serialization, String in) {
+ StringConstraintParser result = new StringConstraintParser();
+ result.serialization = serialization;
+ result.remaining = in;
+ return result;
+ }
+
+ static StringConstraintParser forArgsInternal(ConstraintSerialization serialization, String in) {
+ StringConstraintParser result = forConstraint(serialization, in);
+ result.list = true;
+ return result;
+ }
+
+ boolean parse() {
+ remaining = remaining.trim();
+ Matcher m = PATTERN_START_WITH_PREDICATE.matcher(remaining);
+ if (!m.find()) {
+ if (!list) return false;
+ // when looking at args,
+ // allow empty list
+ if (remaining.startsWith(")")) {
+ result = resultList;
+ return true;
+ }
+ // and allow strings
+ m = PATTERN_START_WITH_QUOTED_STRING.matcher(remaining);
+ if (!m.find()) {
+ return false;
+ }
+ result = JavaStringEscapes.unwrapJavaString(m.group());
+ remaining = remaining.substring(m.end());
+ } else {
+ String p1 = m.group(1);
+ String p2 = serialization.predicateToStringToPreferredName.get(p1);
+ if (p2==null) p2 = p1;
+ remaining = remaining.substring(m.end()).trim();
+
+ if (!remaining.startsWith("(")) {
+ result = p2;
+ } else {
+ remaining = remaining.substring(1).trim();
+ StringConstraintParser args = forArgsInternal(serialization, remaining);
+ if (!args.parse()) return false;
+ if (args.resultList.isEmpty()) {
+ result = p2;
+ } else if (args.resultList.size()==1) {
+ result = MutableMap.of(p2, Iterables.getOnlyElement(args.resultList));
+ } else {
+ result = MutableMap.of(p2, args.result);
+ }
+ remaining = args.remaining;
+ if (!remaining.startsWith(")")) return false;
+ remaining = remaining.substring(1).trim();
+ }
+ if (!list) return remaining.isEmpty();
+ }
+ resultList.add(result);
+ if (remaining.isEmpty() || remaining.startsWith(")")) {
+ result = resultList;
+ return true;
+ }
+ if (!remaining.startsWith(",")) return false;
+ remaining = remaining.substring(1);
+ return parse();
+ }
+ }
+
+ private void collectPredicateListFromJson(Object o, List<Predicate<?>> result) {
+ if (o instanceof Collection) {
+ ((Collection<?>)o).stream().forEach(i -> collectPredicateListFromJson(i, result));
+ return;
+ }
+ Predicate<?> p = toPredicateFromJson(o);
+ if (Predicates.alwaysTrue().equals(p)) {
+ // no point in keeping this one
+ return;
+ }
+ result.add(p);
+ }
+ public Predicate<?> toPredicateFromJson(Object o) {
+ if (o instanceof Collection) {
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ Predicate<?> result2 = and((List)toPredicateListFromJsonList((Collection<?>)o));
+ return result2;
+ }
+
+ String key;
+ List<Object> args;
+ if (o instanceof String) {
+ key = (String)o;
+ args = MutableList.of();
+ } else if (o instanceof Map) {
+ if (((Map<?,?>)o).size()!=1) {
+ throw new IllegalArgumentException("Unsupported constraint; map input should have a single key: "+o);
+ }
+ // we only support single-key maps with string as key and value as list (of args) or other type as single arg, as in predicateName(args)
+ key = (String) Iterables.getOnlyElement( ((Map<?,?>)o).keySet() );
+ Object v = Iterables.getOnlyElement( ((Map<?,?>)o).values() );
+ if (v instanceof Iterable) {
+ args = MutableList.copyOf((Iterable<?>)v);
+ } else {
+ args = Collections.singletonList(v);
+ }
+ } else if (o instanceof Predicate) {
+ return (Predicate<?>)o;
+ } else {
+ throw new IllegalArgumentException("Unsupported constraint; constraint should be string, list, or single-key map: "+o);
+ }
+ Function<List<?>, Predicate<?>> constructor = predicatePreferredNameToConstructor.get(key);
+ if (constructor==null) {
+ String preferredName = predicateToStringToPreferredName.get(key);
+ if (preferredName!=null) {
+ constructor = predicatePreferredNameToConstructor.get(preferredName);
+ if (constructor==null) {
+ throw new IllegalArgumentException("Incomplete constraint: "+key+", maps to "+preferredName+", but no constructor known");
+ }
+ } else {
+ throw new IllegalArgumentException("Unsupported constraint: "+key);
+ }
+ }
+ return constructor.apply(args);
+ }
+
+ private <T> Predicate<?> and(Iterable<Predicate<? super T>> preds) {
+ Iterator<Predicate<? super T>> pi = preds.iterator();
+ if (!pi.hasNext()) return Predicates.alwaysTrue();
+ Predicate<?> first = pi.next();
+ if (!pi.hasNext()) return first;
+ return Predicates.and(preds);
+ }
+ public List<Predicate<?>> toPredicateListFromJsonList(Collection<?> o) {
+ List<Predicate<?>> result = MutableList.of();
+ collectPredicateListFromJson(o, result);
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/bd34655c/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
new file mode 100644
index 0000000..2065044
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.objs;
+
+import java.util.List;
+
+import org.apache.brooklyn.core.config.ConfigConstraints;
+import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.text.StringPredicates;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+
+public class ConstraintSerializationTest extends BrooklynMgmtUnitTestSupport {
+
+ @Test
+ public void testSimple() {
+ assertPredJsonBidi(ConfigConstraints.required(), MutableList.of("required"));
+ }
+
+ @Test
+ public void testInteresting() {
+ assertPredJsonBidi(Predicates.and(ConfigConstraints.required(), StringPredicates.matchesRegex(".*")),
+ MutableList.of("required", MutableMap.of("regex", ".*")));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testNestedAnd() {
+ Predicate<String> p = Predicates.<String>and(
+ ConfigConstraints.required(),
+ Predicates.and(Predicates.alwaysTrue()),
+ Predicates.<String>and(StringPredicates.matchesRegex(".*")));
+ Assert.assertEquals(ConstraintSerialization.INSTANCE.toJsonList(p),
+ MutableList.of("required", MutableMap.of("regex", ".*")));
+ }
+
+ @Test
+ public void testAltName() {
+ Predicate<String> p = StringPredicates.matchesGlob("???*");
+ Assert.assertEquals(ConstraintSerialization.INSTANCE.toPredicateFromJson(
+ MutableList.of(MutableMap.of("matchesGlob", "???*"))).toString(), p.toString());
+ Assert.assertEquals(ConstraintSerialization.INSTANCE.toPredicateFromJson(
+ MutableList.of(MutableMap.of("glob", "???*"))).toString(), p.toString());
+ Assert.assertEquals(ConstraintSerialization.INSTANCE.toJsonList(p),
+ MutableList.of(MutableMap.of("glob", "???*")));
+ }
+
+ @Test
+ public void testAltPred() {
+ Predicate<?> p = Predicates.notNull();
+ Assert.assertEquals(ConstraintSerialization.INSTANCE.toJsonList(p),
+ MutableList.of("required"));
+ Assert.assertEquals(ConstraintSerialization.INSTANCE.toPredicateFromJson("required").toString(),
+ ConfigConstraints.required().toString());
+ }
+
+ private void assertPredJsonBidi(Predicate<?> pred, List<?> json) {
+ Assert.assertEquals(ConstraintSerialization.INSTANCE.toJsonList(pred), json);
+ // some predicates don't support equals, but all (the ones we use) must support toString
+ Assert.assertEquals(ConstraintSerialization.INSTANCE.toPredicateFromJson(json).toString(), pred.toString());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/bd34655c/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/ConfigSummary.java
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/ConfigSummary.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/ConfigSummary.java
index 49aa2fe..c6f1ec6 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/ConfigSummary.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/ConfigSummary.java
@@ -28,17 +28,14 @@ import java.util.Objects;
import javax.annotation.Nullable;
import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.objs.ConstraintSerialization;
import org.apache.brooklyn.util.collections.Jsonya;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.javalang.coerce.TypeCoercer;
-import org.apache.brooklyn.util.text.StringPredicates;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.base.Function;
-import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -64,7 +61,7 @@ public class ConfigSummary implements HasName, Serializable {
@JsonInclude(Include.NON_NULL)
private final Boolean pinned;
@JsonInclude(Include.NON_NULL)
- private final List<String> constraints;
+ private final List<Object> constraints;
@JsonInclude(Include.NON_NULL)
private final Map<String, URI> links;
@@ -84,7 +81,7 @@ public class ConfigSummary implements HasName, Serializable {
@JsonProperty("priority") Double priority,
@JsonProperty("possibleValues") List<Map<String, String>> possibleValues,
@JsonProperty("pinned") Boolean pinned,
- @JsonProperty("constraints") List<String> constraints,
+ @JsonProperty("constraints") List<?> constraints,
@JsonProperty("links") Map<String, URI> links) {
this.name = name;
this.type = type;
@@ -95,7 +92,7 @@ public class ConfigSummary implements HasName, Serializable {
this.priority = priority;
this.possibleValues = possibleValues;
this.pinned = pinned;
- this.constraints = (constraints == null) ? ImmutableList.<String>of() : ImmutableList.copyOf(constraints);
+ this.constraints = (constraints == null) ? ImmutableList.<Object>of() : ImmutableList.copyOf(constraints);
this.links = (links == null) ? ImmutableMap.<String, URI>of() : ImmutableMap.copyOf(links);
}
@@ -111,9 +108,7 @@ public class ConfigSummary implements HasName, Serializable {
this.label = label;
this.priority = priority;
this.pinned = pinned;
- this.constraints = !config.getConstraint().equals(Predicates.alwaysTrue())
- ? ImmutableList.of((config.getConstraint().getClass().equals(StringPredicates.isNonBlank().getClass()) ? "required" : config.getConstraint().toString()))
- : ImmutableList.<String>of();
+ this.constraints = ConstraintSerialization.INSTANCE.toJsonList(config);
if (config.getType().isEnum()) {
this.type = Enum.class.getName();
this.defaultValue = config.getDefaultValue() instanceof Enum? ((Enum<?>) config.getDefaultValue()).name() :
@@ -175,7 +170,7 @@ public class ConfigSummary implements HasName, Serializable {
return pinned;
}
- public List<String> getConstraints() {
+ public List<Object> getConstraints() {
return constraints;
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/bd34655c/utils/common/src/main/java/org/apache/brooklyn/util/text/StringPredicates.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/text/StringPredicates.java b/utils/common/src/main/java/org/apache/brooklyn/util/text/StringPredicates.java
index 2006e65..b57b1db 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/text/StringPredicates.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/text/StringPredicates.java
@@ -26,6 +26,7 @@ import java.util.Set;
import javax.annotation.Nullable;
import org.apache.brooklyn.util.collections.MutableSet;
+import org.apache.brooklyn.util.text.StringEscapes.JavaStringEscapes;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@@ -109,7 +110,7 @@ public class StringPredicates {
@Override
public String toString() {
- return "containsLiteralCaseInsensitive("+fragment+")";
+ return "containsLiteralCaseInsensitive("+JavaStringEscapes.wrapJavaString(fragment)+")";
}
}
@@ -131,7 +132,7 @@ public class StringPredicates {
@Override
public String toString() {
- return "containsLiteral("+fragment+")";
+ return "containsLiteral("+JavaStringEscapes.wrapJavaString(fragment)+")";
}
}
@@ -210,7 +211,7 @@ public class StringPredicates {
}
@Override
public String toString() {
- return "startsWith("+prefix+")";
+ return "startsWith("+JavaStringEscapes.wrapJavaString(prefix)+")";
}
}
@@ -284,7 +285,7 @@ public class StringPredicates {
}
@Override
public String toString() {
- return "matchesRegex("+regex+")";
+ return "matchesRegex("+JavaStringEscapes.wrapJavaString(regex)+")";
}
}
@@ -303,7 +304,7 @@ public class StringPredicates {
}
@Override
public String toString() {
- return "matchesGlob("+glob+")";
+ return "matchesGlob("+JavaStringEscapes.wrapJavaString(glob)+")";
}
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/bd34655c/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java b/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
index d7ffd4b..1eb1435 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
@@ -193,7 +193,27 @@ public class Strings {
}
return string.substring(index);
}
-
+
+ /**
+ * Removes everything after the marker, optionally also removing the marker.
+ * If marker not found the string is unchanged.
+ */
+ public static String removeAfter(String string, String marker, boolean includeMarker) {
+ int i = string.indexOf(marker);
+ if (i==-1) return string;
+ return string.substring(0, i + (includeMarker ? marker.length() : 0));
+ }
+
+ /**
+ * Removes everything before the marker, optionally also removing the marker.
+ * If marker not found the string is unchanged.
+ */
+ public static String removeBefore(String string, String marker, boolean includeMarker) {
+ int i = string.indexOf(marker);
+ if (i==-1) return string;
+ return string.substring(i + (includeMarker ? 0 : marker.length()));
+ }
+
/** convenience for {@link com.google.common.base.Joiner} */
public static String join(Iterable<? extends Object> list, String separator) {
if (list==null) return null;
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/bd34655c/utils/common/src/test/java/org/apache/brooklyn/test/AssertsTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/test/AssertsTest.java b/utils/common/src/test/java/org/apache/brooklyn/test/AssertsTest.java
index 1105acd..96e31fd 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/test/AssertsTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/test/AssertsTest.java
@@ -128,7 +128,7 @@ public class AssertsTest {
try {
Asserts.assertStringMatchesRegex("hello", "hello", "he");
Asserts.shouldHaveFailedPreviously();
- } catch (AssertionError e) { Asserts.expectedFailureContains(e, "hello", "matchesRegex(he)"); }
+ } catch (AssertionError e) { Asserts.expectedFailureContains(e, "hello", "matchesRegex(\"he\")"); }
}
@Test
[3/7] brooklyn-server git commit: accept toStrings in/as json
Posted by al...@apache.org.
accept toStrings in/as json
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/5fec2756
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/5fec2756
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/5fec2756
Branch: refs/heads/master
Commit: 5fec2756f61b6bba1f37d96a04c07ef9229ec4de
Parents: 0d6f572
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Sep 21 12:32:55 2018 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Sep 21 12:32:55 2018 +0100
----------------------------------------------------------------------
.../brooklyn/core/objs/ConstraintSerialization.java | 6 ++++++
.../brooklyn/core/objs/ConstraintSerializationTest.java | 12 ++++++++++++
2 files changed, 18 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/5fec2756/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java b/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
index 57258bc..6844a72 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
@@ -314,6 +314,12 @@ public class ConstraintSerialization {
List<Object> args;
if (o instanceof String) {
key = (String)o;
+ if (key.indexOf("(")>=0) {
+ // it wasn't json; delegate to the parser again
+ StringConstraintParser parser = StringConstraintParser.forConstraint(this, key);
+ if (!parser.parse()) throw new IllegalStateException("cannot match: "+key);
+ return toPredicateFromJson(parser.result);
+ }
args = MutableList.of();
} else if (o instanceof Map) {
if (((Map<?,?>)o).size()!=1) {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/5fec2756/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
index 2065044..539fc87 100644
--- a/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
@@ -67,6 +67,18 @@ public class ConstraintSerializationTest extends BrooklynMgmtUnitTestSupport {
}
@Test
+ public void testAcceptsMap() {
+ Predicate<String> p = StringPredicates.matchesGlob("???*");
+ Assert.assertEquals(ConstraintSerialization.INSTANCE.toPredicateFromJson(MutableMap.of("matchesGlob", "???*")).toString(), p.toString());
+ }
+
+ @Test
+ public void testAcceptsString() {
+ Predicate<String> p = StringPredicates.matchesGlob("???*");
+ Assert.assertEquals(ConstraintSerialization.INSTANCE.toPredicateFromJson("matchesGlob(\"???*\")").toString(), p.toString());
+ }
+
+ @Test
public void testAltPred() {
Predicate<?> p = Predicates.notNull();
Assert.assertEquals(ConstraintSerialization.INSTANCE.toJsonList(p),
[2/7] brooklyn-server git commit: add {forbidden, required}{If,
Unless} constraints
Posted by al...@apache.org.
add {forbidden,required}{If,Unless} constraints
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/0d6f5721
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/0d6f5721
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/0d6f5721
Branch: refs/heads/master
Commit: 0d6f57219bd7ce36c912fddd26f37a46c6f8dbc2
Parents: bd34655
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Sep 21 11:49:47 2018 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Sep 21 11:49:47 2018 +0100
----------------------------------------------------------------------
.../brooklyn/core/config/ConfigConstraints.java | 69 ++++++++++
.../core/objs/ConstraintSerialization.java | 13 +-
.../brooklyn/util/core/ResourcePredicates.java | 6 +-
.../core/config/ConfigKeyConstraintTest.java | 133 ++++++++++++++-----
.../java/org/apache/brooklyn/test/Asserts.java | 16 ++-
5 files changed, 195 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d6f5721/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java b/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
index 35f672e..4ee584d 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
@@ -30,6 +30,7 @@ import org.apache.brooklyn.api.objs.BrooklynObject;
import org.apache.brooklyn.api.objs.EntityAdjunct;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.core.objs.AbstractEntityAdjunct;
import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
import org.apache.brooklyn.core.objs.BrooklynObjectPredicate;
@@ -37,6 +38,7 @@ import org.apache.brooklyn.core.objs.ConstraintSerialization;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.ReferenceWithError;
import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.text.StringEscapes.JavaStringEscapes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -243,4 +245,71 @@ public abstract class ConfigConstraints<T extends BrooklynObject> {
return "required()";
}
}
+
+ private static abstract class OtherKeyPredicate implements BrooklynObjectPredicate<Object> {
+ private String otherKeyName;
+
+ public OtherKeyPredicate(String otherKeyName) {
+ this.otherKeyName = otherKeyName;
+ }
+
+ public abstract String predicateName();
+
+ @Override
+ public String toString() {
+ return predicateName()+"("+JavaStringEscapes.wrapJavaString(otherKeyName)+")";
+ }
+
+ @Override
+ public boolean apply(Object input) {
+ return apply(input, BrooklynTaskTags.getContextEntity(Tasks.current()));
+ }
+
+ @Override
+ public boolean apply(Object input, BrooklynObject context) {
+ if (context==null) return true;
+ // would be nice to offer an explanation, but that will need a richer API or a thread local
+ return test(input, context.config().get(ConfigKeys.newConfigKey(Object.class, otherKeyName)));
+ }
+
+ public abstract boolean test(Object thisValue, Object otherValue);
+
+ }
+
+ public static Predicate<Object> forbiddenIf(String otherKeyName) { return new ForbiddenIfPredicate(otherKeyName); }
+ public static class ForbiddenIfPredicate extends OtherKeyPredicate {
+ public ForbiddenIfPredicate(String otherKeyName) { super(otherKeyName); }
+ @Override public String predicateName() { return "forbiddenIf"; }
+ @Override public boolean test(Object thisValue, Object otherValue) {
+ return (thisValue==null) || (otherValue==null);
+ }
+ }
+
+ public static Predicate<Object> forbiddenUnless(String otherKeyName) { return new ForbiddenUnlessPredicate(otherKeyName); }
+ public static class ForbiddenUnlessPredicate extends OtherKeyPredicate {
+ public ForbiddenUnlessPredicate(String otherKeyName) { super(otherKeyName); }
+ @Override public String predicateName() { return "forbiddenUnless"; }
+ @Override public boolean test(Object thisValue, Object otherValue) {
+ return (thisValue==null) || (otherValue!=null);
+ }
+ }
+
+ public static Predicate<Object> requiredIf(String otherKeyName) { return new RequiredIfPredicate(otherKeyName); }
+ public static class RequiredIfPredicate extends OtherKeyPredicate {
+ public RequiredIfPredicate(String otherKeyName) { super(otherKeyName); }
+ @Override public String predicateName() { return "requiredIf"; }
+ @Override public boolean test(Object thisValue, Object otherValue) {
+ return (thisValue!=null) || (otherValue==null);
+ }
+ }
+
+ public static Predicate<Object> requiredUnless(String otherKeyName) { return new RequiredUnlessPredicate(otherKeyName); }
+ public static class RequiredUnlessPredicate extends OtherKeyPredicate {
+ public RequiredUnlessPredicate(String otherKeyName) { super(otherKeyName); }
+ @Override public String predicateName() { return "requiredUnless"; }
+ @Override public boolean test(Object thisValue, Object otherValue) {
+ return (thisValue!=null) || (otherValue!=null);
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d6f5721/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java b/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
index a6b7039..57258bc 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
@@ -34,6 +34,7 @@ import org.apache.brooklyn.core.config.ConfigConstraints;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
+import org.apache.brooklyn.util.core.ResourcePredicates;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.text.StringEscapes.JavaStringEscapes;
import org.apache.brooklyn.util.text.StringPredicates;
@@ -168,11 +169,19 @@ public class ConstraintSerialization {
PredicateSerializationRuleAdder.predicateListConstructor((o) -> Predicates.or((Iterable)o)).preferredName("any").equivalentNames("or").add(this);
PredicateSerializationRuleAdder.predicateListConstructor((o) -> /* and predicate is default when given list */ toPredicateFromJson(o)).preferredName("all").sample(Predicates.and(Collections.emptyList())).equivalentNames("and").add(this);
- PredicateSerializationRuleAdder.noArgConstructor(() -> Predicates.alwaysFalse()).add(this);
- PredicateSerializationRuleAdder.noArgConstructor(() -> Predicates.alwaysTrue()).add(this);
+ PredicateSerializationRuleAdder.noArgConstructor(Predicates::alwaysFalse).add(this);
+ PredicateSerializationRuleAdder.noArgConstructor(Predicates::alwaysTrue).add(this);
+
+ PredicateSerializationRuleAdder.noArgConstructor(ResourcePredicates::urlExists).preferredName("urlExists").add(this);
+ PredicateSerializationRuleAdder.noArgConstructor(StringPredicates::isBlank).add(this);
PredicateSerializationRuleAdder.stringConstructor(StringPredicates::matchesRegex).preferredName("regex").add(this);
PredicateSerializationRuleAdder.stringConstructor(StringPredicates::matchesGlob).preferredName("glob").add(this);
+
+ PredicateSerializationRuleAdder.stringConstructor(ConfigConstraints::forbiddenIf).add(this);
+ PredicateSerializationRuleAdder.stringConstructor(ConfigConstraints::forbiddenUnless).add(this);
+ PredicateSerializationRuleAdder.stringConstructor(ConfigConstraints::requiredIf).add(this);
+ PredicateSerializationRuleAdder.stringConstructor(ConfigConstraints::requiredUnless).add(this);
}
public static ConstraintSerialization INSTANCE = new ConstraintSerialization();
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d6f5721/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java b/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java
index 439aaae..240ab52 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java
@@ -22,7 +22,9 @@ package org.apache.brooklyn.util.core;
import javax.annotation.Nullable;
import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.core.objs.BrooklynObjectPredicate;
+import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.text.StringPredicates;
import org.apache.brooklyn.util.text.Strings;
@@ -54,7 +56,7 @@ public class ResourcePredicates {
@Override
public boolean apply(@Nullable String resource) {
- return apply(resource, null);
+ return apply(resource, BrooklynTaskTags.getContextEntity(Tasks.current()));
}
@Override
@@ -64,7 +66,7 @@ public class ResourcePredicates {
@Override
public String toString() {
- return "ResourcePredicates.exists()";
+ return "ResourcePredicates.urlExists()";
}
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d6f5721/core/src/test/java/org/apache/brooklyn/core/config/ConfigKeyConstraintTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/config/ConfigKeyConstraintTest.java b/core/src/test/java/org/apache/brooklyn/core/config/ConfigKeyConstraintTest.java
index 46710fb..a251cbc 100644
--- a/core/src/test/java/org/apache/brooklyn/core/config/ConfigKeyConstraintTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/config/ConfigKeyConstraintTest.java
@@ -20,11 +20,10 @@
package org.apache.brooklyn.core.config;
import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.fail;
import java.util.concurrent.Callable;
+import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.location.Location;
@@ -45,7 +44,6 @@ import org.apache.brooklyn.core.test.entity.TestEntityImpl;
import org.apache.brooklyn.core.test.policy.TestPolicy;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.javalang.JavaClassNames;
import org.apache.brooklyn.util.net.Networking;
import org.apache.brooklyn.util.time.Duration;
@@ -154,10 +152,9 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
public void testExceptionWhenEntityHasNullConfig() {
try {
app.createAndManageChild(EntitySpec.create(EntityWithNonNullConstraint.class));
- fail("Expected exception when managing entity with missing config");
+ Asserts.shouldHaveFailedPreviously("Expected exception when managing entity with missing config");
} catch (Exception e) {
- Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t);
+ Asserts.expectedFailureOfType(e, ConstraintViolationException.class);
}
}
@@ -176,10 +173,9 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
public void testExceptionWhenSubclassSetsInvalidDefaultValue() {
try {
app.createAndManageChild(EntitySpec.create(EntityProvidingDefaultValueForConfigKeyInRange.class));
- fail("Expected exception when managing entity setting invalid default value");
+ Asserts.shouldHaveFailedPreviously("Expected exception when managing entity setting invalid default value");
} catch (Exception e) {
- Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
+ Asserts.expectedFailureOfType(e, ConstraintViolationException.class);
}
}
@@ -188,10 +184,9 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
try {
app.createAndManageChild(EntitySpec.create(EntityWithNonNullConstraintWithNonNullDefault.class)
.configure(EntityWithNonNullConstraintWithNonNullDefault.NON_NULL_WITH_DEFAULT, (Object) null));
- fail("Expected exception when config key set to null");
+ Asserts.shouldHaveFailedPreviously("Expected exception when config key set to null");
} catch (Exception e) {
- Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
+ Asserts.expectedFailureOfType(e, ConstraintViolationException.class);
}
}
@@ -200,10 +195,9 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
try {
app.createAndManageChild(EntitySpec.create(EntityRequiringConfigKeyInRange.class)
.configure(ImmutableMap.of("test.conf.range", -1)));
- fail("Expected exception when managing entity with invalid config");
+ Asserts.shouldHaveFailedPreviously("Expected exception when managing entity with invalid config");
} catch (Exception e) {
- Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
+ Asserts.expectedFailureOfType(e, ConstraintViolationException.class);
}
}
@@ -214,10 +208,9 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
try {
testEntity.addChild(EntitySpec.create(EntityRequiringConfigKeyInRange.class)
.configure(EntityRequiringConfigKeyInRange.RANGE, -1));
- fail("Expected exception when managing child with invalid config");
+ Asserts.shouldHaveFailedPreviously("Expected exception when managing child with invalid config");
} catch (Exception e) {
- Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
+ Asserts.expectedFailureOfType(e, ConstraintViolationException.class);
}
}
@@ -228,10 +221,9 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
.configure(EntityWithNonNullConstraint.NON_NULL_CONFIG, (Object) null));
try {
ConfigConstraints.assertValid(p);
- fail("Expected exception when validating policy with missing config");
+ Asserts.shouldHaveFailedPreviously("Expected exception when validating policy with missing config");
} catch (Exception e) {
- Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
+ Asserts.expectedFailureOfType(e, ConstraintViolationException.class);
}
}
@@ -240,10 +232,9 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
try {
mgmt.getEntityManager().createPolicy(PolicySpec.create(PolicyWithConfigConstraint.class)
.configure(PolicyWithConfigConstraint.NON_NULL_CONFIG, (Object) null));
- fail("Expected exception when creating policy with missing config");
+ Asserts.shouldHaveFailedPreviously("Expected exception when creating policy with missing config");
} catch (Exception e) {
- Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
+ Asserts.expectedFailureOfType(e, ConstraintViolationException.class);
}
}
@@ -252,10 +243,9 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
try {
mgmt.getEntityManager().createEnricher(EnricherSpec.create(EnricherWithConfigConstraint.class)
.configure(EnricherWithConfigConstraint.PATTERN, "123.123.256.10"));
- fail("Expected exception when creating enricher with invalid config");
+ Asserts.shouldHaveFailedPreviously("Expected exception when config key set to null");
} catch (Exception e) {
- Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
+ Asserts.expectedFailureOfType(e, ConstraintViolationException.class);
}
}
@@ -289,7 +279,7 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
app.createAndManageChild(EntitySpec.create(EntityWithContextAwareConstraint.class)
.displayName("Mr. Big")
.configure("must-be-display-name", "Mr. Bag"));
- fail("Expected exception when managing entity with incorrect config");
+ Asserts.shouldHaveFailedPreviously("Expected exception when managing entity with incorrect config");
} catch (Exception e) {
Asserts.expectedFailureOfType(e, ConstraintViolationException.class);
}
@@ -306,7 +296,7 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
// NB the call above does not currently/necessarily apply validation
log.debug(JavaClassNames.niceClassAndMethod()+" got "+value+" for "+EntityRequiringConfigKeyInRange.RANGE+", now explicitly validating");
ConfigConstraints.assertValid(child);
- fail("Expected exception when managing entity with incorrect config; instead passed assertion and got: "+value);
+ Asserts.shouldHaveFailedPreviously("Expected exception when managing entity with incorrect config; instead passed assertion and got: "+value);
} catch (Exception e) {
Asserts.expectedFailureOfType(e, ConstraintViolationException.class);
}
@@ -349,11 +339,90 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
public void testCannotUpdateConfigToInvalidValue(BrooklynObject object) {
try {
object.config().set(EntityRequiringConfigKeyInRange.RANGE, -1);
- fail("Expected exception when calling config().set with invalid value on " + object);
+ Asserts.shouldHaveFailedPreviously("Expected exception when calling config().set with invalid value on " + object);
} catch (Exception e) {
- Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
+ Asserts.expectedFailureOfType(e, ConstraintViolationException.class);
}
}
+ public static interface EntityForForbiddenAndRequiredConditionalConstraints extends TestEntity {
+ ConfigKey<Object> X = ConfigKeys.builder(Object.class).name("x")
+ .build();
+ }
+ @ImplementedBy(EntityForForbiddenAndRequiredConditionalConstraintsForbiddenIfImpl.class)
+ public static interface EntityForForbiddenAndRequiredConditionalConstraintsForbiddenIf extends EntityForForbiddenAndRequiredConditionalConstraints {
+ static ConfigKey<Object> FI = ConfigKeys.builder(Object.class).name("forbiddenIfX")
+ .constraint(ConfigConstraints.forbiddenIf("x")).build();
+ }
+ public static class EntityForForbiddenAndRequiredConditionalConstraintsForbiddenIfImpl extends TestEntityImpl implements EntityForForbiddenAndRequiredConditionalConstraintsForbiddenIf {}
+
+ @ImplementedBy(EntityForForbiddenAndRequiredConditionalConstraintsForbiddenUnlessImpl.class)
+ public static interface EntityForForbiddenAndRequiredConditionalConstraintsForbiddenUnless extends EntityForForbiddenAndRequiredConditionalConstraints {
+ static ConfigKey<Object> FU = ConfigKeys.builder(Object.class).name("forbiddenUnlessX")
+ .constraint(ConfigConstraints.forbiddenUnless("x")).build();
+ }
+ public static class EntityForForbiddenAndRequiredConditionalConstraintsForbiddenUnlessImpl extends TestEntityImpl implements EntityForForbiddenAndRequiredConditionalConstraintsForbiddenUnless {}
+
+ @ImplementedBy(EntityForForbiddenAndRequiredConditionalConstraintsRequiredIfImpl.class)
+ public static interface EntityForForbiddenAndRequiredConditionalConstraintsRequiredIf extends EntityForForbiddenAndRequiredConditionalConstraints {
+ static ConfigKey<Object> RI = ConfigKeys.builder(Object.class).name("requiredIfX")
+ .constraint(ConfigConstraints.requiredIf("x")).build();
+ }
+ public static class EntityForForbiddenAndRequiredConditionalConstraintsRequiredIfImpl extends TestEntityImpl implements EntityForForbiddenAndRequiredConditionalConstraintsRequiredIf {}
+
+ @ImplementedBy(EntityForForbiddenAndRequiredConditionalConstraintsRequiredUnlessImpl.class)
+ public static interface EntityForForbiddenAndRequiredConditionalConstraintsRequiredUnless extends EntityForForbiddenAndRequiredConditionalConstraints {
+ static ConfigKey<Object> RU = ConfigKeys.builder(Object.class).name("requiredUnlessX")
+ .constraint(ConfigConstraints.requiredUnless("x")).build();
+ }
+ public static class EntityForForbiddenAndRequiredConditionalConstraintsRequiredUnlessImpl extends TestEntityImpl implements EntityForForbiddenAndRequiredConditionalConstraintsRequiredUnless {}
+
+ @Test
+ public void testForbiddenAndRequiredConditionalConstraintsForbiddenIf() {
+ assertKeyBehaviour(EntityForForbiddenAndRequiredConditionalConstraintsForbiddenIf.class, EntityForForbiddenAndRequiredConditionalConstraintsForbiddenIf.FI,
+ false, true, true, true);
+ }
+
+ @Test
+ public void testForbiddenAndRequiredConditionalConstraintsForbiddenUnless() {
+ assertKeyBehaviour(EntityForForbiddenAndRequiredConditionalConstraintsForbiddenUnless.class, EntityForForbiddenAndRequiredConditionalConstraintsForbiddenUnless.FU,
+ true, true, false, true);
+ }
+
+ @Test
+ public void testForbiddenAndRequiredConditionalConstraintsRequiredIf() {
+ assertKeyBehaviour(EntityForForbiddenAndRequiredConditionalConstraintsRequiredIf.class, EntityForForbiddenAndRequiredConditionalConstraintsRequiredIf.RI,
+ true, false, true, true);
+ }
+
+ @Test
+ public void testForbiddenAndRequiredConditionalConstraintsRequiredUnlelss() {
+ assertKeyBehaviour(EntityForForbiddenAndRequiredConditionalConstraintsRequiredUnless.class, EntityForForbiddenAndRequiredConditionalConstraintsRequiredUnless.RU,
+ true, true, true, false);
+ }
+
+ private void assertKeyBehaviour(Class<? extends Entity> clazz, ConfigKey<Object> key, boolean ifBoth, boolean ifJustX, boolean ifJustThis, boolean ifNone) {
+ assertKeyBehaviour("both set", clazz, true, key, true, ifBoth);
+ assertKeyBehaviour("only other key set", clazz, true, key, false, ifJustX);
+ assertKeyBehaviour("only this key set", clazz, false, key, true, ifJustThis);
+ assertKeyBehaviour("neither key set", clazz, false, key, false, ifNone);
+ }
+
+ private void assertKeyBehaviour(String description, Class<? extends Entity> clazz, boolean isXSet, ConfigKey<Object> key, boolean isKeySet, boolean shouldSucceed) {
+ try {
+ EntitySpec<?> spec = EntitySpec.create(clazz);
+ if (isXSet) spec.configure(EntityForForbiddenAndRequiredConditionalConstraints.X, "set");
+ if (isKeySet) spec.configure(key, "set");
+ app.createAndManageChild(spec);
+ if (!shouldSucceed) {
+ Asserts.shouldHaveFailedPreviously("Expected failure when testing "+key.getName()+" - "+description);
+ }
+ } catch (Exception e) {
+ if (!shouldSucceed) {
+ Asserts.expectedFailureOfType("Expected ConstraintViolationException when testing "+key.getName()+" - "+description, e, ConstraintViolationException.class);
+ } else {
+ throw new AssertionError("Expected success when testing "+key.getName()+" - "+description+"; instead got "+e, e);
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d6f5721/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java b/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
index 6975139..eb9275a 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
@@ -1261,17 +1261,21 @@ public class Asserts {
* or more usually the test failure of this method is thrown,
* with detail of the original {@link Throwable} logged and included in the caused-by.
*/
- @SuppressWarnings("unchecked")
public static void expectedFailureOfType(Throwable e, Class<?> permittedSupertype, Class<?> ...permittedSupertypes) {
+ expectedFailureOfType(null, e, permittedSupertype, permittedSupertypes);
+ }
+ @SuppressWarnings("unchecked")
+ public static void expectedFailureOfType(String message, Throwable e, Class<?> permittedSupertype, Class<?> ...permittedSupertypeExtras) {
+ @SuppressWarnings("rawtypes")
+ List<Class<?>> permittedSupertypes = MutableList.of(permittedSupertype).appendAll((List)Arrays.asList(permittedSupertypeExtras));
if (e instanceof ShouldHaveFailedPreviouslyAssertionError) throw (Error) e;
- Throwable match = Exceptions.getFirstThrowableOfType(e, (Class<? extends Throwable>) permittedSupertype);
- if (match != null) return;
for (Class<?> clazz: permittedSupertypes) {
- match = Exceptions.getFirstThrowableOfType(e, (Class<? extends Throwable>)clazz);
- if (match != null) return;
+ if (Exceptions.getFirstThrowableOfType(e, (Class<? extends Throwable>)clazz) != null) {
+ return;
+ }
}
rethrowPreferredException(e,
- new AssertionError("Error "+JavaClassNames.simpleClassName(e)+" is not any of the expected types: " + Arrays.asList(permittedSupertypes), e));
+ new AssertionError((message!=null ? message+": " : "") + "Error "+JavaClassNames.simpleClassName(e)+" is not any of the expected types: " + permittedSupertypes, e));
}
/** Tests {@link #expectedFailure(Throwable)} and that the <code>toString</code>
[4/7] brooklyn-server git commit: forgot to use deserialization
routines when parsing catalog input
Posted by al...@apache.org.
forgot to use deserialization routines when parsing catalog input
also test and fix for some edge-cases in serializing
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/fdb2784a
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/fdb2784a
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/fdb2784a
Branch: refs/heads/master
Commit: fdb2784a8bdc7a3bc53508a381b258539f7aafc0
Parents: 5fec275
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Sat Sep 22 01:24:09 2018 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Sat Sep 22 01:24:09 2018 +0100
----------------------------------------------------------------------
.../brooklyn/core/config/ConfigConstraints.java | 9 ++++
.../brooklyn/core/objs/BasicSpecParameter.java | 51 +-------------------
.../core/objs/ConstraintSerialization.java | 9 ++--
.../brooklyn/util/core/ResourcePredicates.java | 2 +-
.../core/objs/ConstraintSerializationTest.java | 45 +++++++++++++----
5 files changed, 52 insertions(+), 64 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fdb2784a/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java b/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
index 4ee584d..c234aae 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
@@ -22,6 +22,7 @@ package org.apache.brooklyn.core.config;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.Location;
@@ -244,6 +245,14 @@ public abstract class ConfigConstraints<T extends BrooklynObject> {
public String toString() {
return "required()";
}
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof RequiredPredicate) && obj.getClass().equals(getClass());
+ }
+ @Override
+ public int hashCode() {
+ return Objects.hash(toString());
+ }
}
private static abstract class OtherKeyPredicate implements BrooklynObjectPredicate<Object> {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fdb2784a/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java b/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
index 7c1bde0..7c777f8 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/BasicSpecParameter.java
@@ -18,8 +18,6 @@
*/
package org.apache.brooklyn.core.objs;
-import static com.google.common.base.Preconditions.checkArgument;
-
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
@@ -55,7 +53,6 @@ import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.text.StringPredicates;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -70,7 +67,6 @@ import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
import com.google.common.reflect.TypeToken;
public class BasicSpecParameter<T> implements SpecParameter<T>{
@@ -221,18 +217,6 @@ public class BasicSpecParameter<T> implements SpecParameter<T>{
.put("port", PortRange.class)
.build();
- private static final Map<String, Predicate<?>> BUILT_IN_CONSTRAINTS = ImmutableMap.<String, Predicate<?>>of(
- "required", StringPredicates.isNonBlank());
-
- private static final Map<String, Function<Object, Predicate<?>>> BUILT_IN_CONSTRAINT_FACTORIES = ImmutableMap.<String, Function<Object, Predicate<?>>>of(
- "regex", new Function<Object, Predicate<?>>() {
- @Override public Predicate<?> apply(Object input) {
- // TODO Could try to handle deferred supplier as well?
- checkArgument(input instanceof String, "Constraint regex value must be a string, but got %s (%s)",
- (input == null ? "null" : input.getClass().getName()), input);
- return StringPredicates.matchesRegex((String)input);
- }});
-
private static List<SpecParameter<?>> parseParameters(List<?> inputsRaw, Function<Object, Object> specialFlagTransformer, BrooklynClassLoadingContext loader) {
if (inputsRaw == null) return ImmutableList.of();
List<SpecParameter<?>> inputs = new ArrayList<>(inputsRaw.size());
@@ -381,40 +365,7 @@ public class BasicSpecParameter<T> implements SpecParameter<T>{
}
private static Predicate<?> parseConstraint(Object untypedConstraint, BrooklynClassLoadingContext loader) {
- // TODO Could try to handle deferred supplier as well?
- if (untypedConstraint instanceof Predicate) {
- // An explicit predicate (e.g. via "$brooklyn:object: ...")
- return (Predicate<?>) untypedConstraint;
- } else if (untypedConstraint instanceof String) {
- // build-in simple declaration, such as "required"
- String constraint = (String)untypedConstraint;
- if (BUILT_IN_CONSTRAINTS.containsKey(constraint)) {
- return BUILT_IN_CONSTRAINTS.get(constraint);
- } else {
- throw new IllegalArgumentException("The constraint '" + constraint + "' for a catalog input is not "
- + "recognized as a built-in (" + BUILT_IN_CONSTRAINTS.keySet() + " or "
- + BUILT_IN_CONSTRAINT_FACTORIES.keySet() + ")");
- }
- } else if (untypedConstraint instanceof Map) {
- // For example "regex: foo.*"
- Map<?,?> constraint = (Map<?,?>)untypedConstraint;
- if (constraint.size() == 1) {
- Object key = Iterables.getOnlyElement(constraint.keySet());
- Object val = constraint.get(key);
- if (BUILT_IN_CONSTRAINT_FACTORIES.containsKey(key)) {
- Function<Object, Predicate<?>> factory = BUILT_IN_CONSTRAINT_FACTORIES.get(key);
- return factory.apply(val);
- } else {
- throw new IllegalArgumentException("The constraint '" + constraint + "' for a catalog input is not "
- + "recognized as a built-in (" + BUILT_IN_CONSTRAINTS.keySet() + ")");
- }
- } else {
- throw new IllegalArgumentException("The config key constraint '" + constraint + "' is not supported - "
- + "it can handle only single key:value constraint.");
- }
- } else {
- throw new IllegalArgumentException("The constraint '" + untypedConstraint + "' for a catalog input is not recognized");
- }
+ return ConstraintSerialization.INSTANCE.toPredicateFromJson(untypedConstraint);
}
private static ConfigInheritance parseInheritance(Object obj, BrooklynClassLoadingContext loader) {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fdb2784a/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java b/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
index 6844a72..2fef0e8 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
@@ -214,6 +214,9 @@ public class ConstraintSerialization {
if (parser.result instanceof Map && ((Map)parser.result).size()==1 && ((Map)parser.result).containsKey("all")) {
return (List<Object>) ((Map)parser.result).get("all");
}
+ if ("Predicates.alwaysTrue".equals(parser.result)) {
+ return Collections.emptyList();
+ }
return ImmutableList.of(parser.result);
}
@@ -291,7 +294,7 @@ public class ConstraintSerialization {
}
}
- private void collectPredicateListFromJson(Object o, List<Predicate<?>> result) {
+ private void collectPredicateListFromJson(Object o, Collection<Predicate<?>> result) {
if (o instanceof Collection) {
((Collection<?>)o).stream().forEach(i -> collectPredicateListFromJson(i, result));
return;
@@ -361,9 +364,9 @@ public class ConstraintSerialization {
return Predicates.and(preds);
}
public List<Predicate<?>> toPredicateListFromJsonList(Collection<?> o) {
- List<Predicate<?>> result = MutableList.of();
+ Set<Predicate<?>> result = MutableSet.of();
collectPredicateListFromJson(o, result);
- return result;
+ return MutableList.copyOf(result);
}
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fdb2784a/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java b/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java
index 240ab52..effed58 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java
@@ -66,7 +66,7 @@ public class ResourcePredicates {
@Override
public String toString() {
- return "ResourcePredicates.urlExists()";
+ return "ResourcePredicates.exists()";
}
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fdb2784a/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
index 539fc87..a8fdb02 100644
--- a/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
@@ -58,10 +58,10 @@ public class ConstraintSerializationTest extends BrooklynMgmtUnitTestSupport {
@Test
public void testAltName() {
Predicate<String> p = StringPredicates.matchesGlob("???*");
- Assert.assertEquals(ConstraintSerialization.INSTANCE.toPredicateFromJson(
- MutableList.of(MutableMap.of("matchesGlob", "???*"))).toString(), p.toString());
- Assert.assertEquals(ConstraintSerialization.INSTANCE.toPredicateFromJson(
- MutableList.of(MutableMap.of("glob", "???*"))).toString(), p.toString());
+ assertSamePredicate(ConstraintSerialization.INSTANCE.toPredicateFromJson(
+ MutableList.of(MutableMap.of("matchesGlob", "???*"))), p);
+ assertSamePredicate(ConstraintSerialization.INSTANCE.toPredicateFromJson(
+ MutableList.of(MutableMap.of("glob", "???*"))), p);
Assert.assertEquals(ConstraintSerialization.INSTANCE.toJsonList(p),
MutableList.of(MutableMap.of("glob", "???*")));
}
@@ -69,13 +69,19 @@ public class ConstraintSerializationTest extends BrooklynMgmtUnitTestSupport {
@Test
public void testAcceptsMap() {
Predicate<String> p = StringPredicates.matchesGlob("???*");
- Assert.assertEquals(ConstraintSerialization.INSTANCE.toPredicateFromJson(MutableMap.of("matchesGlob", "???*")).toString(), p.toString());
+ assertSamePredicate(ConstraintSerialization.INSTANCE.toPredicateFromJson(MutableMap.of("matchesGlob", "???*")), p);
+ }
+
+ @Test
+ public void testAcceptsForbiddenIfMap() {
+ Predicate<Object> p = ConfigConstraints.forbiddenIf("x");
+ assertSamePredicate(ConstraintSerialization.INSTANCE.toPredicateFromJson(MutableMap.of("forbiddenIf", "x")), p);
}
@Test
public void testAcceptsString() {
Predicate<String> p = StringPredicates.matchesGlob("???*");
- Assert.assertEquals(ConstraintSerialization.INSTANCE.toPredicateFromJson("matchesGlob(\"???*\")").toString(), p.toString());
+ assertSamePredicate(ConstraintSerialization.INSTANCE.toPredicateFromJson("matchesGlob(\"???*\")"), p);
}
@Test
@@ -83,14 +89,33 @@ public class ConstraintSerializationTest extends BrooklynMgmtUnitTestSupport {
Predicate<?> p = Predicates.notNull();
Assert.assertEquals(ConstraintSerialization.INSTANCE.toJsonList(p),
MutableList.of("required"));
- Assert.assertEquals(ConstraintSerialization.INSTANCE.toPredicateFromJson("required").toString(),
- ConfigConstraints.required().toString());
+ assertSamePredicate(ConstraintSerialization.INSTANCE.toPredicateFromJson("required"),
+ ConfigConstraints.required());
+ }
+
+ @Test
+ public void testFlattens() {
+ assertSamePredicate(ConstraintSerialization.INSTANCE.toPredicateFromJson(MutableList.of("required", "required")),
+ ConfigConstraints.required());
+ }
+
+ @Test
+ public void testEmpty() {
+ assertSamePredicate(ConstraintSerialization.INSTANCE.toPredicateFromJson(MutableList.of()),
+ Predicates.alwaysTrue());
+ Assert.assertEquals(ConstraintSerialization.INSTANCE.toJsonList(Predicates.alwaysTrue()),
+ MutableList.of());
}
private void assertPredJsonBidi(Predicate<?> pred, List<?> json) {
Assert.assertEquals(ConstraintSerialization.INSTANCE.toJsonList(pred), json);
+ assertSamePredicate(ConstraintSerialization.INSTANCE.toPredicateFromJson(json), pred);
+ }
+
+ private static void assertSamePredicate(Predicate<?> p1, Predicate<?> p2) {
// some predicates don't support equals, but all (the ones we use) must support toString
- Assert.assertEquals(ConstraintSerialization.INSTANCE.toPredicateFromJson(json).toString(), pred.toString());
+ Assert.assertEquals(p1.toString(), p2.toString());
+ Assert.assertEquals(p1.getClass(), p2.getClass());
}
-
+
}
[5/7] brooklyn-server git commit: address further PR comments
Posted by al...@apache.org.
address further PR comments
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/fc1c5883
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/fc1c5883
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/fc1c5883
Branch: refs/heads/master
Commit: fc1c588381029a3623c155d88a76185d7e01f696
Parents: fdb2784
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Sat Sep 22 01:45:00 2018 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Sat Sep 22 01:45:00 2018 +0100
----------------------------------------------------------------------
.../apache/brooklyn/core/config/ConfigConstraints.java | 10 +++++-----
.../brooklyn/core/objs/ConstraintSerialization.java | 4 +++-
.../org/apache/brooklyn/util/core/ResourcePredicates.java | 2 +-
3 files changed, 9 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fc1c5883/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java b/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
index c234aae..67d8aef 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/ConfigConstraints.java
@@ -256,7 +256,7 @@ public abstract class ConfigConstraints<T extends BrooklynObject> {
}
private static abstract class OtherKeyPredicate implements BrooklynObjectPredicate<Object> {
- private String otherKeyName;
+ private final String otherKeyName;
public OtherKeyPredicate(String otherKeyName) {
this.otherKeyName = otherKeyName;
@@ -286,7 +286,7 @@ public abstract class ConfigConstraints<T extends BrooklynObject> {
}
public static Predicate<Object> forbiddenIf(String otherKeyName) { return new ForbiddenIfPredicate(otherKeyName); }
- public static class ForbiddenIfPredicate extends OtherKeyPredicate {
+ protected static class ForbiddenIfPredicate extends OtherKeyPredicate {
public ForbiddenIfPredicate(String otherKeyName) { super(otherKeyName); }
@Override public String predicateName() { return "forbiddenIf"; }
@Override public boolean test(Object thisValue, Object otherValue) {
@@ -295,7 +295,7 @@ public abstract class ConfigConstraints<T extends BrooklynObject> {
}
public static Predicate<Object> forbiddenUnless(String otherKeyName) { return new ForbiddenUnlessPredicate(otherKeyName); }
- public static class ForbiddenUnlessPredicate extends OtherKeyPredicate {
+ protected static class ForbiddenUnlessPredicate extends OtherKeyPredicate {
public ForbiddenUnlessPredicate(String otherKeyName) { super(otherKeyName); }
@Override public String predicateName() { return "forbiddenUnless"; }
@Override public boolean test(Object thisValue, Object otherValue) {
@@ -304,7 +304,7 @@ public abstract class ConfigConstraints<T extends BrooklynObject> {
}
public static Predicate<Object> requiredIf(String otherKeyName) { return new RequiredIfPredicate(otherKeyName); }
- public static class RequiredIfPredicate extends OtherKeyPredicate {
+ protected static class RequiredIfPredicate extends OtherKeyPredicate {
public RequiredIfPredicate(String otherKeyName) { super(otherKeyName); }
@Override public String predicateName() { return "requiredIf"; }
@Override public boolean test(Object thisValue, Object otherValue) {
@@ -313,7 +313,7 @@ public abstract class ConfigConstraints<T extends BrooklynObject> {
}
public static Predicate<Object> requiredUnless(String otherKeyName) { return new RequiredUnlessPredicate(otherKeyName); }
- public static class RequiredUnlessPredicate extends OtherKeyPredicate {
+ protected static class RequiredUnlessPredicate extends OtherKeyPredicate {
public RequiredUnlessPredicate(String otherKeyName) { super(otherKeyName); }
@Override public String predicateName() { return "requiredUnless"; }
@Override public boolean test(Object thisValue, Object otherValue) {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fc1c5883/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java b/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
index 2fef0e8..984e2e7 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
@@ -40,12 +40,14 @@ import org.apache.brooklyn.util.text.StringEscapes.JavaStringEscapes;
import org.apache.brooklyn.util.text.StringPredicates;
import org.apache.brooklyn.util.text.Strings;
+import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
+@Beta
public class ConstraintSerialization {
private final Map<String, String> predicateToStringToPreferredName = MutableMap.of();
@@ -184,7 +186,7 @@ public class ConstraintSerialization {
PredicateSerializationRuleAdder.stringConstructor(ConfigConstraints::requiredUnless).add(this);
}
- public static ConstraintSerialization INSTANCE = new ConstraintSerialization();
+ public final static ConstraintSerialization INSTANCE = new ConstraintSerialization();
private ConstraintSerialization() {}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fc1c5883/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java b/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java
index effed58..240ab52 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/ResourcePredicates.java
@@ -66,7 +66,7 @@ public class ResourcePredicates {
@Override
public String toString() {
- return "ResourcePredicates.exists()";
+ return "ResourcePredicates.urlExists()";
}
}
[7/7] brooklyn-server git commit: This closes #999
Posted by al...@apache.org.
This closes #999
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/a3d0ea06
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/a3d0ea06
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/a3d0ea06
Branch: refs/heads/master
Commit: a3d0ea06edcd15362688107f0afd9b153048c7e6
Parents: e27cc7b 3d214b8
Author: Aled Sage <al...@gmail.com>
Authored: Mon Sep 24 12:30:11 2018 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Mon Sep 24 12:30:11 2018 +0100
----------------------------------------------------------------------
.../brooklyn/core/config/ConfigConstraints.java | 103 +++++
.../brooklyn/core/objs/BasicSpecParameter.java | 51 +--
.../core/objs/ConstraintSerialization.java | 375 +++++++++++++++++++
.../brooklyn/util/core/ResourcePredicates.java | 6 +-
.../core/config/ConfigKeyConstraintTest.java | 133 +++++--
.../objs/BasicSpecParameterFromListTest.java | 5 +-
.../core/objs/ConstraintSerializationTest.java | 121 ++++++
.../brooklyn/rest/domain/ConfigSummary.java | 17 +-
.../java/org/apache/brooklyn/test/Asserts.java | 16 +-
.../brooklyn/util/text/StringPredicates.java | 11 +-
.../org/apache/brooklyn/util/text/Strings.java | 22 +-
.../org/apache/brooklyn/test/AssertsTest.java | 2 +-
12 files changed, 752 insertions(+), 110 deletions(-)
----------------------------------------------------------------------
[6/7] brooklyn-server git commit: split out notNull as different to
required=nonBlank, fix tests
Posted by al...@apache.org.
split out notNull as different to required=nonBlank, fix tests
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/3d214b89
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/3d214b89
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/3d214b89
Branch: refs/heads/master
Commit: 3d214b89fc5308451e5078ee4651f878eab6d081
Parents: fc1c588
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Sat Sep 22 02:19:42 2018 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Sat Sep 22 02:48:58 2018 +0100
----------------------------------------------------------------------
.../org/apache/brooklyn/core/objs/ConstraintSerialization.java | 3 ++-
.../brooklyn/core/objs/BasicSpecParameterFromListTest.java | 5 +++--
.../apache/brooklyn/core/objs/ConstraintSerializationTest.java | 2 +-
3 files changed, 6 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/3d214b89/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java b/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
index 984e2e7..32b71f0 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/ConstraintSerialization.java
@@ -167,12 +167,13 @@ public class ConstraintSerialization {
@SuppressWarnings({ "unchecked", "rawtypes" })
private void init() {
PredicateSerializationRuleAdder.predicateListConstructor((o) -> ConfigConstraints.required()).
- equivalentPredicates(Predicates.notNull(), StringPredicates.isNonBlank()).add(this);
+ equivalentPredicates(StringPredicates.isNonBlank()).add(this);
PredicateSerializationRuleAdder.predicateListConstructor((o) -> Predicates.or((Iterable)o)).preferredName("any").equivalentNames("or").add(this);
PredicateSerializationRuleAdder.predicateListConstructor((o) -> /* and predicate is default when given list */ toPredicateFromJson(o)).preferredName("all").sample(Predicates.and(Collections.emptyList())).equivalentNames("and").add(this);
PredicateSerializationRuleAdder.noArgConstructor(Predicates::alwaysFalse).add(this);
PredicateSerializationRuleAdder.noArgConstructor(Predicates::alwaysTrue).add(this);
+ PredicateSerializationRuleAdder.noArgConstructor(Predicates::notNull).add(this);
PredicateSerializationRuleAdder.noArgConstructor(ResourcePredicates::urlExists).preferredName("urlExists").add(this);
PredicateSerializationRuleAdder.noArgConstructor(StringPredicates::isBlank).add(this);
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/3d214b89/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java
index 887e054..3ce8d9c 100644
--- a/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromListTest.java
@@ -28,6 +28,7 @@ import java.util.List;
import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
import org.apache.brooklyn.api.objs.SpecParameter;
import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigConstraints;
import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext;
import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport;
import org.apache.brooklyn.util.text.StringPredicates;
@@ -99,7 +100,7 @@ public class BasicSpecParameterFromListTest extends BrooklynMgmtUnitTestSupport
assertEquals(type.getDefaultValue(), defaultValue);
assertEquals(type.getDescription(), description);
assertTrue(type.getInheritanceByContext().values().isEmpty(), "Unexpected inheritance: "+type.getInheritanceByContext());
- assertConstraint(type.getConstraint(), StringPredicates.isNonBlank());
+ assertConstraint(type.getConstraint(), ConfigConstraints.required());
}
@Test
@@ -132,7 +133,7 @@ public class BasicSpecParameterFromListTest extends BrooklynMgmtUnitTestSupport
"name", name,
"constraints", ImmutableList.of(constraint)));
ConfigKey<?> type = input.getConfigKey();
- assertConstraint(type.getConstraint(), StringPredicates.isNonBlank());
+ assertConstraint(type.getConstraint(), ConfigConstraints.required());
}
@Test(expectedExceptions = IllegalArgumentException.class)
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/3d214b89/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
index a8fdb02..bdbc5ad 100644
--- a/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/objs/ConstraintSerializationTest.java
@@ -86,7 +86,7 @@ public class ConstraintSerializationTest extends BrooklynMgmtUnitTestSupport {
@Test
public void testAltPred() {
- Predicate<?> p = Predicates.notNull();
+ Predicate<?> p = StringPredicates.isNonBlank();
Assert.assertEquals(ConstraintSerialization.INSTANCE.toJsonList(p),
MutableList.of("required"));
assertSamePredicate(ConstraintSerialization.INSTANCE.toPredicateFromJson("required"),