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