make Location use a ConfigMap to bring it in line with others

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

Branch: refs/heads/master
Commit: ddc17d157d6ef4418a9af3883ad9bcd16ca2c383
Parents: 06eca35
Author: Alex Heneveld <alex.henev...@cloudsoftcorp.com>
Authored: Tue Sep 20 12:28:18 2016 +0100
Committer: Alex Heneveld <alex.henev...@cloudsoftcorp.com>
Committed: Wed Sep 21 16:06:06 2016 +0100

----------------------------------------------------------------------
 .../config/internal/AbstractConfigMapImpl.java  |  50 ++++++-
 .../brooklyn/core/entity/AbstractEntity.java    |  56 +++++---
 .../core/entity/internal/EntityConfigMap.java   |  32 +----
 .../core/location/AbstractLocation.java         | 114 ++++++----------
 .../location/internal/LocationConfigMap.java    | 136 +++++++++++++++++++
 .../core/objs/AbstractEntityAdjunct.java        |   7 +-
 .../brooklyn/core/objs/AdjunctConfigMap.java    |  20 +--
 .../core/objs/BrooklynObjectInternal.java       |   6 +-
 .../core/location/LocationConfigTest.java       |  15 +-
 9 files changed, 288 insertions(+), 148 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/ddc17d15/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 b40e928..60760f6 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
@@ -169,13 +169,22 @@ public abstract class AbstractConfigMapImpl implements 
ConfigMap {
         }
     }
  
