You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by dr...@apache.org on 2017/02/15 10:56:23 UTC
[1/2] brooklyn-server git commit: BROOKLYN-433: regex/obj config key
constraint in yaml
Repository: brooklyn-server
Updated Branches:
refs/heads/master 0f649fe17 -> 38396711d
BROOKLYN-433: regex/obj config key constraint in yaml
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/4bda12b7
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/4bda12b7
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/4bda12b7
Branch: refs/heads/master
Commit: 4bda12b70ffc2146aa60ac0ab40de52b3b266a8d
Parents: 0f649fe
Author: Aled Sage <al...@gmail.com>
Authored: Fri Feb 3 13:30:09 2017 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Mon Feb 13 14:22:56 2017 +0000
----------------------------------------------------------------------
.../camp/brooklyn/ConfigParametersYamlTest.java | 178 +++++++++++++++++++
.../brooklyn/core/objs/BasicSpecParameter.java | 69 +++++--
2 files changed, 235 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/4bda12b7/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigParametersYamlTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigParametersYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigParametersYamlTest.java
index d7040e5..fe602fe 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigParametersYamlTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigParametersYamlTest.java
@@ -22,6 +22,8 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -31,6 +33,7 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.PortRange;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.ConstraintViolationException;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.location.PortRanges;
import org.apache.brooklyn.core.sensor.Sensors;
@@ -52,6 +55,7 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@@ -750,6 +754,180 @@ public class ConfigParametersYamlTest extends AbstractYamlRebindTest {
assertEquals(entity.sensors().get(Sensors.newSensor(Object.class, "my.param.key")), 1234);
}
+ @Test
+ public void testConfigParameterConstraintRequired() throws Exception {
+ addCatalogItems(
+ "brooklyn.catalog:",
+ " itemType: entity",
+ " items:",
+ " - id: entity-with-keys",
+ " item:",
+ " type: "+TestEntity.class.getName(),
+ " brooklyn.parameters:",
+ " - name: testRequired",
+ " type: String",
+ " constraints:",
+ " - required");
+
+ String yamlNoVal = Joiner.on("\n").join(
+ "services:",
+ "- type: entity-with-keys");
+
+ String yamlWithVal = Joiner.on("\n").join(
+ "services:",
+ "- type: entity-with-keys",
+ " brooklyn.config:",
+ " testRequired: myval");
+
+ try {
+ createStartWaitAndLogApplication(yamlNoVal);
+ Asserts.shouldHaveFailedPreviously();
+ } catch (ConstraintViolationException e) {
+ // success
+ }
+
+ Entity app = createStartWaitAndLogApplication(yamlWithVal);
+ TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+ assertKeyEquals(entity, "testRequired", null, String.class, null, "myval");
+
+ // Rebind, and then check again that the config key is listed
+ Entity newApp = rebind();
+ TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
+ assertKeyEquals(newEntity, "testRequired", null, String.class, null, "myval");
+ }
+
+ @Test
+ public void testConfigParameterConstraintRegex() throws Exception {
+ addCatalogItems(
+ "brooklyn.catalog:",
+ " itemType: entity",
+ " items:",
+ " - id: entity-with-keys",
+ " item:",
+ " type: "+TestEntity.class.getName(),
+ " brooklyn.parameters:",
+ " - name: testRequired",
+ " type: String",
+ " constraints:",
+ " - regex: myprefix.*");
+
+ String yamlNoVal = Joiner.on("\n").join(
+ "services:",
+ "- type: entity-with-keys");
+
+ String yamlWrongVal = Joiner.on("\n").join(
+ "services:",
+ "- type: entity-with-keys",
+ " brooklyn.config:",
+ " testRequired: wrongval");
+
+ String yamlWithVal = Joiner.on("\n").join(
+ "services:",
+ "- type: entity-with-keys",
+ " brooklyn.config:",
+ " testRequired: myprefix-myVal");
+
+ try {
+ createStartWaitAndLogApplication(yamlNoVal);
+ Asserts.shouldHaveFailedPreviously();
+ } catch (ConstraintViolationException e) {
+ Asserts.expectedFailureContains(e, "matchesRegex"); // success
+ }
+
+ try {
+ createStartWaitAndLogApplication(yamlWrongVal);
+ Asserts.shouldHaveFailedPreviously();
+ } catch (ConstraintViolationException e) {
+ Asserts.expectedFailureContains(e, "Invalid value for", "wrongval"); // success
+ }
+
+ Entity app = createStartWaitAndLogApplication(yamlWithVal);
+ TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+ assertKeyEquals(entity, "testRequired", null, String.class, null, "myprefix-myVal");
+
+ // Rebind, and then check again that the config key is listed
+ Entity newApp = rebind();
+ TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
+ assertKeyEquals(newEntity, "testRequired", null, String.class, null, "myprefix-myVal");
+ }
+
+ @Test
+ public void testConfigParameterConstraintObject() throws Exception {
+ addCatalogItems(
+ "brooklyn.catalog:",
+ " itemType: entity",
+ " items:",
+ " - id: entity-with-keys",
+ " item:",
+ " type: "+TestEntity.class.getName(),
+ " brooklyn.parameters:",
+ " - name: testRequired",
+ " type: String",
+ " constraints:",
+ " - $brooklyn:object:",
+ " type: " + PredicateRegexPojo.class.getName(),
+ " object.fields:",
+ " regex: myprefix.*");
+
+
+ String yamlNoVal = Joiner.on("\n").join(
+ "services:",
+ "- type: entity-with-keys");
+
+ String yamlWrongVal = Joiner.on("\n").join(
+ "services:",
+ "- type: entity-with-keys",
+ " brooklyn.config:",
+ " testRequired: wrongval");
+
+ String yamlWithVal = Joiner.on("\n").join(
+ "services:",
+ "- type: entity-with-keys",
+ " brooklyn.config:",
+ " testRequired: myprefix-myVal");
+
+ try {
+ createStartWaitAndLogApplication(yamlNoVal);
+ Asserts.shouldHaveFailedPreviously();
+ } catch (ConstraintViolationException e) {
+ Asserts.expectedFailureContains(e, "Error configuring", "PredicateRegexPojo(myprefix.*)"); // success
+ }
+
+ try {
+ createStartWaitAndLogApplication(yamlWrongVal);
+ Asserts.shouldHaveFailedPreviously();
+ } catch (ConstraintViolationException e) {
+ Asserts.expectedFailureContains(e, "Invalid value for", "wrongval"); // success
+ }
+
+ Entity app = createStartWaitAndLogApplication(yamlWithVal);
+ TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+ assertKeyEquals(entity, "testRequired", null, String.class, null, "myprefix-myVal");
+
+ // Rebind, and then check again that the config key is listed
+ Entity newApp = rebind();
+ TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
+ assertKeyEquals(newEntity, "testRequired", null, String.class, null, "myprefix-myVal");
+ }
+
+ public static class PredicateRegexPojo implements Predicate<Object> {
+ private String regex;
+
+ public void setRegex(final String regex) {
+ this.regex = checkNotNull(regex, "regex");
+ }
+
+ @Override
+ public boolean apply(Object input) {
+ return (input instanceof String) && ((String)input).matches(regex);
+ }
+
+ @Override
+ public String toString() {
+ return "PredicateRegexPojo("+regex+")";
+ }
+ }
+
protected <T> void assertKeyEquals(Entity entity, String keyName, String expectedDescription, Class<T> expectedType, T expectedDefaultVal, T expectedEntityVal) {
ConfigKey<?> key = entity.getEntityType().getConfigKey(keyName);
assertNotNull(key, "No key '"+keyName+"'; keys="+entity.getEntityType().getConfigKeys());
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/4bda12b7/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 cc9d66a..d8c0522 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,6 +18,8 @@
*/
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.Collections;
@@ -56,6 +58,7 @@ 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>{
@@ -203,7 +206,16 @@ public class BasicSpecParameter<T> implements SpecParameter<T>{
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);
+ }});
+
public 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());
@@ -279,25 +291,21 @@ public class BasicSpecParameter<T> implements SpecParameter<T>{
}
@SuppressWarnings({ "unchecked", "rawtypes" })
- private static Predicate parseConstraints(Object obj, BrooklynClassLoadingContext loader) {
- List constraintsRaw;
+ private static Predicate<?> parseConstraints(Object obj, BrooklynClassLoadingContext loader) {
+ List<?> constraintsRaw;
if (obj == null) {
constraintsRaw = ImmutableList.of();
} else if (obj instanceof String) {
constraintsRaw = ImmutableList.of(obj);
} else if (obj instanceof List) {
- constraintsRaw = (List) obj;
+ constraintsRaw = (List<?>) obj;
} else {
- throw new IllegalArgumentException ("The constraint '" + obj + "' for a catalog input is invalid format - string or list supported");
+ throw new IllegalArgumentException ("The constraint '" + obj + "' for a catalog input is invalid format - "
+ + "string or list supported");
}
- List<Predicate> constraints = new ArrayList(constraintsRaw.size());
+ List<Predicate<?>> constraints = new ArrayList<>(constraintsRaw.size());
for (Object untypedConstraint : constraintsRaw) {
- String constraint = (String)untypedConstraint;
- if (BUILT_IN_CONSTRAINTS.containsKey(constraint)) {
- constraints.add(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() + ")");
- }
+ constraints.add(parseConstraint(untypedConstraint, loader));
}
if (!constraints.isEmpty()) {
if (constraints.size() == 1) {
@@ -310,6 +318,43 @@ 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");
+ }
+ }
+
private static ConfigInheritance parseInheritance(Object obj, BrooklynClassLoadingContext loader) {
if (obj == null || obj instanceof String) {
// TODO
[2/2] brooklyn-server git commit: This closes #558
Posted by dr...@apache.org.
This closes #558
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/38396711
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/38396711
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/38396711
Branch: refs/heads/master
Commit: 38396711d3b26d37142bdd660253edf269c3216f
Parents: 0f649fe 4bda12b
Author: Duncan Godwin <dr...@googlemail.com>
Authored: Wed Feb 15 10:55:59 2017 +0000
Committer: Duncan Godwin <dr...@googlemail.com>
Committed: Wed Feb 15 10:55:59 2017 +0000
----------------------------------------------------------------------
.../camp/brooklyn/ConfigParametersYamlTest.java | 178 +++++++++++++++++++
.../brooklyn/core/objs/BasicSpecParameter.java | 69 +++++--
2 files changed, 235 insertions(+), 12 deletions(-)
----------------------------------------------------------------------