You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sj...@apache.org on 2015/10/14 15:55:52 UTC
[06/17] incubator-brooklyn git commit: Adds
ConfigurationSupportInternal.getNonBlocking
Adds ConfigurationSupportInternal.getNonBlocking
ConfigConstraints uses the method to give a grace period to tasks when
validating values.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/aa5c00f6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/aa5c00f6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/aa5c00f6
Branch: refs/heads/master
Commit: aa5c00f6c6b148fb192786f127d0bac19dc0e3d1
Parents: 2f9b9e1
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Thu Oct 8 17:49:47 2015 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Thu Oct 8 17:54:43 2015 +0100
----------------------------------------------------------------------
.../brooklyn/core/config/ConfigConstraints.java | 20 ++++---
.../brooklyn/core/entity/AbstractEntity.java | 4 ++
.../core/location/AbstractLocation.java | 6 +++
.../AbstractConfigurationSupportInternal.java | 37 +++++++++++++
.../core/objs/AbstractEntityAdjunct.java | 5 ++
.../core/objs/BrooklynObjectInternal.java | 28 +++++++---
.../core/config/ConfigKeyConstraintTest.java | 55 ++++++++++++++++----
7 files changed, 132 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/aa5c00f6/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 6c6445f..b1afe75 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
@@ -29,6 +29,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.objs.AbstractEntityAdjunct;
import org.apache.brooklyn.core.objs.BrooklynObjectPredicate;
import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
+import org.apache.brooklyn.util.guava.Maybe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,6 +37,11 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
+/**
+ * Checks configuration constraints on entities and their adjuncts.
+ *
+ * @since 0.9.0
+ */
public abstract class ConfigConstraints<T extends BrooklynObject> {
public static final Logger LOG = LoggerFactory.getLogger(ConfigConstraints.class);
@@ -107,13 +113,13 @@ public abstract class ConfigConstraints<T extends BrooklynObject> {
Iterable<ConfigKey<?>> configKeys = getBrooklynObjectTypeConfigKeys();
LOG.trace("Checking config keys on {}: {}", getBrooklynObject(), configKeys);
for (ConfigKey<?> configKey : configKeys) {
- // getRaw returns null if explicitly set and absent if config key was unset.
- Object value = configInternal.getRaw(configKey).or(configKey.getDefaultValue());
-
- if (value == null || value.getClass().isAssignableFrom(configKey.getType())) {
- // Cast should be safe because the author of the constraint on the config key had to
- // keep its type to Predicte<? super T>, where T is ConfigKey<T>.
+ // getNonBlocking method coerces the value to the config key's type.
+ Maybe<?> maybeValue = configInternal.getNonBlocking(configKey);
+ if (maybeValue.isPresent()) {
+ Object value = maybeValue.get();
try {
+ // Cast is safe because the author of the constraint on the config key had to
+ // keep its type to Predicte<? super T>, where T is ConfigKey<T>.
Predicate<Object> po = (Predicate<Object>) configKey.getConstraint();
boolean isValid;
if (po instanceof BrooklynObjectPredicate) {
@@ -125,7 +131,7 @@ public abstract class ConfigConstraints<T extends BrooklynObject> {
violating.add(configKey);
}
} catch (Exception e) {
- LOG.debug("Error checking constraint on {} {} ", configKey.getName(), e);
+ LOG.debug("Error checking constraint on " + configKey.getName(), e);
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/aa5c00f6/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
index 1291587..a2e12f4 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
@@ -1214,7 +1214,11 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
getManagementSupport().getEntityChangeListener().onConfigChanged(key);
return result;
+ }
+ @Override
+ protected ExecutionContext getContext() {
+ return AbstractEntity.this.getExecutionContext();
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/aa5c00f6/core/src/main/java/org/apache/brooklyn/core/location/AbstractLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/AbstractLocation.java b/core/src/main/java/org/apache/brooklyn/core/location/AbstractLocation.java
index 1f6788c..0fd3f7b 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/AbstractLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/AbstractLocation.java
@@ -33,6 +33,7 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.Group;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.mgmt.ExecutionContext;
import org.apache.brooklyn.api.mgmt.SubscriptionContext;
import org.apache.brooklyn.api.mgmt.SubscriptionHandle;
import org.apache.brooklyn.api.mgmt.Task;
@@ -473,6 +474,11 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
private ConfigInheritance getDefaultInheritance() {
return ConfigInheritance.ALWAYS;
}
+
+ @Override
+ protected ExecutionContext getContext() {
+ return AbstractLocation.this.getManagementContext().getServerExecutionContext();
+ }
}
public class BasicSubscriptionSupport implements SubscriptionSupportInternal {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/aa5c00f6/core/src/main/java/org/apache/brooklyn/core/objs/AbstractConfigurationSupportInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/AbstractConfigurationSupportInternal.java b/core/src/main/java/org/apache/brooklyn/core/objs/AbstractConfigurationSupportInternal.java
index 4caa7e6..6cb8bb4 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/AbstractConfigurationSupportInternal.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/AbstractConfigurationSupportInternal.java
@@ -19,9 +19,17 @@
package org.apache.brooklyn.core.objs;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.mgmt.ExecutionContext;
import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.time.Duration;
public abstract class AbstractConfigurationSupportInternal implements BrooklynObjectInternal.ConfigurationSupportInternal {
@@ -41,6 +49,30 @@ public abstract class AbstractConfigurationSupportInternal implements BrooklynOb
}
@Override
+ public <T> Maybe<T> getNonBlocking(HasConfigKey<T> key) {
+ return getNonBlocking(key.getConfigKey());
+ }
+
+ @Override
+ public <T> Maybe<T> getNonBlocking(ConfigKey<T> key) {
+ // getRaw returns Maybe(val) if the key was explicitly set (where val can be null)
+ // or Absent if the config key was unset.
+ Object unresolved = getRaw(key).or(key.getDefaultValue());
+ final Object marker = new Object();
+ // Give tasks a short grace period to resolve.
+ Object resolved = Tasks.resolving(unresolved)
+ .as(Object.class)
+ .defaultValue(marker)
+ .timeout(Duration.of(5, TimeUnit.MILLISECONDS))
+ .context(getContext())
+ .swallowExceptions()
+ .get();
+ return (resolved != marker)
+ ? TypeCoercions.tryCoerce(resolved, key.getTypeToken())
+ : Maybe.<T>absent();
+ }
+
+ @Override
public <T> T set(HasConfigKey<T> key, Task<T> val) {
return set(key.getConfigKey(), val);
}
@@ -50,4 +82,9 @@ public abstract class AbstractConfigurationSupportInternal implements BrooklynOb
return set(key.getConfigKey(), val);
}
+ /**
+ * @return An execution context for use by {@link #getNonBlocking(ConfigKey)}
+ */
+ @Nullable
+ protected abstract ExecutionContext getContext();
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/aa5c00f6/core/src/main/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunct.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunct.java b/core/src/main/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunct.java
index 25c58ad..a7b00f4 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunct.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunct.java
@@ -357,6 +357,11 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
public void refreshInheritedConfigOfChildren() {
// no-op for location
}
+
+ @Override
+ protected ExecutionContext getContext() {
+ return AbstractEntityAdjunct.this.execution;
+ }
}
public <T> T getConfig(ConfigKey<T> key) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/aa5c00f6/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynObjectInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynObjectInternal.java b/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynObjectInternal.java
index 257da5a..6888c52 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynObjectInternal.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynObjectInternal.java
@@ -46,11 +46,11 @@ public interface BrooklynObjectInternal extends BrooklynObject, Rebindable {
@Beta
public interface ConfigurationSupportInternal extends Configurable.ConfigurationSupport {
-
+
/**
- * Returns a read-only view of all the config key/value pairs on this entity, backed by a string-based map,
+ * Returns a read-only view of all the config key/value pairs on this entity, backed by a string-based map,
* including config names that did not match anything on this entity.
- *
+ *
* TODO This method gives no information about which config is inherited versus local;
* this means {@link ConfigKey#getInheritance()} cannot be respected. This is an unsolvable problem
* for "config names that did not match anything on this entity". Therefore consider using
@@ -58,14 +58,14 @@ public interface BrooklynObjectInternal extends BrooklynObject, Rebindable {
*/
@Beta
ConfigBag getBag();
-
+
/**
- * Returns a read-only view of the local (i.e. not inherited) config key/value pairs on this entity,
+ * Returns a read-only view of the local (i.e. not inherited) config key/value pairs on this entity,
* backed by a string-based map, including config names that did not match anything on this entity.
*/
@Beta
ConfigBag getLocalBag();
-
+
/**
* Returns the uncoerced value for this config key, if available, not taking any default.
* If there is no local value and there is an explicit inherited value, will return the inherited.
@@ -92,6 +92,20 @@ public interface BrooklynObjectInternal extends BrooklynObject, Rebindable {
@Beta
Maybe<Object> getLocalRaw(HasConfigKey<?> key);
+ /**
+ * Attempts to coerce the value for this config key, if available,
+ * taking a default and {@link Maybe#absent absent} if the uncoerced
+ * cannot be resolved within a short timeframe.
+ */
+ @Beta
+ <T> Maybe<T> getNonBlocking(ConfigKey<T> key);
+
+ /**
+ * @see {@link #getNonBlocking(ConfigKey)}
+ */
+ @Beta
+ <T> Maybe<T> getNonBlocking(HasConfigKey<T> key);
+
@Beta
void addToLocalBag(Map<String, ?> vals);
@@ -100,7 +114,7 @@ public interface BrooklynObjectInternal extends BrooklynObject, Rebindable {
@Beta
void refreshInheritedConfig();
-
+
@Beta
void refreshInheritedConfigOfChildren();
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/aa5c00f6/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 05e0814..8a9e1c6 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
@@ -23,8 +23,11 @@ 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.EntitySpec;
import org.apache.brooklyn.api.entity.ImplementedBy;
+import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.api.objs.BrooklynObject;
import org.apache.brooklyn.api.policy.Policy;
import org.apache.brooklyn.api.policy.PolicySpec;
@@ -38,8 +41,11 @@ import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
import org.apache.brooklyn.core.test.policy.TestPolicy;
+import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.net.Networking;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
@@ -164,7 +170,7 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
fail("Expected exception when managing entity setting invalid default value");
} catch (Exception e) {
Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t);
+ assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
}
}
@@ -176,7 +182,7 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
fail("Expected exception when config key set to null");
} catch (Exception e) {
Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t);
+ assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
}
}
@@ -188,7 +194,7 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
fail("Expected exception when managing entity with invalid config");
} catch (Exception e) {
Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t);
+ assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
}
}
@@ -196,14 +202,14 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
public void testExceptionWhenAppGrandchildHasInvalidConfig() {
app.start(ImmutableList.of(app.newSimulatedLocation()));
TestEntity testEntity = app.addChild(EntitySpec.create(TestEntity.class));
+ try {
testEntity.addChild(EntitySpec.create(EntityRequiringConfigKeyInRange.class)
.configure(EntityRequiringConfigKeyInRange.RANGE, -1));
- try {
Entities.manage(testEntity);
fail("Expected exception when managing child with invalid config");
} catch (Exception e) {
Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t);
+ assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
}
}
@@ -217,7 +223,7 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
fail("Expected exception when validating policy with missing config");
} catch (Exception e) {
Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t);
+ assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
}
}
@@ -229,7 +235,7 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
fail("Expected exception when creating policy with missing config");
} catch (Exception e) {
Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t);
+ assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
}
}
@@ -241,7 +247,7 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
fail("Expected exception when creating enricher with invalid config");
} catch (Exception e) {
Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t, "Exception was: " + Exceptions.collapseText(e));
+ assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
}
}
@@ -278,8 +284,39 @@ public class ConfigKeyConstraintTest extends BrooklynAppUnitTestSupport {
fail("Expected exception when managing entity with incorrect config");
} catch (Exception e) {
Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
- assertNotNull(t);
+ assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
}
}
+ @Test
+ public void testQuickFutureResolved() {
+ // Result of task is -1, outside of the range specified by the config key.
+ try {
+ app.createAndManageChild(EntitySpec.create(EntityRequiringConfigKeyInRange.class)
+ .configure(EntityRequiringConfigKeyInRange.RANGE, sleepingTask(Duration.ZERO, -1)));
+ fail("Expected exception when managing entity with incorrect config");
+ } catch (Exception e) {
+ Throwable t = Exceptions.getFirstThrowableOfType(e, ConstraintViolationException.class);
+ assertNotNull(t, "Original exception was: " + Exceptions.collapseText(e));
+ }
+ }
+
+ @Test
+ public void testSlowFutureNotResolved() {
+ // i.e. no exception because task is too slow to resolve.
+ app.createAndManageChild(EntitySpec.create(EntityRequiringConfigKeyInRange.class)
+ .configure(EntityRequiringConfigKeyInRange.RANGE, sleepingTask(Duration.PRACTICALLY_FOREVER, -1)));
+ }
+
+ private static <T> Task<T> sleepingTask(final Duration delay, final T result) {
+ return Tasks.<T>builder()
+ .body(new Callable<T>() {
+ @Override public T call() throws Exception {
+ Time.sleep(delay);
+ return result;
+ }
+ })
+ .build();
+ }
+
}