-    public void addToLocalBag(Map<String,?> vals) {
+    @SuppressWarnings("unchecked")
+    public void addToLocalBag(Map<?,?> vals) {
 //        ConfigBag ownConfigBag = ConfigBag.newInstance().putAll(vals);
 //        ownConfig.putAll(ownConfigBag.getAllConfigAsConfigKeyMap());
         // below seems more straightforward; should be the same.
         // potential problem if clash of config key types?
-        for (Map.Entry<String, ?> entry : vals.entrySet()) {
-            setConfig(ConfigKeys.newConfigKey(Object.class, entry.getKey()), 
entry.getValue());
+        for (Map.Entry<?, ?> entry : vals.entrySet()) {
+            if (entry.getKey()==null)
+                throw new IllegalArgumentException("Cannot put null key into 
"+this);
+            else if (entry.getKey() instanceof String)
+                setConfig(ConfigKeys.newConfigKey(Object.class, 
(String)entry.getKey()), entry.getValue());
+            else if (entry.getKey() instanceof ConfigKey)
+                setConfig((ConfigKey<Object>)entry.getKey(), entry.getValue());
+            else if (entry.getKey() instanceof HasConfigKey)
+                setConfig( 
((HasConfigKey<Object>)entry.getKey()).getConfigKey(), entry.getValue() );
+            else throw new IllegalArgumentException("Cannot put key 
"+entry.getKey()+" (unknown type "+entry.getKey().getClass()+") into "+this);
         }
     }
     
@@ -184,6 +193,40 @@ public abstract class AbstractConfigMapImpl implements 
ConfigMap {
         ownConfig.remove(key);
     }
 
+    public void removeFromLocalBag(ConfigKey<?> key) {
+        ownConfig.remove(key);
+    }
+
+    protected abstract BrooklynObjectInternal getParent();
+    
+    @Override
+    public Maybe<Object> getConfigRaw(ConfigKey<?> key, boolean 
includeInherited) {
+        // TODO does not currently respect inheritance modes
+        if (ownConfig.containsKey(key)) return Maybe.of(ownConfig.get(key));
+        if (!includeInherited || getParent()==null) return Maybe.absent();
+        return getParent().config().getInternalConfigMap().getConfigRaw(key, 
includeInherited);
+    }
+    
+    /** an immutable copy of the config visible at this entity, local and 
inherited (preferring local) */
+    // TODO deprecate because key inheritance not respected
+    public Map<ConfigKey<?>,Object> getAllConfig() {
+        Map<ConfigKey<?>,Object> result = new 
LinkedHashMap<ConfigKey<?>,Object>();
+        if (getParent()!=null)
+            result.putAll( 
getParent().config().getInternalConfigMap().getAllConfig() );
+        result.putAll(ownConfig);
+        return Collections.unmodifiableMap(result);
+    }
+    
+    /** Creates an immutable copy of the config visible at this entity, local 
and inherited (preferring local), including those that did not match config 
keys */
+    // TODO deprecate because key inheritance not respected
+    public ConfigBag getAllConfigBag() {
+        ConfigBag result = ConfigBag.newInstance().putAll(ownConfig);
+        if (getParent()!=null) {
+            result.putIfAbsent(
+                
((AbstractConfigMapImpl)getParent().config().getInternalConfigMap()).getAllConfigBag()
 );
+        }
+        return result.seal();
+    }
     protected Object coerceConfigVal(ConfigKey<?> key, Object v) {
         Object val;
         if ((v instanceof Future) || (v instanceof DeferredSupplier)) {
@@ -212,7 +255,6 @@ public abstract class AbstractConfigMapImpl implements 
ConfigMap {
         }
         return val;
     }
-
     
     @Override
     public Map<String,Object> asMapWithStringKeys() {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/ddc17d15/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 1885677..663c0ac 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
@@ -43,6 +43,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.EntityMemento;
+import org.apache.brooklyn.api.objs.BrooklynObject;
 import org.apache.brooklyn.api.objs.EntityAdjunct;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
@@ -54,14 +55,15 @@ import org.apache.brooklyn.api.sensor.Sensor;
 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.ConfigMap;
 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;
 import org.apache.brooklyn.core.config.BasicConfigInheritance;
 import org.apache.brooklyn.core.config.BasicConfigKey;
 import org.apache.brooklyn.core.config.ConfigConstraints;
+import org.apache.brooklyn.core.config.internal.AbstractConfigMapImpl;
 import org.apache.brooklyn.core.config.render.RendererHints;
 import org.apache.brooklyn.core.enricher.AbstractEnricher;
 import org.apache.brooklyn.core.entity.internal.EntityConfigMap;
@@ -1207,9 +1209,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 configsInternal.getConfig(key);
+            return getConfigsInternal().getConfig(key);
         }
 
         @Override
@@ -1224,33 +1230,44 @@ public abstract class AbstractEntity extends 
AbstractBrooklynObject implements E
         }
 
         @Override
-        public ConfigBag getBag() {
-            return configsInternal.getAllConfigBag();
-        }
-
-        @Override
         public ConfigBag getLocalBag() {
-            return configsInternal.getLocalConfigBag();
+            return getConfigsInternal().getLocalConfigBag();
         }
 
         @Override
         public Maybe<Object> getRaw(ConfigKey<?> key) {
-            return configsInternal.getConfigRaw(key, true);
+            return getConfigsInternal().getConfigRaw(key, true);
         }
 
         @Override
         public Maybe<Object> getLocalRaw(ConfigKey<?> key) {
-            return configsInternal.getConfigRaw(key, false);
+            return getConfigsInternal().getConfigRaw(key, false);
         }
 
         @Override
-        public void addToLocalBag(Map<String, ?> vals) {
-            configsInternal.addToLocalBag(vals);
+        public void addToLocalBag(Map<?, ?> vals) {
+            getConfigsInternal().addToLocalBag(vals);
         }
 
         @Override
         public void removeFromLocalBag(String key) {
-            configsInternal.removeFromLocalBag(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();
         }
 
         @Override
@@ -1275,22 +1292,21 @@ public abstract class AbstractEntity extends 
AbstractBrooklynObject implements E
                 // 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[] { AbstractEntity.this, key, val });
+                        new Object[] { getContainer(), key, val });
             }
-            T result = (T) configsInternal.setConfig(key, val);
+            T result = (T) getConfigsInternal().setConfig(key, val);
             
             
getManagementSupport().getEntityChangeListener().onConfigChanged(key);
             return result;
         }
 
-        @Override
-        protected ExecutionContext getContext() {
-            return AbstractEntity.this.getExecutionContext();
+        protected BrooklynObject getContainer() {
+            return AbstractEntity.this;
         }
         
         @Override
-        public ConfigMap getInternalConfigMap() {
-            return configsInternal;
+        protected ExecutionContext getContext() {
+            return AbstractEntity.this.getExecutionContext();
         }
     }
     

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/ddc17d15/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 7dac49d..e2ff0be 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
@@ -20,8 +20,6 @@ package org.apache.brooklyn.core.entity.internal;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
-import java.util.Collections;
-import java.util.LinkedHashMap;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
@@ -39,7 +37,6 @@ import org.apache.brooklyn.core.entity.EntityFunctions;
 import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
 import 
org.apache.brooklyn.core.objs.BrooklynObjectInternal.ConfigurationSupportInternal;
-import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.internal.ConfigKeySelfExtracting;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.slf4j.Logger;
@@ -125,7 +122,7 @@ public class EntityConfigMap extends AbstractConfigMapImpl {
         
             if (result.getValue()!=null) return result.getValue();
         } else {
-            LOG.warn("Config key {} of {} is not a ConfigKeySelfExtracting; 
cannot retrieve value; returning default", ownKey, this);
+            LOG.warn("Config key {} of {} is not a ConfigKeySelfExtracting; 
cannot retrieve value; returning default", ownKey, getBrooklynObject());
         }
         return null;
     }
@@ -135,31 +132,8 @@ public class EntityConfigMap extends AbstractConfigMapImpl 
{
     }
 
     @Override
-    public Maybe<Object> getConfigRaw(ConfigKey<?> key, boolean 
includeInherited) {
-        if (ownConfig.containsKey(key)) return Maybe.of(ownConfig.get(key));
-        if (!includeInherited || getEntity().getParent()==null) return 
Maybe.absent(); 
-        return ((EntityInternal)getEntity().getParent()).config().getRaw(key);
-    }
-    
-    /** an immutable copy of the config visible at this entity, local and 
inherited (preferring local) */
-    // TODO deprecate because key inheritance not respected
-    public Map<ConfigKey<?>,Object> getAllConfig() {
-        Map<ConfigKey<?>,Object> result = new 
LinkedHashMap<ConfigKey<?>,Object>();
-        if (getEntity().getParent()!=null)
-            result.putAll( 
((BrooklynObjectInternal)getEntity().getParent()).config().getInternalConfigMap().getAllConfig()
 );
-        result.putAll(ownConfig);
-        return Collections.unmodifiableMap(result);
-    }
-    
-    /** Creates an immutable copy of the config visible at this entity, local 
and inherited (preferring local), including those that did not match config 
keys */
-    // TODO deprecate because key inheritance not respected
-    public ConfigBag getAllConfigBag() {
-        ConfigBag result = ConfigBag.newInstance().putAll(ownConfig);
-        if (getEntity().getParent()!=null) {
-            result.putIfAbsent(
-                ((EntityConfigMap) 
((BrooklynObjectInternal)getEntity().getParent()).config().getInternalConfigMap()).getAllConfigBag()
 );
-        }
-        return result.seal();
+    protected BrooklynObjectInternal getParent() {
+        return (EntityInternal) getEntity().getParent();
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/ddc17d15/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 20b44ce..f89ae27 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
@@ -21,7 +21,6 @@ package org.apache.brooklyn.core.location;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.apache.brooklyn.util.JavaGroovyEquivalents.groovyTruth;
-import static org.apache.brooklyn.util.groovy.GroovyJavaMethods.elvis;
 
 import java.io.Closeable;
 import java.util.Collection;
@@ -34,7 +33,6 @@ 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.ManagementContext;
 import org.apache.brooklyn.api.mgmt.SubscriptionContext;
 import org.apache.brooklyn.api.mgmt.SubscriptionHandle;
 import org.apache.brooklyn.api.mgmt.Task;
@@ -43,21 +41,19 @@ import 
org.apache.brooklyn.api.mgmt.rebind.mementos.LocationMemento;
 import org.apache.brooklyn.api.objs.Configurable;
 import org.apache.brooklyn.api.sensor.Sensor;
 import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.config.ConfigInheritance;
 import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.config.ConfigMap;
 import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
+import org.apache.brooklyn.config.ConfigMap;
 import org.apache.brooklyn.core.BrooklynFeatureEnablement;
-import org.apache.brooklyn.core.config.BasicConfigInheritance;
 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.ConfigKeys.InheritanceContext;
 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;
 import org.apache.brooklyn.core.location.geo.HasHostGeoInfo;
 import org.apache.brooklyn.core.location.geo.HostGeoInfo;
+import org.apache.brooklyn.core.location.internal.LocationConfigMap;
 import org.apache.brooklyn.core.location.internal.LocationDynamicType;
 import org.apache.brooklyn.core.location.internal.LocationInternal;
 import org.apache.brooklyn.core.mgmt.internal.LocalLocationManager;
@@ -71,8 +67,6 @@ import org.apache.brooklyn.util.core.ClassLoaderUtils;
 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.core.task.Tasks;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.stream.Streams;
@@ -129,7 +123,7 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
     
     private BasicSubscriptionSupport subscriptions = new 
BasicSubscriptionSupport();
     
-    private ConfigBag configBag = new ConfigBag();
+    private LocationConfigMap configMap = new LocationConfigMap(this);
 
     /** not for direct access; refer to as 'subscriptionTracker' via getter so 
that it is initialized */
     protected transient SubscriptionTracker _subscriptionTracker;
@@ -203,7 +197,7 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
         if 
(BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_USE_BROOKLYN_LIVE_OBJECTS_DATAGRID_STORAGE))
 {
             Location oldParent = parent.get();
             Set<Location> oldChildren = children;
-            Map<String, Object> oldConfig = configBag.getAllConfig();
+            LocationConfigMap oldConfig = configMap;
             Long oldCreationTimeUtc = creationTimeUtc.get();
             String oldDisplayName = name.get();
             HostGeoInfo oldHostGeoInfo = hostGeoInfo.get();
@@ -230,9 +224,9 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
                 displayNameAutoGenerated = false;
             }
 
-            configBag = 
ConfigBag.newLiveInstance(managementContext.getStorage().<String,Object>getMap(getId()+"-config"));
+            configMap = new LocationConfigMap(this, 
managementContext.getStorage().<ConfigKey<?>,Object>getMap(getId()+"-config"));
             if (oldConfig.size() > 0) {
-                configBag.putAll(oldConfig);
+                configMap.setLocalConfig(oldConfig.getLocalConfig());
             }
         }
     }
@@ -249,17 +243,18 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
         
         boolean firstTime = !configured.getAndSet(true);
             
-        configBag.putAll(properties);
+        config().addToLocalBag(properties);
         
         if (properties.containsKey(PARENT_LOCATION.getName())) {
             // need to ensure parent's list of children is also updated
-            setParent(configBag.get(PARENT_LOCATION));
+            setParent(config().get(PARENT_LOCATION));
             
             // don't include parentLocation in configBag, as breaks rebind
-            configBag.remove(PARENT_LOCATION);
+            config().removeFromLocalBag(PARENT_LOCATION);
         }
 
-        // NB: flag-setting done here must also be done in 
BasicLocationRebindSupport 
+        // NB: flag-setting done here must also be done in 
BasicLocationRebindSupport
+        ConfigBag configBag = ConfigBag.newInstance(properties);
         FlagUtils.setFieldsFromFlagsWithBag(this, properties, configBag, 
firstTime);
         FlagUtils.setAllConfigKeys(this, configBag, false);
 
@@ -390,42 +385,24 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
 
     private class BasicConfigurationSupport extends 
AbstractConfigurationSupportInternal {
 
+        // 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) {
-            // TODO support merging
-            Object result = null;
-            if (hasConfig(key, false)) {
-                result = getLocalBag().getAllConfigRaw().get(key.getName());
-
-            } else if (getParent() != null && isInherited(key)) {
-                result = getParent().getConfig(key);
-
-            } else {
-                // In case this entity class has overridden the given key 
(e.g. to set default), then retrieve this entity's key
-                // TODO when locations become entities, the duplication of 
this compared to EntityConfigMap.getConfig will disappear.
-                @SuppressWarnings("unchecked")
-                ConfigKey<T> ownKey = (ConfigKey<T>) 
elvis(locationType.getConfigKey(key.getName()), key);
-                result = ownKey.getDefaultValue();
-            }
-
-            if (result instanceof DeferredSupplier<?>) {
-                try {
-                    ManagementContext mgmt = 
AbstractLocation.this.getManagementContext();
-                    ExecutionContext exec = mgmt.getServerExecutionContext();
-                    result = Tasks.resolveValue(result, key.getType(), exec);
-
-                } catch (Exception e) {
-                    throw Exceptions.propagate(e);
-                }
-            }
+            return getConfigMap().getConfig(key);
 
-            return TypeCoercions.coerce(result, key.getTypeToken());
         }
 
         @Override
         public <T> T set(ConfigKey<T> key, T val) {
             ConfigConstraints.assertValid(AbstractLocation.this, key, val);
-            T result = configBag.put(key, val);
+            @SuppressWarnings("unchecked")
+            T result = (T) getConfigMap().setConfig(key, val);
             onChanged();
             return result;
         }
@@ -438,7 +415,7 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
 
         @Override
         public ConfigBag getBag() {
-            ConfigBag result = ConfigBag.newInstanceExtending(configBag, 
ImmutableMap.of());
+            ConfigBag result = getLocalBag();
             Location p = getParent();
             if (p!=null) 
result.putIfAbsent(((LocationInternal)p).config().getBag());
             return result;
@@ -446,30 +423,34 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
 
         @Override
         public ConfigBag getLocalBag() {
-            return configBag;
+            ConfigBag result = ConfigBag.newInstance();
+            result.putAll(getConfigMap().getLocalConfig());
+            return result;
         }
 
         @Override
         public Maybe<Object> getRaw(ConfigKey<?> key) {
-            if (hasConfig(key, false)) return 
Maybe.of(getLocalBag().getStringKey(key.getName()));
-            if (getParent() != null && isInherited(key)) return 
((LocationInternal)getParent()).config().getRaw(key);
-            return Maybe.absent();
+            return getConfigMap().getConfigRaw(key, true);
         }
 
         @Override
         public Maybe<Object> getLocalRaw(ConfigKey<?> key) {
-            if (hasConfig(key, false)) return 
Maybe.of(getLocalBag().getStringKey(key.getName()));
-            return Maybe.absent();
+            return getConfigMap().getConfigLocalRaw(key);
         }
 
         @Override
-        public void addToLocalBag(Map<String, ?> vals) {
-            configBag.putAll(vals);
+        public void addToLocalBag(Map<?, ?> vals) {
+            getConfigMap().addToLocalBag(vals);
         }
 
         @Override
         public void removeFromLocalBag(String key) {
-            configBag.remove(key);
+            getConfigMap().removeFromLocalBag(key);
+        }
+        
+        @Override
+        public void removeFromLocalBag(ConfigKey<?> key) {
+            getConfigMap().removeFromLocalBag(key);
         }
 
         @Override
@@ -482,22 +463,6 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
             // no-op for location
         }
         
-        private boolean hasConfig(ConfigKey<?> key, boolean includeInherited) {
-            if (includeInherited && isInherited(key)) {
-                return getBag().containsKey(key);
-            } else {
-                return getLocalBag().containsKey(key);
-            }
-        }
-        
-        private boolean isInherited(ConfigKey<?> key) {
-            return ConfigKeys.isReinherited(key, 
InheritanceContext.RUNTIME_MANAGEMENT);
-        }
-
-        private ConfigInheritance getDefaultInheritance() {
-            return BasicConfigInheritance.OVERWRITE;
-        }
-
         @Override
         protected ExecutionContext getContext() {
             return 
AbstractLocation.this.getManagementContext().getServerExecutionContext();
@@ -505,7 +470,7 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
         
         @Override
         public ConfigMap getInternalConfigMap() {
-            throw new UnsupportedOperationException("location does not use 
config map");
+            return getConfigMap();
         }
     }
     
@@ -578,7 +543,7 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
     @Override
     @Deprecated
     public boolean hasConfig(ConfigKey<?> key, boolean includeInherited) {
-        return config.hasConfig(key, includeInherited);
+        return config().getInternalConfigMap().getConfigRaw(key, 
includeInherited).isPresent();
     }
 
     @Override
@@ -734,6 +699,7 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
         loadExtension();
     }
 
+    @SuppressWarnings({ "unchecked", "rawtypes" })
     private void loadExtension() {
         Map<String, String> extensions = 
getConfig(LocationConfigKeys.EXTENSIONS);
         if (extensions != null) {
@@ -792,6 +758,10 @@ public abstract class AbstractLocation extends 
AbstractBrooklynObject implements
         return new BasicLocationRebindSupport(this);
     }
     
+    public LocationDynamicType getLocationTypeInternal() {
+        return locationType;
+    }
+    
     @SuppressWarnings("unchecked")
     @Override
     public RelationSupportInternal<Location> relations() {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/ddc17d15/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
new file mode 100644
index 0000000..0e79668
--- /dev/null
+++ 
b/core/src/main/java/org/apache/brooklyn/core/location/internal/LocationConfigMap.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.location.internal;
+
+import static org.apache.brooklyn.util.groovy.GroovyJavaMethods.elvis;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.mgmt.ExecutionContext;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.config.ConfigInheritance;
+import org.apache.brooklyn.config.ConfigInheritance.ContainerAndValue;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.config.ConfigMap;
+import org.apache.brooklyn.core.config.BasicConfigInheritance;
+import 
org.apache.brooklyn.core.config.BasicConfigInheritance.AncestorContainerAndKeyValueIterator;
+import org.apache.brooklyn.core.config.ConfigKeys.InheritanceContext;
+import org.apache.brooklyn.core.config.internal.AbstractConfigMapImpl;
+import org.apache.brooklyn.core.location.AbstractLocation;
+import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
+import org.apache.brooklyn.util.core.internal.ConfigKeySelfExtracting;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+
+public class LocationConfigMap extends AbstractConfigMapImpl {
+
+    private static final Logger log = 
LoggerFactory.getLogger(LocationConfigMap.class);
+    
+    public LocationConfigMap(AbstractLocation loc) {
+        super(loc);
+    }
+
+    public LocationConfigMap(AbstractLocation loc, Map<ConfigKey<?>, Object> 
storage) {
+        super(loc, storage);
+    }
+
+    protected AbstractLocation getLocation() {
+        return (AbstractLocation) getBrooklynObject();
+    }
+    
+    @Override
+    protected BrooklynObjectInternal getParent() {
+        return (BrooklynObjectInternal) getLocation().getParent();
+    }
+    
+    @Override
+    protected <T> T getConfigImpl(final ConfigKey<T> key) {
+        Function<Location, ConfigKey<T>> keyFn = new Function<Location, 
ConfigKey<T>>() {
+            @SuppressWarnings("unchecked")
+            @Override
+            public ConfigKey<T> apply(Location input) {
+                if (input instanceof AbstractLocation) {
+                    return (ConfigKey<T>) elvis( 
((AbstractLocation)input).getLocationTypeInternal().getConfigKey(key.getName()),
 key );
+                }
+                return key;
+            }
+        };
+        
+        // In case this entity class has overridden the given key (e.g. to set 
default), then retrieve this entity's key
+        ConfigKey<T> ownKey = keyFn.apply(getLocation());
+        if (ownKey==null) ownKey = key;
+        
+        LocalEvaluateKeyValue<Location,T> evalFn = new 
LocalEvaluateKeyValue<Location,T>(ownKey);
+
+        if (ownKey instanceof ConfigKeySelfExtracting) {
+            Maybe<T> ownExplicitValue = evalFn.apply(getLocation());
+            
+            AncestorContainerAndKeyValueIterator<Location, T> ckvi = new 
AncestorContainerAndKeyValueIterator<Location,T>(
+                getLocation(), keyFn, evalFn, new 
Function<Location,Location>() {
+                    @Override
+                    public Location apply(Location input) {
+                        if (input==null) return null;
+                        return input.getParent();
+                    }
+                });
+            
+            ContainerAndValue<T> result = 
getDefaultRuntimeInheritance().resolveInheriting(ownKey,
+                ownExplicitValue, getLocation(),
+                ckvi, InheritanceContext.RUNTIME_MANAGEMENT);
+        
+            if (result.getValue()!=null) return result.getValue();
+        } else {
+            log.warn("Config key {} of {} is not a ConfigKeySelfExtracting; 
cannot retrieve value; returning default", ownKey, getBrooklynObject());
+        }
+        return null;
+    }
+    
+    private ConfigInheritance getDefaultRuntimeInheritance() {
+        return BasicConfigInheritance.OVERWRITE; 
+    }
+
+    @Override
+    protected ExecutionContext getExecutionContext(BrooklynObject bo) {
+        if (bo==null) return null;
+        ManagementContext mgmt = ((AbstractLocation)bo).getManagementContext();
+        if (mgmt==null) return null;
+        return mgmt.getServerExecutionContext();
+    }
+
+    @Override
+    protected void postLocalEvaluate(ConfigKey<?> key, BrooklynObject bo, 
Maybe<?> rawValue, Maybe<?> resolvedValue) {
+    }
+
+    @Override
+    protected void postSetConfig() {
+    }
+
+    @Override
+    public ConfigMap submap(Predicate<ConfigKey<?>> filter) {
+        throw new UnsupportedOperationException("Location does not support 
submap");
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/ddc17d15/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 1f20d6d..dd05c4d 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
@@ -336,7 +336,7 @@ public abstract class AbstractEntityAdjunct extends 
AbstractBrooklynObject imple
         }
 
         @Override
-        public void addToLocalBag(Map<String, ?> vals) {
+        public void addToLocalBag(Map<?, ?> vals) {
             configsInternal.addToLocalBag(vals);
         }
         
@@ -344,6 +344,11 @@ public abstract class AbstractEntityAdjunct extends 
AbstractBrooklynObject imple
         public void removeFromLocalBag(String key) {
             configsInternal.removeFromLocalBag(key);
         }
+
+        @Override
+        public void removeFromLocalBag(ConfigKey<?> key) {
+            configsInternal.removeFromLocalBag(key);
+        }
         
         @Override
         public void refreshInheritedConfig() {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/ddc17d15/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 32a613a..7ad9468 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
@@ -20,7 +20,6 @@ package org.apache.brooklyn.core.objs;
 
 import static org.apache.brooklyn.util.groovy.GroovyJavaMethods.elvis;
 
-import java.util.Collections;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
@@ -37,7 +36,6 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
-import com.google.common.collect.Maps;
 
 public class AdjunctConfigMap extends AbstractConfigMapImpl {
 
@@ -69,6 +67,11 @@ public class AdjunctConfigMap extends AbstractConfigMapImpl {
     }
 
     @Override
+    protected BrooklynObjectInternal getParent() {
+        return null;
+    }
+    
+    @Override
     protected void postLocalEvaluate(ConfigKey<?> key, BrooklynObject bo, 
Maybe<?> rawValue, Maybe<?> resolvedValue) { /* noop */ }
 
     @Override
@@ -100,19 +103,6 @@ public class AdjunctConfigMap extends 
AbstractConfigMapImpl {
     }
     
     @Override
-    public Maybe<Object> getConfigRaw(ConfigKey<?> key, boolean 
includeInherited) {
-        if (ownConfig.containsKey(key)) return Maybe.of(ownConfig.get(key));
-        return Maybe.absent();
-    }
-    
-    /** returns the config of this policy */
-    @Override
-    public Map<ConfigKey<?>,Object> getAllConfig() {
-        // Don't use ImmutableMap because valide for values to be null
-        return Collections.unmodifiableMap(Maps.newLinkedHashMap(ownConfig));
-    }
-
-    @Override
     public AdjunctConfigMap submap(Predicate<ConfigKey<?>> filter) {
         AdjunctConfigMap m = new AdjunctConfigMap(getAdjunct());
         for (Map.Entry<ConfigKey<?>,Object> entry: ownConfig.entrySet())

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/ddc17d15/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 4baea63..600104b 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
@@ -124,13 +124,17 @@ public interface BrooklynObjectInternal extends 
BrooklynObject, Rebindable {
         @Beta
         <T> Maybe<T> getNonBlocking(HasConfigKey<T> key);
 
+        /** Adds keys or strings, making anonymous keys from strings; throws 
on other keys */
         @Beta
-        void addToLocalBag(Map<String, ?> vals);
+        void addToLocalBag(Map<?, ?> vals);
 
         @Beta
         void removeFromLocalBag(String key);
 
         @Beta
+        void removeFromLocalBag(ConfigKey<?> key);
+        
+        @Beta
         void refreshInheritedConfig();
 
         @Beta

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/ddc17d15/core/src/test/java/org/apache/brooklyn/core/location/LocationConfigTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/core/location/LocationConfigTest.java 
b/core/src/test/java/org/apache/brooklyn/core/location/LocationConfigTest.java
index 6d6ba7f..fb6cb16 100644
--- 
a/core/src/test/java/org/apache/brooklyn/core/location/LocationConfigTest.java
+++ 
b/core/src/test/java/org/apache/brooklyn/core/location/LocationConfigTest.java
@@ -25,10 +25,11 @@ import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.location.AbstractLocation;
 import org.apache.brooklyn.core.location.internal.LocationInternal;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.util.core.flags.SetFromFlag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
@@ -38,7 +39,9 @@ import com.google.common.collect.ImmutableMap;
 
 public class LocationConfigTest {
 
-    // TODO Duplication of LocationConfigTest, but with locations instead of 
entities
+    // TODO near duplication of EntityConfigTest, but with locations instead 
of entities
+    
+    private static final Logger log = 
LoggerFactory.getLogger(LocationConfigTest.class);
     
     private ManagementContext managementContext;
 
@@ -104,7 +107,8 @@ public class LocationConfigTest {
         Assert.assertEquals(child.getAllConfig(false), ImmutableMap.of());
     }
     
-    // TODO Fails for location, but passes for entity; not worth fixing here; 
locations will soon be entities!
+    // Fails for location, but passes (or used to pass) for entity; not worth 
fixing here; locations will soon be entities, we hope
+    // (Probably also fails for entities now; could just delete test?)
     @Test(groups="WIP")
     public void testChildConfigBagInheritsFlagNameFromParentSetsOwnConfigKey() 
throws Exception {
         LocationInternal loc = 
managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
@@ -160,6 +164,8 @@ public class LocationConfigTest {
                 .parent(loc)
                 .configure("mychildconfigflagname", "overrideMyval"));
 
+        log.info("local="+child.config().getLocalBag());
+        log.info("all="+child.config().getBag());
         assertEquals(child.config().getBag().getAllConfig(), 
ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", 
"mychildconfigflagname", "overrideMyval"));
         assertEquals(child.config().getLocalBag().getAllConfig(), 
ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", 
"mychildconfigflagname", "overrideMyval"));
         Assert.assertEquals(child.getAllConfig(true), 
ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", 
"mychildconfigflagname", "overrideMyval"));
@@ -178,7 +184,6 @@ public class LocationConfigTest {
         
Assert.assertEquals(subloc.getConfig(MyLocation.MY_CONFIG_WITH_DEFAULT), 
"mysubdefault");
     }
     
-    @SuppressWarnings("serial")
     public static class MyLocation extends AbstractLocation {
         public static final ConfigKey<String> MY_CONFIG = 
ConfigKeys.newStringConfigKey("mylocation.myconfig");
 
@@ -188,7 +193,6 @@ public class LocationConfigTest {
         public static final ConfigKey<String> MY_CONFIG_WITH_DEFAULT = 
ConfigKeys.newStringConfigKey("mylocation.myconfigwithdefault", "", 
"mydefault");
     }
     
-    @SuppressWarnings("serial")
     public static class MyChildLocation extends AbstractLocation {
         public static final ConfigKey<String> MY_CHILD_CONFIG = 
ConfigKeys.newStringConfigKey("mychildlocation.myconfig");
 
@@ -196,7 +200,6 @@ public class LocationConfigTest {
         public static final ConfigKey<String> MY_CHILD_CONFIG_WITH_FLAGNAME = 
ConfigKeys.newStringConfigKey("mychildlocation.myconfigwithflagname");
     }
     
-    @SuppressWarnings("serial")
     public static class MySubLocation extends MyLocation {
         public static final ConfigKey<String> MY_CONFIG_WITH_DEFAULT = 
ConfigKeys.newConfigKeyWithDefault(MyLocation.MY_CONFIG_WITH_DEFAULT, 
"mysubdefault");
     }

Reply via email to