share code in AbstractConfigurationSupport, and fix location config issues from 
previous

support clearing, prevent writes to config bag, and allow coercion from class 
names


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/8405d877
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/8405d877
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/8405d877

Branch: refs/heads/master
Commit: 8405d8774a0380a99b9dd1fbd2daf7fc15265cb8
Parents: ddc17d1
Author: Alex Heneveld <alex.henev...@cloudsoftcorp.com>
Authored: Tue Sep 20 13:07:22 2016 +0100
Committer: Alex Heneveld <alex.henev...@cloudsoftcorp.com>
Committed: Wed Sep 21 16:06:06 2016 +0100

----------------------------------------------------------------------
 .../config/internal/AbstractConfigMapImpl.java  | 16 ++--
 .../brooklyn/core/entity/AbstractEntity.java    | 89 +++-----------------
 .../core/entity/internal/EntityConfigMap.java   |  2 +-
 .../core/location/AbstractLocation.java         | 72 +++-------------
 .../location/internal/LocationConfigMap.java    | 11 ++-
 .../mgmt/internal/LocalLocationManager.java     |  6 +-
 .../mgmt/rebind/BasicLocationRebindSupport.java |  8 +-
 .../AbstractConfigurationSupportInternal.java   | 82 ++++++++++++++++++
 .../core/objs/AbstractEntityAdjunct.java        | 83 +++++-------------
 .../brooklyn/core/objs/AdjunctConfigMap.java    |  2 +-
 .../core/objs/BrooklynObjectInternal.java       |  3 +
 .../jclouds/JcloudsByonLocationResolver.java    |  3 +-
 .../location/jclouds/JcloudsLocation.java       | 26 +++---
 .../jclouds/JcloudsLocationResolverTest.java    | 34 ++++++--
 14 files changed, 193 insertions(+), 244 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/core/src/main/java/org/apache/brooklyn/core/config/internal/AbstractConfigMapImpl.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/config/internal/AbstractConfigMapImpl.java
 
b/core/src/main/java/org/apache/brooklyn/core/config/internal/AbstractConfigMapImpl.java
index 60760f6..6593aed 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/config/internal/AbstractConfigMapImpl.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/config/internal/AbstractConfigMapImpl.java
@@ -74,7 +74,7 @@ public abstract class AbstractConfigMapImpl implements 
ConfigMap {
         this.ownConfig = storage;
     }
 
