This is an automated email from the ASF dual-hosted git repository.
heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
The following commit(s) were added to refs/heads/master by this push:
new a1782df fix behaviour when a task / deferred is set _at_ the level of
a structured config key
new 5ddf395 Merge branch 'master' of
https://gitbox.apache.org/repos/asf/brooklyn-server
a1782df is described below
commit a1782df72f2aad99e7548742f828f021f10f56a9
Author: Alex Heneveld <[email protected]>
AuthorDate: Sun May 23 16:30:45 2021 +0100
fix behaviour when a task / deferred is set _at_ the level of a structured
config key
---
.../apache/brooklyn/core/config/MapConfigKey.java | 30 +++++++++++++++++-----
.../internal/AbstractCollectionConfigKey.java | 17 +++++++-----
.../brooklyn/util/core/task/ValueResolver.java | 7 +++++
.../MapListAndOtherStructuredConfigKeyTest.java | 17 ++++++++++++
4 files changed, 59 insertions(+), 12 deletions(-)
diff --git
a/core/src/main/java/org/apache/brooklyn/core/config/MapConfigKey.java
b/core/src/main/java/org/apache/brooklyn/core/config/MapConfigKey.java
index 3a11cf8..e3b70d3 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/MapConfigKey.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/MapConfigKey.java
@@ -26,11 +26,13 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import org.apache.brooklyn.api.mgmt.ExecutionContext;
+import org.apache.brooklyn.api.mgmt.TaskAdaptable;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.internal.AbstractStructuredConfigKey;
import org.apache.brooklyn.util.collections.Jsonya;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.core.task.ValueResolver;
import org.apache.brooklyn.util.guava.Maybe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -182,13 +184,29 @@ public class MapConfigKey<V> extends
AbstractStructuredConfigKey<Map<String,V>,M
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Object applyValueToMap(Object value, Map target) {
- if (value == null)
+ if (value == null) {
return null;
- if (value instanceof StructuredModification)
- return ((StructuredModification)value).applyToKeyInMap(this,
target);
- if (value instanceof Map.Entry)
- return applyEntryValueToMap((Map.Entry)value, target);
+ }
+ if (value instanceof StructuredModification) {
+ return ((StructuredModification) value).applyToKeyInMap(this,
target);
+ }
+ if (value instanceof Map.Entry) {
+ return applyEntryValueToMap((Map.Entry) value, target);
+ }
if (!(value instanceof Map)) {
+ if (ValueResolver.isDeferredOrTaskInternal(value)) {
+ boolean isSet = isSet(target);
+ if (isSet) {
+ String warning = "Discouraged undecorated setting of a
task to in-use StructuredConfigKey " + this + ": use MapModification.{set,add}.
" +
+ "Defaulting to replacing root. Look at debug
logging for call stack.";
+ log.warn(warning);
+ if (log.isDebugEnabled())
+ log.debug("Trace for: " + warning, new
Throwable("Trace for: " + warning));
+ }
+ // just put here as the set - prior to 2021-05 we put things
under an anonymous subkey
+ return target.put(this, value);
+ }
+
Maybe<Map> coercedValue = TypeCoercions.tryCoerce(value,
Map.class);
if (coercedValue.isPresent()) {
log.trace("Coerced value for {} from type {} to map", this,
value.getClass().getName());
@@ -197,7 +215,7 @@ public class MapConfigKey<V> extends
AbstractStructuredConfigKey<Map<String,V>,M
throw new IllegalArgumentException("Cannot set non-map entries
on "+this+", given type "+value.getClass().getName()+", value "+value);
}
}
-
+
Map result = new MutableMap();
for (Object entry: ((Map)value).entrySet()) {
Map.Entry entryT = (Map.Entry)entry;
diff --git
a/core/src/main/java/org/apache/brooklyn/core/config/internal/AbstractCollectionConfigKey.java
b/core/src/main/java/org/apache/brooklyn/core/config/internal/AbstractCollectionConfigKey.java
index acea209..c898d0d 100644
---
a/core/src/main/java/org/apache/brooklyn/core/config/internal/AbstractCollectionConfigKey.java
+++
b/core/src/main/java/org/apache/brooklyn/core/config/internal/AbstractCollectionConfigKey.java
@@ -28,6 +28,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.SubElementConfigKey;
import org.apache.brooklyn.util.collections.MutableSet;
+import org.apache.brooklyn.util.core.task.ValueResolver;
import org.apache.brooklyn.util.text.Identifiers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -85,6 +86,7 @@ public abstract class AbstractCollectionConfigKey<T, RawT
extends Collection<Obj
protected Object applyValueToMap(Object value, Map target, boolean
isInCollection) {
if (value instanceof StructuredModification) {
return ((StructuredModification)value).applyToKeyInMap(this,
target);
+
} else if ((value instanceof Iterable) && (!isInCollection)) {
// collections set _here_ (not in subkeys) get added
boolean isSet = isSet(target);
@@ -104,22 +106,25 @@ public abstract class AbstractCollectionConfigKey<T, RawT
extends Collection<Obj
target.put(this, MutableSet.of());
}
return null;
- } else if (value instanceof TaskAdaptable) {
+ }
+
+ if (ValueResolver.isDeferredOrTaskInternal(value)) {
boolean isSet = isSet(target);
if (isSet) {
- String warning = "Discouraged undecorated setting of a task to
in-use StructuredConfigKey "+this+": use SetModification.{set,add}. " +
- "Defaulting to 'add'. Look at debug logging for call
stack.";
+ String warning = "Discouraged undecorated setting of a
task/deferred to in-use StructuredConfigKey "+this+": use
SetModification.{set,add}. " +
+ "Defaulting to replacing root. Look at debug logging for
call stack.";
log.warn(warning);
if (log.isDebugEnabled())
log.debug("Trace for: "+warning, new Throwable("Trace for:
"+warning));
}
+ }
+ if (isInCollection) {
// just add to set, using anonymous key
target.put(subKey(), value);
return null;
} else {
- // just add to set, using anonymous key
- target.put(subKey(), value);
- return null;
+ // just put here as the set - prior to 2021-05 we put things under
an anonymous subkey
+ return target.put(this, value);
}
}
diff --git
a/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java
b/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java
index 842e812..9b5ac10 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java
@@ -395,6 +395,13 @@ public class ValueResolver<T> implements
DeferredSupplier<T>, Iterable<Maybe<Obj
return immediately || BrooklynTaskTags.hasTag(Tasks.current(),
BrooklynTaskTags.IMMEDIATE_TASK_TAG);
}
+ public static boolean isDeferredOrTaskInternal(Object o) {
+ if (o instanceof TaskAdaptable || o instanceof DeferredSupplier || o
instanceof Future) {
+ return true;
+ }
+ return false;
+ }
+
@SuppressWarnings({ "unchecked", "rawtypes" })
protected Maybe<T> getMaybeInternal() {
if (started.getAndSet(true))
diff --git
a/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.java
b/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.java
index 9b609af..99cd75c 100644
---
a/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.java
+++
b/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.java
@@ -19,6 +19,7 @@
package org.apache.brooklyn.core.config;
import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.guava.Maybe;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
@@ -136,6 +137,14 @@ public class MapListAndOtherStructuredConfigKeyTest
extends BrooklynAppUnitTestS
}
@Test
+ public void testMapConfigKeyCanStoreAndRetrieveFutureAtRoot() throws
Exception {
+ entity.config().set(TestEntity.CONF_MAP_THING,
DependentConfiguration.whenDone(Callables.returning(MutableMap.of("akey",
"aval"))));
+ app.start(locs);
+
+ assertEquals(entity.getConfig(TestEntity.CONF_MAP_THING),
ImmutableMap.of("akey","aval"));
+ }
+
+ @Test
public void
testUnstructuredConfigKeyCanStoreAndRetrieveFutureValsPutAsMap() throws
Exception {
final AtomicReference<String> bval = new
AtomicReference<String>("bval-too-early");
final AtomicInteger bref = new AtomicInteger(0);
@@ -237,6 +246,14 @@ public class MapListAndOtherStructuredConfigKeyTest
extends BrooklynAppUnitTestS
}
@Test
+ public void testSetConfigKeyCanStoreAndRetrieveFutureAtRoot() throws
Exception {
+ entity.config().set(TestEntity.CONF_SET_THING,
DependentConfiguration.whenDone(Callables.returning(MutableSet.of("aval",
"bval"))));
+ app.start(locs);
+
+ assertEquals(entity.getConfig(TestEntity.CONF_SET_THING),
ImmutableSet.of("aval","bval"));
+ }
+
+ @Test
public void testSetConfigKeyAddDirect() throws Exception {
entity.config().set(TestEntity.CONF_SET_THING.subKey(), "aval");
entity.config().set((ConfigKey)TestEntity.CONF_SET_THING, "bval");