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");

Reply via email to