-    protected BrooklynObjectInternal getBrooklynObject() {
+    public BrooklynObjectInternal getBrooklynObject() {
         return bo;
     }
     
@@ -189,8 +189,8 @@ public abstract class AbstractConfigMapImpl implements 
ConfigMap {
     }
     
     public void removeFromLocalBag(String key) {
-        // FIXME probably never worked, config key vs string ?
-        ownConfig.remove(key);
+        // previously removed the string (?)
+        ownConfig.remove(ConfigKeys.newConfigKey(Object.class, key));
     }
 
     public void removeFromLocalBag(ConfigKey<?> key) {
@@ -228,21 +228,20 @@ public abstract class AbstractConfigMapImpl implements 
ConfigMap {
         return result.seal();
     }
     protected Object coerceConfigVal(ConfigKey<?> key, Object v) {
-        Object val;
         if ((v instanceof Future) || (v instanceof DeferredSupplier)) {
             // no coercion for these (coerce on exit)
-            val = v;
+            return v;
         } else if (key instanceof StructuredConfigKey) {
             // no coercion for these structures (they decide what to do)
-            val = v;
+            return v;
         } else if ((v instanceof Map || v instanceof Iterable) && 
key.getType().isInstance(v)) {
             // don't do coercion on put for these, if the key type is 
compatible, 
             // because that will force resolution deeply
-            val = v;
+            return v;
         } else {
             try {
                 // try to coerce on input, to detect errors sooner
-                val = TypeCoercions.coerce(v, key.getTypeToken());
+                return TypeCoercions.coerce(v, key.getTypeToken());
             } catch (Exception e) {
                 throw new IllegalArgumentException("Cannot coerce or set "+v+" 
to "+key, e);
                 // if can't coerce, we could just log as below and *throw* the 
error when we retrieve the config
@@ -253,7 +252,6 @@ public abstract class AbstractConfigMapImpl implements 
ConfigMap {
 //                val = v;
             }
         }
-        return val;
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/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 663c0ac..fe65cff 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
@@ -56,7 +56,6 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
 import org.apache.brooklyn.api.sensor.SensorEventListener;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
-import org.apache.brooklyn.config.ConfigMap;
 import org.apache.brooklyn.core.BrooklynFeatureEnablement;
 import org.apache.brooklyn.core.BrooklynLogging;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
@@ -100,7 +99,6 @@ import org.apache.brooklyn.util.collections.SetFromLiveMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.flags.FlagUtils;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.core.task.DeferredSupplier;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.javalang.Equals;
 import org.apache.brooklyn.util.text.Strings;
@@ -1209,65 +1207,13 @@ public abstract class AbstractEntity extends 
AbstractBrooklynObject implements E
     // TODO revert to private when config() is reverted to return 
ConfigurationSupportInternal
     public class BasicConfigurationSupport extends 
AbstractConfigurationSupportInternal {
 
-        protected AbstractConfigMapImpl getConfigsInternal() {
-            return configsInternal;
-        }
-        
-        @Override
-        public <T> T get(ConfigKey<T> key) {
-            return getConfigsInternal().getConfig(key);
-        }
-
         @Override
-        public <T> T set(ConfigKey<T> key, T val) {
+        protected <T> void assertValid(ConfigKey<T> key, T val) {
             ConfigConstraints.assertValid(AbstractEntity.this, key, val);
-            return setConfigInternal(key, val);
-        }
-
-        @Override
-        public <T> T set(ConfigKey<T> key, Task<T> val) {
-            return setConfigInternal(key, val);
-        }
-
-        @Override
-        public ConfigBag getLocalBag() {
-            return getConfigsInternal().getLocalConfigBag();
-        }
-
-        @Override
-        public Maybe<Object> getRaw(ConfigKey<?> key) {
-            return getConfigsInternal().getConfigRaw(key, true);
-        }
-
-        @Override
-        public Maybe<Object> getLocalRaw(ConfigKey<?> key) {
-            return getConfigsInternal().getConfigRaw(key, false);
-        }
-
-        @Override
-        public void addToLocalBag(Map<?, ?> vals) {
-            getConfigsInternal().addToLocalBag(vals);
-        }
-
-        @Override
-        public void removeFromLocalBag(String key) {
-            getConfigsInternal().removeFromLocalBag(key);
         }
         
-        @Override
-        public void removeFromLocalBag(ConfigKey<?> key) {
-            getConfigsInternal().removeFromLocalBag(key);
-        }
-        
-        @Override
-        public ConfigMap getInternalConfigMap() {
-            return getConfigsInternal();
-        }
-
-        @Override
-        // TODO deprecate because key inheritance not respected
-        public ConfigBag getBag() {
-            return ((EntityConfigMap)getConfigsInternal()).getAllConfigBag();
+        protected AbstractConfigMapImpl getConfigsInternal() {
+            return configsInternal;
         }
 
         @Override
@@ -1284,22 +1230,23 @@ public abstract class AbstractEntity extends 
AbstractBrooklynObject implements E
             }
         }
         
-        @SuppressWarnings("unchecked")
-        private <T> T setConfigInternal(ConfigKey<T> key, Object val) {
+        @Override
+        protected <T> void onConfigChanging(ConfigKey<T> key, Object val) {
             if (!inConstruction && getManagementSupport().isDeployed()) {
                 // previously we threw, then warned, but it is still quite 
common;
                 // so long as callers don't expect miracles, it should be fine.
                 // i (Alex) think the way to be stricter about this (if that 
becomes needed) 
                 // would be to introduce a 'mutable' field on config keys
                 LOG.debug("configuration being made to {} after deployment: {} 
= {}; change may not be visible in other contexts", 
-                        new Object[] { getContainer(), key, val });
+                    new Object[] { getContainer(), key, val });
             }
-            T result = (T) getConfigsInternal().setConfig(key, val);
-            
+        }
+        
+        protected <T> void onConfigChanged(ConfigKey<T> key, Object val) {
             
getManagementSupport().getEntityChangeListener().onConfigChanged(key);
-            return result;
         }
 
+        @Override
         protected BrooklynObject getContainer() {
             return AbstractEntity.this;
         }
@@ -1351,14 +1298,6 @@ public abstract class AbstractEntity extends 
AbstractBrooklynObject implements E
         return config().set(key, val);
     }
 
-    /**
-     * @deprecated since 0.7.0; use {@code config().set(key, task)}, with 
{@link Task} instead of {@link DeferredSupplier}
-     */
-    @Deprecated
-    public <T> T setConfig(ConfigKey<T> key, DeferredSupplier val) {
-        return config.setConfigInternal(key, val);
-    }
-
     @Override
     @Deprecated
     public <T> T setConfig(HasConfigKey<T> key, T val) {
@@ -1371,14 +1310,6 @@ public abstract class AbstractEntity extends 
AbstractBrooklynObject implements E
         return (T) config().set(key, val);
     }
 
-    /**
-     * @deprecated since 0.7.0; use {@code config().set(key, task)}, with 
{@link Task} instead of {@link DeferredSupplier}
-     */
-    @Deprecated
-    public <T> T setConfig(HasConfigKey<T> key, DeferredSupplier val) {
-        return setConfig(key.getConfigKey(), val);
-    }
-
     @SuppressWarnings("unchecked")
     public <T> T setConfigEvenIfOwned(ConfigKey<T> key, T val) {
         return (T) configsInternal.setConfig(key, val);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/core/src/main/java/org/apache/brooklyn/core/entity/internal/EntityConfigMap.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/entity/internal/EntityConfigMap.java
 
b/core/src/main/java/org/apache/brooklyn/core/entity/internal/EntityConfigMap.java
index e2ff0be..c1314b3 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/entity/internal/EntityConfigMap.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/entity/internal/EntityConfigMap.java
@@ -62,7 +62,7 @@ public class EntityConfigMap extends AbstractConfigMapImpl {
      * @deprecated since 0.10.0 kept for serialization */ @Deprecated
     private EntityInternal entity;
     @Override
-    protected BrooklynObjectInternal getBrooklynObject() {
+    public BrooklynObjectInternal getBrooklynObject() {
         BrooklynObjectInternal result = super.getBrooklynObject();
         if (result!=null) return result;
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/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 f89ae27..12253b6 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
@@ -38,6 +38,7 @@ import org.apache.brooklyn.api.mgmt.SubscriptionHandle;
 import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.LocationMemento;
+import org.apache.brooklyn.api.objs.BrooklynObject;
 import org.apache.brooklyn.api.objs.Configurable;
 import org.apache.brooklyn.api.sensor.Sensor;
 import org.apache.brooklyn.api.sensor.SensorEventListener;
@@ -48,6 +49,7 @@ import org.apache.brooklyn.core.BrooklynFeatureEnablement;
 import org.apache.brooklyn.core.config.BasicConfigKey;
 import org.apache.brooklyn.core.config.ConfigConstraints;
 import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.internal.AbstractConfigMapImpl;
 import org.apache.brooklyn.core.internal.storage.BrooklynStorage;
 import org.apache.brooklyn.core.internal.storage.Reference;
 import org.apache.brooklyn.core.internal.storage.impl.BasicReference;
@@ -387,72 +389,21 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
 
         // Sept 2016 now uses AbstractConfigMapImpl like the other 
ConfigurationSupport implementations
         // (now gives us inheritance correctly -- for free!)
-        
-        protected LocationConfigMap getConfigMap() {
-            return configMap;
-        }
-        
-        @Override
-        public <T> T get(ConfigKey<T> key) {
-            return getConfigMap().getConfig(key);
-
-        }
 
         @Override
-        public <T> T set(ConfigKey<T> key, T val) {
+        protected <T> void assertValid(ConfigKey<T> key, T val) {
             ConfigConstraints.assertValid(AbstractLocation.this, key, val);
-            @SuppressWarnings("unchecked")
-            T result = (T) getConfigMap().setConfig(key, val);
-            onChanged();
-            return result;
-        }
-
-        @Override
-        public <T> T set(ConfigKey<T> key, Task<T> val) {
-            // TODO Support for locations
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public ConfigBag getBag() {
-            ConfigBag result = getLocalBag();
-            Location p = getParent();
-            if (p!=null) 
result.putIfAbsent(((LocationInternal)p).config().getBag());
-            return result;
-        }
-
-        @Override
-        public ConfigBag getLocalBag() {
-            ConfigBag result = ConfigBag.newInstance();
-            result.putAll(getConfigMap().getLocalConfig());
-            return result;
         }
 
         @Override
-        public Maybe<Object> getRaw(ConfigKey<?> key) {
-            return getConfigMap().getConfigRaw(key, true);
-        }
-
-        @Override
-        public Maybe<Object> getLocalRaw(ConfigKey<?> key) {
-            return getConfigMap().getConfigLocalRaw(key);
-        }
-
-        @Override
-        public void addToLocalBag(Map<?, ?> vals) {
-            getConfigMap().addToLocalBag(vals);
-        }
-
-        @Override
-        public void removeFromLocalBag(String key) {
-            getConfigMap().removeFromLocalBag(key);
+        protected <T> void onConfigChanging(ConfigKey<T> key, Object val) {
         }
         
         @Override
-        public void removeFromLocalBag(ConfigKey<?> key) {
-            getConfigMap().removeFromLocalBag(key);
+        protected <T> void onConfigChanged(ConfigKey<T> key, Object val) {
+            onChanged();
         }
-
+        
         @Override
         public void refreshInheritedConfig() {
             // no-op for location
@@ -467,10 +418,15 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
         protected ExecutionContext getContext() {
             return 
AbstractLocation.this.getManagementContext().getServerExecutionContext();
         }
+
+        @Override
+        protected AbstractConfigMapImpl getConfigsInternal() {
+            return configMap;
+        }
         
         @Override
-        public ConfigMap getInternalConfigMap() {
-            return getConfigMap();
+        protected BrooklynObject getContainer() {
+            return AbstractLocation.this;
         }
     }
     

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/core/src/main/java/org/apache/brooklyn/core/location/internal/LocationConfigMap.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/location/internal/LocationConfigMap.java
 
b/core/src/main/java/org/apache/brooklyn/core/location/internal/LocationConfigMap.java
index 0e79668..4a854f6 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/location/internal/LocationConfigMap.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/location/internal/LocationConfigMap.java
@@ -132,5 +132,14 @@ public class LocationConfigMap extends 
AbstractConfigMapImpl {
         throw new UnsupportedOperationException("Location does not support 
submap");
     }
 
-
+    @Override
+    protected Object coerceConfigVal(ConfigKey<?> key, Object v) {
+        if ((Class.class.isAssignableFrom(key.getType()) || 
Function.class.isAssignableFrom(key.getType())) && v instanceof String) {
+            // strings can be written where classes/functions are permitted; 
this is a common pattern when configuring locations
+            // (bit sloppy to allow this; tests catch it, eg ImageChooser in 
jclouds)
+            return v;
+        }
+        
+        return super.coerceConfigVal(key, v);
+    }
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalLocationManager.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalLocationManager.java
 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalLocationManager.java
index d73d2ce..709369d 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalLocationManager.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalLocationManager.java
@@ -406,9 +406,9 @@ public class LocalLocationManager implements 
LocationManagerInternal {
             // if not destroying, don't change the parent's children list
             ((AbstractLocation)loc).setParent(null, false);
         }
-        // clear config to help with GC; i know you're not supposed to, but 
this seems to help, else config bag is littered with refs to entities etc
-        // FIXME relies on config().getLocalBag() returning the underlying bag!
-        ((AbstractLocation)loc).config().getLocalBag().clear();
+        // clear config to help with GC; everyone says you're not supposed to, 
but this really seems to help, 
+        // else config bag is littered with refs to entities etc and some JVMs 
seem to keep them around much longer
+        ((AbstractLocation)loc).config().removeAllLocalConfig();
     }
     
     /**

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicLocationRebindSupport.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicLocationRebindSupport.java
 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicLocationRebindSupport.java
index 0f10672..9036e36 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicLocationRebindSupport.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicLocationRebindSupport.java
@@ -35,8 +35,6 @@ import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Sets;
-
 public class BasicLocationRebindSupport extends 
AbstractBrooklynObjectRebindSupport<LocationMemento> {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(BasicLocationRebindSupport.class);
@@ -70,11 +68,9 @@ public class BasicLocationRebindSupport extends 
AbstractBrooklynObjectRebindSupp
         // FIXME Treat config like we do for entities; this code will 
disappear when locations become entities.
         
         // Note that the flags have been set in the constructor
-        // FIXME Relies on location.config().getLocalBag() being mutable (to 
modify the location's own config)
+        // Sept 2016 - now ignores unused and config description
         
-        
location.config().getLocalBag().putAll(memento.getLocationConfig()).markAll(
-                Sets.difference(memento.getLocationConfig().keySet(), 
memento.getLocationConfigUnused())).
-                setDescription(memento.getLocationConfigDescription());
+        location.config().addToLocalBag(memento.getLocationConfig());
 
         for (Map.Entry<String, Object> entry : 
memento.getLocationConfig().entrySet()) {
             String flagName = entry.getKey();

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/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 9cb7a9e..2e18fc0 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,6 +19,7 @@
 
 package org.apache.brooklyn.core.objs;
 
+import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
@@ -27,12 +28,17 @@ import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.mgmt.ExecutionContext;
 import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.api.objs.BrooklynObject;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
+import org.apache.brooklyn.config.ConfigMap;
 import org.apache.brooklyn.core.config.MapConfigKey;
 import org.apache.brooklyn.core.config.StructuredConfigKey;
 import org.apache.brooklyn.core.config.SubElementConfigKey;
+import org.apache.brooklyn.core.config.internal.AbstractConfigMapImpl;
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.core.task.ValueResolver;
@@ -149,6 +155,82 @@ public abstract class AbstractConfigurationSupportInternal 
implements BrooklynOb
         return set(key.getConfigKey(), val);
     }
 
+    protected abstract AbstractConfigMapImpl getConfigsInternal();
+    protected abstract <T> void assertValid(ConfigKey<T> key, T val);
+    protected abstract BrooklynObject getContainer();
+    protected abstract <T> void onConfigChanging(ConfigKey<T> key, Object val);
+    protected abstract <T> void onConfigChanged(ConfigKey<T> key, Object val);
+
+    @Override
+    public <T> T get(ConfigKey<T> key) {
+        return getConfigsInternal().getConfig(key);
+    }
+    
+    @SuppressWarnings("unchecked")
+    protected <T> T setConfigInternal(ConfigKey<T> key, Object val) {
+        onConfigChanging(key, val);
+        T result = (T) getConfigsInternal().setConfig(key, val);
+        onConfigChanged(key, val);
+        return result;
+    }
+
+    @Override
+    public <T> T set(ConfigKey<T> key, T val) {
+        assertValid(key, val);
+        return setConfigInternal(key, val);
+    }
+
+    @Override
+    public <T> T set(ConfigKey<T> key, Task<T> val) {
+        return setConfigInternal(key, val);
+    }
+
+    @Override
+    public ConfigBag getLocalBag() {
+        return getConfigsInternal().getLocalConfigBag();
+    }
+
+    @Override
+    public Maybe<Object> getRaw(ConfigKey<?> key) {
+        return getConfigsInternal().getConfigRaw(key, true);
+    }
+
+    @Override
+    public Maybe<Object> getLocalRaw(ConfigKey<?> key) {
+        return getConfigsInternal().getConfigRaw(key, false);
+    }
+
+    @Override
+    public void addToLocalBag(Map<?, ?> vals) {
+        getConfigsInternal().addToLocalBag(vals);
+    }
+
+    @Override
+    public void removeFromLocalBag(String key) {
+        getConfigsInternal().removeFromLocalBag(key);
+    }
+    
+    @Override
+    public void removeFromLocalBag(ConfigKey<?> key) {
+        getConfigsInternal().removeFromLocalBag(key);
+    }
+    
+    @Override
+    public void removeAllLocalConfig() {
+        
getConfigsInternal().setLocalConfig(MutableMap.<ConfigKey<?>,Object>of());
+    }
+    
+    @Override
+    public ConfigMap getInternalConfigMap() {
+        return getConfigsInternal();
+    }
+
+    @Override
+    // TODO deprecate because key inheritance not respected
+    public ConfigBag getBag() {
+        return getConfigsInternal().getAllConfigBag();
+    }
+    
     /**
      * @return An execution context for use by {@link 
#getNonBlocking(ConfigKey)}
      */

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/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 dd05c4d..c231157 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
@@ -33,7 +33,6 @@ import org.apache.brooklyn.api.entity.EntityLocal;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.mgmt.ExecutionContext;
 import org.apache.brooklyn.api.mgmt.SubscriptionHandle;
-import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.api.objs.BrooklynObject;
 import org.apache.brooklyn.api.objs.Configurable;
 import org.apache.brooklyn.api.objs.EntityAdjunct;
@@ -44,6 +43,7 @@ import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.config.ConfigMap;
 import org.apache.brooklyn.core.config.ConfigConstraints;
 import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.internal.AbstractConfigMapImpl;
 import org.apache.brooklyn.core.enricher.AbstractEnricher;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.EntityInternal;
@@ -52,7 +52,6 @@ import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.flags.FlagUtils;
 import org.apache.brooklyn.util.core.flags.SetFromFlag;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.text.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -87,11 +86,8 @@ public abstract class AbstractEntityAdjunct extends 
AbstractBrooklynObject imple
     /**
      * The config values of this entity. Updating this map should be done
      * via {@link #config()}.
-     * 
-     * @deprecated since 0.7.0; use {@link #config()} instead; this field may 
be made private or deleted in a future release.
      */
-    @Deprecated
-    protected final AdjunctConfigMap configsInternal = new 
AdjunctConfigMap(this);
+    private final AdjunctConfigMap configsInternal = new 
AdjunctConfigMap(this);
 
     /**
      * @deprecated since 0.7.0; use {@link #getAdjunctType()} instead; this 
field may be made private or deleted in a future release.
@@ -286,78 +282,27 @@ public abstract class AbstractEntityAdjunct extends 
AbstractBrooklynObject imple
     
     private class BasicConfigurationSupport extends 
AbstractConfigurationSupportInternal {
 
-        @Override
-        public <T> T get(ConfigKey<T> key) {
-            return configsInternal.getConfig(key);
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public <T> T set(ConfigKey<T> key, T val) {
-            ConfigConstraints.assertValid(entity, key, val);
-            if (entity != null && isRunning()) {
-                doReconfigureConfig(key, val);
-            }
-            T result = (T) configsInternal.setConfig(key, val);
-            onChanged();
-            return result;
-        }
-
         @SuppressWarnings("unchecked")
         @Override
-        public <T> T set(ConfigKey<T> key, Task<T> val) {
+        protected <T> void onConfigChanging(ConfigKey<T> key, Object val) {
             if (entity != null && isRunning()) {
-                // TODO Support for AbstractEntityAdjunct
-                throw new UnsupportedOperationException();
+                doReconfigureConfig(key, (T)val);
             }
-            T result = (T) configsInternal.setConfig(key, val);
-            onChanged();
-            return result;
-        }
-
-        @Override
-        public ConfigBag getBag() {
-            return getLocalBag();
-        }
-
-        @Override
-        public ConfigBag getLocalBag() {
-            return ConfigBag.newInstance(configsInternal.getAllConfig());
-        }
-
-        @Override
-        public Maybe<Object> getRaw(ConfigKey<?> key) {
-            return configsInternal.getConfigRaw(key, true);
-        }
-
-        @Override
-        public Maybe<Object> getLocalRaw(ConfigKey<?> key) {
-            return configsInternal.getConfigRaw(key, false);
-        }
-
-        @Override
-        public void addToLocalBag(Map<?, ?> vals) {
-            configsInternal.addToLocalBag(vals);
         }
         
         @Override
-        public void removeFromLocalBag(String key) {
-            configsInternal.removeFromLocalBag(key);
+        protected <T> void onConfigChanged(ConfigKey<T> key, Object val) {
+            onChanged();
         }
 
         @Override
-        public void removeFromLocalBag(ConfigKey<?> key) {
-            configsInternal.removeFromLocalBag(key);
-        }
-        
-        @Override
         public void refreshInheritedConfig() {
-            // no-op for location
+            // no-op here
         }
         
         @Override
         public void refreshInheritedConfigOfChildren() {
-            // no-op for location
+            // no-op here
         }
 
         @Override
@@ -366,9 +311,19 @@ public abstract class AbstractEntityAdjunct extends 
AbstractBrooklynObject imple
         }
         
         @Override
-        public ConfigMap getInternalConfigMap() {
+        protected AbstractConfigMapImpl getConfigsInternal() {
             return configsInternal;
         }
+
+        @Override
+        protected <T> void assertValid(ConfigKey<T> key, T val) {
+            ConfigConstraints.assertValid(entity, key, val);
+        }
+
+        @Override
+        protected BrooklynObject getContainer() {
+            return AbstractEntityAdjunct.this;
+        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/core/src/main/java/org/apache/brooklyn/core/objs/AdjunctConfigMap.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/objs/AdjunctConfigMap.java 
b/core/src/main/java/org/apache/brooklyn/core/objs/AdjunctConfigMap.java
index 7ad9468..f3ecdea 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/AdjunctConfigMap.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/AdjunctConfigMap.java
@@ -49,7 +49,7 @@ public class AdjunctConfigMap extends AbstractConfigMapImpl {
      * @deprecated since 0.10.0 kept for serialization */ @Deprecated
     private AbstractEntityAdjunct adjunct;
     @Override
-    protected BrooklynObjectInternal getBrooklynObject() {
+    public BrooklynObjectInternal getBrooklynObject() {
         BrooklynObjectInternal result = super.getBrooklynObject();
         if (result!=null) return result;
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/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 600104b..566f957 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
@@ -142,6 +142,9 @@ public interface BrooklynObjectInternal extends 
BrooklynObject, Rebindable {
         
         @Beta
         ConfigMap getInternalConfigMap();
+
+        /** Clears all local config, e.g. on tear-down */
+        void removeAllLocalConfig();
     }
     
     @Beta

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
 
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
index 04c1126..f9a75be 100644
--- 
a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
+++ 
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
@@ -154,7 +154,8 @@ public class JcloudsByonLocationResolver extends 
AbstractLocationResolver implem
                 JcloudsLocation jcloudsLocation = (JcloudsLocation) 
managementContext.getLocationManager().createLocation(jcloudsLocationSpec.get());
                 for (Map<?,?> machineFlags : machinesFlags) {
                     try {
-                        JcloudsMachineLocation machine = 
jcloudsLocation.registerMachine(jcloudsLocation.config().getBag().putAll(machineFlags));
+                        jcloudsLocation.config().addToLocalBag(machineFlags);
+                        JcloudsMachineLocation machine = 
jcloudsLocation.registerMachine(jcloudsLocation.config().getBag());
                         result.add(machine);
                     } catch (NoMachinesAvailableException e) {
                         Map<?,?> sanitizedMachineFlags = 
Sanitizer.sanitize(machineFlags);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
 
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
index a1d1293..65ea8ec 100644
--- 
a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
+++ 
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
@@ -258,8 +258,6 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
                    (groovyTruth(getEndpoint()) ? ":"+getEndpoint() : ""));
         }
 
-        setCreationString(config().getLocalBag());
-
         if (getConfig(MACHINE_CREATION_SEMAPHORE) == null) {
             Integer maxConcurrent = 
getConfig(MAX_CONCURRENT_MACHINE_CREATIONS);
             if (maxConcurrent == null || maxConcurrent < 1) {
@@ -583,13 +581,14 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
         killMachine(m.getId());
     }
 
-    /** attaches a string describing where something is being created
-     * (provider, region/location and/or endpoint, callerContext) */
-    protected void setCreationString(ConfigBag config) {
-        config.setDescription(elvis(config.get(CLOUD_PROVIDER), "unknown")+
+    /** can generate a string describing where something is being created
+     * (provider, region/location and/or endpoint, callerContext);
+     * previously set on the config bag, but not any longer (Sept 2016) as 
config is treated like entities */
+    protected String getCreationString(ConfigBag config) {
+        return elvis(config.get(CLOUD_PROVIDER), "unknown")+
                 (config.containsKey(CLOUD_REGION_ID) ? 
":"+config.get(CLOUD_REGION_ID) : "")+
                 (config.containsKey(CLOUD_ENDPOINT) ? 
":"+config.get(CLOUD_ENDPOINT) : "")+
-                (config.containsKey(CALLER_CONTEXT) ? 
"@"+config.get(CALLER_CONTEXT) : ""));
+                (config.containsKey(CALLER_CONTEXT) ? 
"@"+config.get(CALLER_CONTEXT) : "");
     }
 
     // ----------------- obtaining a new machine ------------------------
@@ -651,7 +650,6 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
             throw new IllegalStateException("Access controller forbids 
provisioning in "+this+": "+access.getMsg());
         }
 
-        setCreationString(setup);
         boolean waitForSshable = 
!"false".equalsIgnoreCase(setup.get(WAIT_FOR_SSHABLE));
         boolean waitForWinRmable = 
!"false".equalsIgnoreCase(setup.get(WAIT_FOR_WINRM_AVAILABLE));
         boolean usePortForwarding = setup.get(USE_PORT_FORWARDING);
@@ -728,10 +726,11 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
                 LOG.debug("jclouds using template {} / options {} to provision 
machine in {}",
                         new Object[] {template, template.getOptions(), 
setup.getDescription()});
 
-                if (!setup.getUnusedConfig().isEmpty())
-                    if (LOG.isDebugEnabled())
-                        LOG.debug("NOTE: unused flags passed to obtain VM in 
"+setup.getDescription()+": "
-                                + Sanitizer.sanitize(setup.getUnusedConfig()));
+                // no longer supported because config is sealed, we use an 
underlying config map
+//                if (!setup.getUnusedConfig().isEmpty())
+//                    if (LOG.isDebugEnabled())
+//                        LOG.debug("NOTE: unused flags passed to obtain VM in 
"+setup.getDescription()+": "
+//                                + 
Sanitizer.sanitize(setup.getUnusedConfig()));
                 nodes = computeService.createNodesInGroup(groupId, 1, 
template);
                 provisionTimestamp = Duration.of(provisioningStopwatch);
             } finally {
@@ -2275,9 +2274,6 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
      * @return
      */
     protected NodeMetadata findNodeOrThrow(ConfigBag config) {
-        if (config.getDescription() == null) {
-            setCreationString(config);
-        }
         String user = checkNotNull(getUser(config), "user");
         String rawId = (String) config.getStringKey("id");
         String rawHostname = (String) config.getStringKey("hostname");

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8405d877/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java
 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java
index 6b568de..e18fd66 100644
--- 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java
+++ 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java
@@ -345,8 +345,7 @@ public class JcloudsLocationResolverTest {
     
     @Test
     public void testResolvesListAndMapPropertiesWithoutMergeOnInheritance() 
throws Exception {
-        // when we have a yaml way to specify config we may wish to have 
different semantics;
-        // it could depend on the collection config key whether to merge on 
inheritance
+        // since prop2 does not specify DEEP_MERGE config inheritance, we 
overwrite
         brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop1", "[ 
a, b ]");
         brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop2", "{ 
a: 1, b: 2 }");
         brooklynProperties.put("brooklyn.location.named.foo", 
"jclouds:softlayer:ams01");
@@ -356,10 +355,6 @@ public class JcloudsLocationResolverTest {
         brooklynProperties.put("brooklyn.location.named.bar", "named:foo");
         brooklynProperties.put("brooklyn.location.named.bar.prop2", "{ c: 4, 
d: 4 }");
         
-        // these do NOT affect the maps
-        brooklynProperties.put("brooklyn.location.named.foo.prop2.z", "9");
-        brooklynProperties.put("brooklyn.location.named.foo.prop3.z", "9");
-        
         JcloudsLocation l = resolve("named:bar");
         assertJcloudsEquals(l, "softlayer", "ams01");
         
@@ -376,6 +371,33 @@ public class JcloudsLocationResolverTest {
         assertEquals(prop3, null);
     }
 
+    @Test
+    public void testResolvesListAndMapPropertiesMergesWithDotQualifiedKeys() 
throws Exception {
+        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop1", "[ 
a, b ]");
+        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop2", "{ 
a: 1, b: 2 }");
+        brooklynProperties.put("brooklyn.location.named.foo", 
"jclouds:softlayer:ams01");
+        
+        brooklynProperties.put("brooklyn.location.named.foo.prop1", "[ a: 1, 
c: 3 ]");
+        brooklynProperties.put("brooklyn.location.named.foo.prop2", "{ b: 3, 
c: 3 }");
+        brooklynProperties.put("brooklyn.location.named.bar", "named:foo");
+        brooklynProperties.put("brooklyn.location.named.bar.prop2", "{ c: 4, 
d: 4 }");
+        
+        // dot-qualified keys now DO get interpreted (sept 2016)
+        brooklynProperties.put("brooklyn.location.named.foo.prop2.z", 9);
+        brooklynProperties.put("brooklyn.location.named.foo.prop3.z", 10);
+        
+        JcloudsLocation l = resolve("named:bar");
+        assertJcloudsEquals(l, "softlayer", "ams01");
+        
+        Map<String, String> prop2 = l.config().get(new 
MapConfigKey<String>(String.class, "prop2"));
+        log.info("prop2: "+prop2);
+        assertEquals(prop2, MutableMap.of("c", 4, "d", 4, "z", "9"));
+        
+        Map<String, String> prop3 = l.config().get(new 
MapConfigKey<String>(String.class, "prop3"));
+        log.info("prop3: "+prop3);
+        assertEquals(prop3, MutableMap.of("z", "10"));
+    }
+    
     private void assertJcloudsEquals(JcloudsLocation loc, String 
expectedProvider, String expectedRegion) {
         assertEquals(loc.getProvider(), expectedProvider);
         assertEquals(loc.getRegion(), expectedRegion);

Reply via email to