You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2016/09/22 21:09:43 UTC

[11/22] brooklyn-server git commit: promote more things to AbstractConfigMapImpl

promote more things to AbstractConfigMapImpl


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

Branch: refs/heads/master
Commit: 06eca356737a528d8e1806b7f2168ae8b07ebf12
Parents: 5e2b7d4
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Sep 20 11:24:36 2016 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Wed Sep 21 16:06:06 2016 +0100

----------------------------------------------------------------------
 .../apache/brooklyn/api/entity/EntityLocal.java |   5 -
 .../config/internal/AbstractConfigMapImpl.java  | 129 +++++++++++++-
 .../brooklyn/core/entity/AbstractEntity.java    |  12 +-
 .../core/entity/internal/EntityConfigMap.java   | 173 +++++++------------
 .../brooklyn/core/objs/AdjunctConfigMap.java    |  98 +++++------
 5 files changed, 235 insertions(+), 182 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/06eca356/api/src/main/java/org/apache/brooklyn/api/entity/EntityLocal.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/EntityLocal.java b/api/src/main/java/org/apache/brooklyn/api/entity/EntityLocal.java
index 4e4e75f..6fa181b 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/EntityLocal.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/EntityLocal.java
@@ -90,11 +90,6 @@ public interface EntityLocal extends Entity {
      * @deprecated since 0.8.0; use {@link SensorSupport#emit(Sensor, Object)} via code like {@code sensors().emit(sensor, val)}.
      */
     <T> void emit(Sensor<T> sensor, T value);
-    
-    /**
-     * @deprecated in 0.5; use {@link #getConfig(ConfigKey)}
-     */
-    <T> T getConfig(ConfigKey<T> key, T defaultValue);
 
     /**
      * Allow us to subscribe to data from a {@link Sensor} on another entity.

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/06eca356/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 eb99157..b40e928 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
@@ -23,39 +23,68 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.concurrent.Future;
 
+import org.apache.brooklyn.api.mgmt.ExecutionContext;
+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.ConfigKeys;
 import org.apache.brooklyn.core.config.Sanitizer;
 import org.apache.brooklyn.core.config.StructuredConfigKey;
 import org.apache.brooklyn.core.entity.internal.ConfigMapViewWithStringKeys;
+import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
+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.internal.ConfigKeySelfExtracting;
 import org.apache.brooklyn.util.core.task.DeferredSupplier;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Function;
+
 public abstract class AbstractConfigMapImpl implements ConfigMap {
 
+    /*
+     * Changed Sept 2016 so that keys can determine inheritance strategy at every level in the hierarchy,
+     * and signifcantly refactored to share code among subclasses, adding Location as a subclass.
+     */
+
     private static final Logger LOG = LoggerFactory.getLogger(AbstractConfigMapImpl.class);
     
     protected final ConfigMapViewWithStringKeys mapViewWithStringKeys = new ConfigMapViewWithStringKeys(this);
+
+    protected BrooklynObjectInternal bo;
     
     /**
      * Map of configuration information that is defined at start-up time for the entity. These
      * configuration parameters are shared and made accessible to the "children" of this
      * entity.
      */
-    protected Map<ConfigKey<?>,Object> ownConfig = Collections.synchronizedMap(new LinkedHashMap<ConfigKey<?>, Object>());
+    protected final Map<ConfigKey<?>,Object> ownConfig;
+    
+    protected AbstractConfigMapImpl(BrooklynObject bo) {
+        // Not using ConcurrentMap, because want to (continue to) allow null values.
+        // Could use ConcurrentMapAcceptingNullVals (with the associated performance hit on entrySet() etc).
+        this(bo, Collections.synchronizedMap(new LinkedHashMap<ConfigKey<?>, Object>()));
+    }
+    protected AbstractConfigMapImpl(BrooklynObject bo, Map<ConfigKey<?>, Object> storage) {
+        this.bo = (BrooklynObjectInternal) bo;
+        this.ownConfig = storage;
+    }
 
+    protected BrooklynObjectInternal getBrooklynObject() {
+        return bo;
+    }
+    
     public <T> T getConfig(ConfigKey<T> key) {
-        return getConfig(key, null);
+        return getConfigImpl(key);
     }
     
-    protected abstract <T> T getConfig(ConfigKey<T> key, T defaultValue);
 
     public <T> T getConfig(HasConfigKey<T> key) {
-        return getConfig(key.getConfigKey(), null);
+        return getConfigImpl(key.getConfigKey());
     }
     
     @Override
@@ -63,6 +92,98 @@ public abstract class AbstractConfigMapImpl implements ConfigMap {
         return getConfigRaw(key, false);
     }
 
+    protected abstract <T> T getConfigImpl(ConfigKey<T> key);
+    
+    protected abstract ExecutionContext getExecutionContext(BrooklynObject bo);
+    protected abstract void postLocalEvaluate(ConfigKey<?> key, BrooklynObject bo, Maybe<?> rawValue, Maybe<?> resolvedValue);
+    
+    protected class LocalEvaluateKeyValue<TContainer extends BrooklynObject, TValue> implements Function<TContainer,Maybe<TValue>> {
+        ConfigKey<TValue> keyIgnoringInheritance;
+        
+        public LocalEvaluateKeyValue(ConfigKey<TValue> keyIgnoringInheritance) {
+            this.keyIgnoringInheritance = keyIgnoringInheritance;
+        }
+        
+        @Override
+        public Maybe<TValue> apply(TContainer bo) {
+            ExecutionContext exec = getExecutionContext(bo);
+            
+            ConfigMap configMap = ((BrooklynObjectInternal)bo).config().getInternalConfigMap();
+            Map<ConfigKey<?>,Object> ownConfig = ((AbstractConfigMapImpl)configMap).ownConfig;
+            Maybe<Object> rawValue = configMap.getConfigLocalRaw(keyIgnoringInheritance);
+            Maybe<TValue> ownValue;
+            
+            // Get own value
+            if (keyIgnoringInheritance instanceof ConfigKeySelfExtracting) {
+                if (((ConfigKeySelfExtracting<TValue>)keyIgnoringInheritance).isSet(ownConfig)) {
+                    Map<ConfigKey<?>, ?> ownCopy;
+                    synchronized (ownConfig) {
+                        // wasteful to make a copy to look up; maybe try once opportunistically?
+                        ownCopy = MutableMap.copyOf(ownConfig);
+                    }
+                    ownValue = Maybe.of(((ConfigKeySelfExtracting<TValue>) keyIgnoringInheritance).extractValue(ownCopy, exec));
+                } else {
+                    ownValue = Maybe.<TValue>absent();
+                }
+            } else {
+                // all our keys are self-extracting
+                LOG.warn("Unexpected key type "+keyIgnoringInheritance+" ("+keyIgnoringInheritance.getClass()+") in "+bo+"; ignoring value");
+                ownValue = Maybe.<TValue>absent();
+            }
+
+            postLocalEvaluate(keyIgnoringInheritance, bo, rawValue, ownValue);
+            return ownValue;
+        }
+    }
+    
+    /** an immutable copy of the config defined at this entity, ie not inherited */
+    public Map<ConfigKey<?>,Object> getLocalConfig() {
+        Map<ConfigKey<?>,Object> result = new LinkedHashMap<ConfigKey<?>,Object>(ownConfig.size());
+        result.putAll(ownConfig);
+        return Collections.unmodifiableMap(result);
+    }
+    
+    /** Creates an immutable copy of the config defined at this entity, ie not inherited, including those that did not match config keys */
+    public ConfigBag getLocalConfigBag() {
+        return ConfigBag.newInstance().putAll(ownConfig).seal();
+    }
+
+    public Object setConfig(ConfigKey<?> key, Object v) {
+        Object val = coerceConfigVal(key, v);
+        Object oldVal;
+        if (key instanceof StructuredConfigKey) {
+            oldVal = ((StructuredConfigKey)key).applyValueToMap(val, ownConfig);
+        } else {
+            oldVal = ownConfig.put(key, val);
+        }
+        postSetConfig();
+        return oldVal;
+    }
+    
+    protected abstract void postSetConfig();
+    
+    public void setLocalConfig(Map<ConfigKey<?>, ?> vals) {
+        synchronized (ownConfig) {
+            ownConfig.clear();
+            ownConfig.putAll(vals);
+        }
+    }
+ 
+    public void addToLocalBag(Map<String,?> 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());
+        }
+    }
+    
+    public void removeFromLocalBag(String key) {
+        // FIXME probably never worked, config key vs string ?
+        ownConfig.remove(key);
+    }
+
     protected Object coerceConfigVal(ConfigKey<?> key, Object v) {
         Object val;
         if ((v instanceof Future) || (v instanceof DeferredSupplier)) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/06eca356/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 750adb2..1885677 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
@@ -1303,12 +1303,12 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
     public <T> T getConfig(HasConfigKey<T> key) {
         return config().get(key);
     }
-    
-    //don't use groovy defaults for defaultValue as that doesn't implement the contract; we need the above
-    @Override
-    @Deprecated
-    public <T> T getConfig(ConfigKey<T> key, T defaultValue) {
-        return configsInternal.getConfig(key, defaultValue);
+
+    // kept for internal use, for convenience
+    protected <T> T getConfig(ConfigKey<T> key, T defaultValue) {
+        T result = configsInternal.getConfig(key);
+        if (result==null) return defaultValue;
+        return result;
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/06eca356/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 a76a592..7dac49d 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
@@ -27,24 +27,19 @@ import java.util.Map;
 import org.apache.brooklyn.api.entity.Entity;
 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.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.Sanitizer;
-import org.apache.brooklyn.core.config.StructuredConfigKey;
 import org.apache.brooklyn.core.config.internal.AbstractConfigMapImpl;
-import org.apache.brooklyn.core.entity.AbstractEntity;
 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.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.core.internal.ConfigKeySelfExtracting;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.slf4j.Logger;
@@ -58,89 +53,81 @@ public class EntityConfigMap extends AbstractConfigMapImpl {
 
     private static final Logger LOG = LoggerFactory.getLogger(EntityConfigMap.class);
 
-    /** entity against which config resolution / task execution will occur */
-    private final AbstractEntity entity;
+    public EntityConfigMap(EntityInternal entity) {
+        super(checkNotNull(entity, "entity must be specified"));
+    }
+    
+    public EntityConfigMap(EntityInternal entity, Map<ConfigKey<?>, Object> storage) {
+        super(checkNotNull(entity, "entity must be specified"), checkNotNull(storage, "storage map must be specified"));
+    }
+
+    /** entity against which config resolution / task execution will occur
+     * @deprecated since 0.10.0 kept for serialization */ @Deprecated
+    private EntityInternal entity;
+    @Override
+    protected BrooklynObjectInternal getBrooklynObject() {
+        BrooklynObjectInternal result = super.getBrooklynObject();
+        if (result!=null) return result;
+
+        synchronized (this) {
+            result = super.getBrooklynObject();
+            if (result!=null) return result;
+            bo = entity;
+            entity = null;
+        }
+        return super.getBrooklynObject();
+    }
 
-    public EntityConfigMap(AbstractEntity entity) {
-        // Not using ConcurrentMap, because want to (continue to) allow null values.
-        // Could use ConcurrentMapAcceptingNullVals (with the associated performance hit on entrySet() etc).
-        this(entity, Collections.synchronizedMap(Maps.<ConfigKey<?>, Object>newLinkedHashMap()));
+    protected EntityInternal getEntity() {
+        return (EntityInternal) getBrooklynObject();
     }
     
-    public EntityConfigMap(AbstractEntity entity, Map<ConfigKey<?>, Object> storage) {
-        this.entity = checkNotNull(entity, "entity must be specified");
-        this.ownConfig = checkNotNull(storage, "storage map must be specified");
+    @Override
+    protected ExecutionContext getExecutionContext(BrooklynObject bo) {
+        return ((EntityInternal)bo).getExecutionContext();
     }
     
-    protected static class LocalEvaluateKeyValue<T> implements Function<Entity,Maybe<T>> {
-        ConfigKey<T> keyIgnoringInheritance;
-        
-        public LocalEvaluateKeyValue(ConfigKey<T> keyIgnoringInheritance) {
-            this.keyIgnoringInheritance = keyIgnoringInheritance;
-        }
-        
-        @Override
-        public Maybe<T> apply(Entity entity) {
-            ExecutionContext exec = ((EntityInternal)entity).getExecutionContext();
-            ConfigMap configMap = ((ConfigurationSupportInternal)entity.config()).getInternalConfigMap();
-            Map<ConfigKey<?>,Object> ownConfig = ((EntityConfigMap)configMap).ownConfig;
-            Maybe<Object> rawValue = configMap.getConfigLocalRaw(keyIgnoringInheritance);
-            Maybe<T> ownValue;
-            
-            // Get own value
-            if (keyIgnoringInheritance instanceof ConfigKeySelfExtracting) {
-                if (((ConfigKeySelfExtracting<T>)keyIgnoringInheritance).isSet(ownConfig)) {
-                    Map<ConfigKey<?>, ?> ownCopy;
-                    synchronized (ownConfig) {
-                        // TODO wasteful to make a copy to look up; maybe try once opportunistically?
-                        ownCopy = MutableMap.copyOf(ownConfig);
-                    }
-                    ownValue = Maybe.of(((ConfigKeySelfExtracting<T>) keyIgnoringInheritance).extractValue(ownCopy, exec));
-                } else {
-                    ownValue = Maybe.<T>absent();
-                }
-            } else {
-                // all our keys are self-extracting
-                LOG.warn("Unexpected key type "+keyIgnoringInheritance+" ("+keyIgnoringInheritance.getClass()+") in "+entity+"; ignoring value");
-                ownValue = Maybe.<T>absent();
-            }
+    @Override
+    protected void postSetConfig() {
+        getEntity().config().refreshInheritedConfigOfChildren();
+    }
 
-            // TEMPORARY CODE
-            // We're notifying of config-changed because currently persistence needs to know when the
-            // attributeWhenReady is complete (so it can persist the result).
-            // Long term, we'll just persist tasks properly so the call to onConfigChanged will go!
-            if (rawValue.isPresent() && (rawValue.get() instanceof Task)) {
-                ((EntityInternal)entity).getManagementSupport().getEntityChangeListener().onConfigChanged(keyIgnoringInheritance);
-            }
-            
-            return ownValue;
+    @Override
+    protected void postLocalEvaluate(ConfigKey<?> key, BrooklynObject bo, Maybe<?> rawValue, Maybe<?> resolvedValue) {
+        // TEMPORARY CODE
+        // We're notifying of config-changed because currently persistence needs to know when the
+        // attributeWhenReady is complete (so it can persist the result).
+        // Long term, we'll just persist tasks properly so the call to onConfigChanged will go!
+        if (rawValue.isPresent() && (rawValue.get() instanceof Task)) {
+            ((EntityInternal)bo).getManagementSupport().getEntityChangeListener().onConfigChanged(key);
         }
     }
     
-    public <T> T getConfig(ConfigKey<T> key, T defaultValue) {
+    @Override
+    protected <T> T getConfigImpl(ConfigKey<T> key) {
         Function<Entity, ConfigKey<T>> keyFn = EntityFunctions.configKeyFinder(key, null);
         
         // 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(entity);
+        ConfigKey<T> ownKey = keyFn.apply(getEntity());
         if (ownKey==null) ownKey = key;
         
-        LocalEvaluateKeyValue<T> evalFn = new LocalEvaluateKeyValue<T>(ownKey);
+        LocalEvaluateKeyValue<Entity,T> evalFn = new LocalEvaluateKeyValue<Entity,T>(ownKey);
 
         if (ownKey instanceof ConfigKeySelfExtracting) {
-            Maybe<T> ownExplicitValue = evalFn.apply(entity);
+            Maybe<T> ownExplicitValue = evalFn.apply(getEntity());
             
             AncestorContainerAndKeyValueIterator<Entity, T> ckvi = new AncestorContainerAndKeyValueIterator<Entity,T>(
-                entity, keyFn, evalFn, EntityFunctions.parent());
+                getEntity(), keyFn, evalFn, EntityFunctions.parent());
             
             ContainerAndValue<T> result = getDefaultRuntimeInheritance().resolveInheriting(ownKey,
-                ownExplicitValue, entity,
+                ownExplicitValue, getEntity(),
                 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, this);
         }
-        return TypeCoercions.coerce(defaultValue, key.getTypeToken());
+        return null;
     }
 
     private ConfigInheritance getDefaultRuntimeInheritance() {
@@ -150,23 +137,16 @@ 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 || entity.getParent()==null) return Maybe.absent(); 
-        return ((ConfigurationSupportInternal)entity.getParent().config()).getRaw(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 (entity.getParent()!=null)
-            result.putAll( ((BrooklynObjectInternal)entity.getParent()).config().getInternalConfigMap().getAllConfig() );
-        result.putAll(ownConfig);
-        return Collections.unmodifiableMap(result);
-    }
-
-    /** an immutable copy of the config defined at this entity, ie not inherited */
-    public Map<ConfigKey<?>,Object> getLocalConfig() {
-        Map<ConfigKey<?>,Object> result = new LinkedHashMap<ConfigKey<?>,Object>(ownConfig.size());
+        if (getEntity().getParent()!=null)
+            result.putAll( ((BrooklynObjectInternal)getEntity().getParent()).config().getInternalConfigMap().getAllConfig() );
         result.putAll(ownConfig);
         return Collections.unmodifiableMap(result);
     }
@@ -175,52 +155,17 @@ public class EntityConfigMap extends AbstractConfigMapImpl {
     // TODO deprecate because key inheritance not respected
     public ConfigBag getAllConfigBag() {
         ConfigBag result = ConfigBag.newInstance().putAll(ownConfig);
-        if (entity.getParent()!=null) {
+        if (getEntity().getParent()!=null) {
             result.putIfAbsent(
-                ((EntityConfigMap) ((BrooklynObjectInternal)entity.getParent()).config().getInternalConfigMap()).getAllConfigBag() );
+                ((EntityConfigMap) ((BrooklynObjectInternal)getEntity().getParent()).config().getInternalConfigMap()).getAllConfigBag() );
         }
         return result.seal();
     }
-
-    /** Creates an immutable copy of the config defined at this entity, ie not inherited, including those that did not match config keys */
-    public ConfigBag getLocalConfigBag() {
-        return ConfigBag.newInstance().putAll(ownConfig).seal();
-    }
-
-    @SuppressWarnings("unchecked")
-    public Object setConfig(ConfigKey<?> key, Object v) {
-        Object val = coerceConfigVal(key, v);
-        Object oldVal;
-        if (key instanceof StructuredConfigKey) {
-            oldVal = ((StructuredConfigKey)key).applyValueToMap(val, ownConfig);
-        } else {
-            oldVal = ownConfig.put(key, val);
-        }
-        entity.config().refreshInheritedConfigOfChildren();
-        return oldVal;
-    }
     
-    public void setLocalConfig(Map<ConfigKey<?>, ?> vals) {
-        synchronized (ownConfig) {
-            ownConfig.clear();
-            ownConfig.putAll(vals);
-        }
-    }
- 
-    public void addToLocalBag(Map<String,?> vals) {
-        ConfigBag ownConfigBag = ConfigBag.newInstance().putAll(vals);
-        // TODO quick fix for problem that ownConfig can get out of synch
-        ownConfig.putAll(ownConfigBag.getAllConfigAsConfigKeyMap());
-    }
-
-    public void removeFromLocalBag(String key) {
-        ownConfig.remove(key);
-    }
-
     @Override
     // TODO deprecate or clarify syntax 
     public EntityConfigMap submap(Predicate<ConfigKey<?>> filter) {
-        EntityConfigMap m = new EntityConfigMap(entity, Maps.<ConfigKey<?>, Object>newLinkedHashMap());
+        EntityConfigMap m = new EntityConfigMap(getEntity(), Maps.<ConfigKey<?>, Object>newLinkedHashMap());
         synchronized (ownConfig) {
             for (Map.Entry<ConfigKey<?>,Object> entry: ownConfig.entrySet()) {
                 if (filter.apply(entry.getKey())) {
@@ -228,8 +173,8 @@ public class EntityConfigMap extends AbstractConfigMapImpl {
                 }
             }
         }
-        if (entity.getParent()!=null) {
-            merge(m, ((EntityConfigMap) ((ConfigurationSupportInternal)entity.getParent().config()).getInternalConfigMap()).submap(filter));
+        if (getEntity().getParent()!=null) {
+            merge(m, ((EntityConfigMap) ((ConfigurationSupportInternal)getEntity().getParent().config()).getInternalConfigMap()).submap(filter));
         }
         return m;
     }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/06eca356/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 87e602b..32a613a 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
@@ -23,11 +23,10 @@ import static org.apache.brooklyn.util.groovy.GroovyJavaMethods.elvis;
 import java.util.Collections;
 import java.util.Map;
 
-import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.mgmt.ExecutionContext;
+import org.apache.brooklyn.api.objs.BrooklynObject;
 import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.config.StructuredConfigKey;
 import org.apache.brooklyn.core.config.internal.AbstractConfigMapImpl;
 import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
@@ -44,48 +43,60 @@ public class AdjunctConfigMap extends AbstractConfigMapImpl {
 
     private static final Logger LOG = LoggerFactory.getLogger(AdjunctConfigMap.class);
 
-    /** policy against which config resolution / task execution will occur */
-    private final AbstractEntityAdjunct adjunct;
+    public AdjunctConfigMap(AbstractEntityAdjunct adjunct) {
+        super( Preconditions.checkNotNull(adjunct, "AbstractEntityAdjunct must be specified") );
+    }
 
-    /*
-     * TODO An alternative implementation approach would be to have:
-     *   setParent(Entity o, Map<ConfigKey,Object> inheritedConfig=[:])
-     * The idea is that the parent could in theory decide explicitly what in its config
-     * would be shared.
-     * I (Aled) am undecided as to whether that would be better...
-     * 
-     * (Alex) i lean toward the config key getting to make the decision
-     */
+    /** policy against which config resolution / task execution will occur 
+     * @deprecated since 0.10.0 kept for serialization */ @Deprecated
+    private AbstractEntityAdjunct adjunct;
+    @Override
+    protected BrooklynObjectInternal getBrooklynObject() {
+        BrooklynObjectInternal result = super.getBrooklynObject();
+        if (result!=null) return result;
 
-    public AdjunctConfigMap(AbstractEntityAdjunct adjunct) {
-        this.adjunct = Preconditions.checkNotNull(adjunct, "AbstractEntityAdjunct must be specified");
+        synchronized (this) {
+            result = super.getBrooklynObject();
+            if (result!=null) return result;
+            bo = adjunct;
+            adjunct = null;
+        }
+        return super.getBrooklynObject();
+    }
+
+    protected AbstractEntityAdjunct getAdjunct() {
+        return (AbstractEntityAdjunct) getBrooklynObject();
     }
 
-    @SuppressWarnings("unchecked")
-    protected <T> T getConfig(ConfigKey<T> key, T defaultValue) {
-        // FIXME What about inherited task in config?!
-        //              alex says: think that should work, no?
-        // FIXME What if someone calls getConfig on a task, before setting parent app?
-        //              alex says: not supported (throw exception, or return the task)
+    @Override
+    protected void postLocalEvaluate(ConfigKey<?> key, BrooklynObject bo, Maybe<?> rawValue, Maybe<?> resolvedValue) { /* noop */ }
+
+    @Override
+    protected void postSetConfig() { /* noop */ }
+
+    @Override
+    protected ExecutionContext getExecutionContext(BrooklynObject bo) {
+        // TODO expose ((AbstractEntityAdjunct)bo).execution ?
+        Entity entity = ((AbstractEntityAdjunct)bo).entity;
+        return (entity != null) ? ((EntityInternal)entity).getExecutionContext() : null;
+    }
+    
+    protected <T> T getConfigImpl(ConfigKey<T> key) {
+        // tasks won't resolve if we aren't yet connected to an entity
+        
+        // no need for inheritance, so much simpler than other impls
         
-        // In case this entity class has overridden the given key (e.g. to set default), then retrieve this entity's key
-        // TODO If ask for a config value that's not in our configKeys, should we really continue with rest of method and return key.getDefaultValue?
-        //      e.g. SshBasedJavaAppSetup calls setAttribute(JMX_USER), which calls getConfig(JMX_USER)
-        //           but that example doesn't have a default...
-        ConfigKey<T> ownKey = adjunct!=null ? (ConfigKey<T>)elvis(adjunct.getAdjunctType().getConfigKey(key.getName()), key) : key;
+        @SuppressWarnings("unchecked")
+        ConfigKey<T> ownKey = getAdjunct()!=null ? (ConfigKey<T>)elvis(getAdjunct().getAdjunctType().getConfigKey(key.getName()), key) : key;
         
-        // Don't use groovy truth: if the set value is e.g. 0, then would ignore set value and return default!
         if (ownKey instanceof ConfigKeySelfExtracting) {
             if (((ConfigKeySelfExtracting<T>)ownKey).isSet(ownConfig)) {
-                // FIXME Should we support config from futures? How to get execution context before setEntity?
-                EntityLocal entity = adjunct.entity;
-                ExecutionContext exec = (entity != null) ? ((EntityInternal)entity).getExecutionContext() : null;
-                return ((ConfigKeySelfExtracting<T>)ownKey).extractValue(ownConfig, exec);
+                return ((ConfigKeySelfExtracting<T>)ownKey).extractValue(ownConfig, getExecutionContext(getAdjunct()));
             }
         } else {
             LOG.warn("Config key {} of {} is not a ConfigKeySelfExtracting; cannot retrieve value; returning default", ownKey, this);
         }
-        return TypeCoercions.coerce((defaultValue != null) ? defaultValue : ownKey.getDefaultValue(), key.getTypeToken());
+        return TypeCoercions.coerce(ownKey.getDefaultValue(), key.getTypeToken());
     }
     
     @Override
@@ -101,28 +112,9 @@ public class AdjunctConfigMap extends AbstractConfigMapImpl {
         return Collections.unmodifiableMap(Maps.newLinkedHashMap(ownConfig));
     }
 
-    public Object setConfig(ConfigKey<?> key, Object v) {
-        Object val = coerceConfigVal(key, v);
-        if (key instanceof StructuredConfigKey) {
-            return ((StructuredConfigKey)key).applyValueToMap(val, ownConfig);
-        } else {
-            return ownConfig.put(key, val);
-        }
-    }
-    
-    public void addToLocalBag(Map<String, ?> vals) {
-        for (Map.Entry<String, ?> entry : vals.entrySet()) {
-            setConfig(ConfigKeys.newConfigKey(Object.class, entry.getKey()), entry.getValue());
-        }
-    }
-
-    public void removeFromLocalBag(String key) {
-        ownConfig.remove(key);
-    }
-
     @Override
     public AdjunctConfigMap submap(Predicate<ConfigKey<?>> filter) {
-        AdjunctConfigMap m = new AdjunctConfigMap(adjunct);
+        AdjunctConfigMap m = new AdjunctConfigMap(getAdjunct());
         for (Map.Entry<ConfigKey<?>,Object> entry: ownConfig.entrySet())
             if (filter.apply(entry.getKey()))
                 m.ownConfig.put(entry.getKey(), entry.getValue());