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:49 UTC
[17/22] brooklyn-server git commit: cleaner config / config-map api
understanding inheritance
cleaner config / config-map api understanding inheritance
* Config is now resolved against the ancestor where it is defined, e.g. attributeWhenReady;
(but do we need a way to specify that config should be resolved against the resolver?)
* submap is no longer supported for entity config; findKeys has been introduced
* many methods tidied and deprecated
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/0d655e05
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/0d655e05
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/0d655e05
Branch: refs/heads/master
Commit: 0d655e0503ae1cdf7ad4f95b5321118041bd0592
Parents: 914982e
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Sep 20 16:43:43 2016 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Wed Sep 21 16:06:07 2016 +0100
----------------------------------------------------------------------
.../apache/brooklyn/api/objs/Configurable.java | 5 +
.../BrooklynComponentTemplateResolver.java | 46 ++-
.../brooklyn/ConfigInheritanceYamlTest.java | 22 +-
.../brooklyn/camp/brooklyn/ObjectsYamlTest.java | 9 +
.../core/config/BasicConfigInheritance.java | 185 ++++------
.../apache/brooklyn/core/config/ConfigKeys.java | 37 --
.../config/internal/AbstractConfigMapImpl.java | 367 ++++++++++++++-----
.../AncestorContainerAndKeyValueIterator.java | 12 +-
.../internal/BasicConfigValueAtContainer.java | 54 ---
.../internal/LazyContainerAndKeyValue.java | 27 +-
.../core/effector/ssh/SshEffectorTasks.java | 67 ++--
.../brooklyn/core/entity/AbstractEntity.java | 8 +-
.../internal/ConfigMapViewWithStringKeys.java | 10 +-
.../core/entity/internal/EntityConfigMap.java | 69 +---
.../core/internal/BrooklynPropertiesImpl.java | 23 +-
.../core/location/AbstractLocation.java | 13 +-
.../core/location/BasicLocationRegistry.java | 4 +-
.../location/internal/LocationConfigMap.java | 92 ++---
.../entitlement/PerUserEntitlementManager.java | 11 +-
.../BasicExternalConfigSupplierRegistry.java | 2 +-
.../internal/DeferredBrooklynProperties.java | 11 +-
.../mgmt/rebind/BasicEntityRebindSupport.java | 2 +-
.../mgmt/rebind/BasicLocationRebindSupport.java | 4 +-
.../mgmt/rebind/dto/MementosGenerators.java | 6 +-
.../AbstractConfigurationSupportInternal.java | 35 +-
.../core/objs/AbstractEntityAdjunct.java | 11 +-
.../brooklyn/core/objs/AdjunctConfigMap.java | 55 +--
.../core/objs/BasicConfigurableObject.java | 13 +-
.../core/objs/BrooklynObjectInternal.java | 19 +-
.../core/server/BrooklynServerPaths.java | 4 +-
.../FixedListMachineProvisioningLocation.java | 4 +-
.../brooklyn/util/core/ClassLoaderUtils.java | 2 +-
.../brooklyn/util/core/task/ssh/SshTasks.java | 30 +-
.../brooklyn/core/entity/EntityConfigTest.java | 13 +-
.../core/mgmt/rebind/RebindFailuresTest.java | 30 +-
.../util/core/internal/FlagUtilsTest.java | 7 +
.../jclouds/JcloudsByonLocationResolver.java | 2 +-
.../location/jclouds/JcloudsLocation.java | 2 +-
.../AbstractPortableTemplateBuilder.java | 2 +-
.../apache/brooklyn/rest/BrooklynWebConfig.java | 4 +-
.../rest/resources/EntityConfigResource.java | 7 +-
.../rest/resources/PolicyConfigResource.java | 4 +-
.../rest/transform/LocationTransformer.java | 17 +-
.../rest/resources/LocationResourceTest.java | 23 +-
.../rest/util/EntityLocationUtilsTest.java | 2 +-
.../BrooklynNodeUpgradeEffectorBody.java | 2 +-
.../base/VanillaSoftwareProcessTest.java | 3 +-
.../brooklyn/config/ConfigInheritance.java | 180 ++++-----
.../brooklyn/config/ConfigInheritances.java | 185 ++++++++++
.../org/apache/brooklyn/config/ConfigKey.java | 8 +-
.../org/apache/brooklyn/config/ConfigMap.java | 103 ++++--
.../brooklyn/config/ConfigValueAtContainer.java | 17 +-
.../apache/brooklyn/config/StringConfigMap.java | 10 +
.../util/exceptions/ReferenceWithError.java | 14 +-
54 files changed, 1097 insertions(+), 797 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/api/src/main/java/org/apache/brooklyn/api/objs/Configurable.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/objs/Configurable.java b/api/src/main/java/org/apache/brooklyn/api/objs/Configurable.java
index 02eee54..ea36c4d 100644
--- a/api/src/main/java/org/apache/brooklyn/api/objs/Configurable.java
+++ b/api/src/main/java/org/apache/brooklyn/api/objs/Configurable.java
@@ -18,11 +18,14 @@
*/
package org.apache.brooklyn.api.objs;
+import java.util.Set;
+
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
import com.google.common.annotations.Beta;
+import com.google.common.base.Predicate;
/**
* Something that has mutable config, such as an entity or policy.
@@ -94,5 +97,7 @@ public interface Configurable {
* @see {@link #setConfig(ConfigKey, Task)}
*/
<T> T set(HasConfigKey<T> key, Task<T> val);
+
+ Set<ConfigKey<?>> findKeys(Predicate<ConfigKey<?>> predicate);
}
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
index 2f7c643..ccf18c0 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
@@ -46,6 +46,7 @@ import org.apache.brooklyn.camp.spi.ApplicationComponentTemplate;
import org.apache.brooklyn.camp.spi.AssemblyTemplate;
import org.apache.brooklyn.camp.spi.PlatformComponentTemplate;
import org.apache.brooklyn.config.ConfigInheritance;
+import org.apache.brooklyn.config.ConfigInheritances;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.ConfigValueAtContainer;
import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
@@ -73,6 +74,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
+import com.google.common.base.Functions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
@@ -289,25 +291,27 @@ public class BrooklynComponentTemplateResolver {
Collection<FlagConfigKeyAndValueRecord> records = findAllFlagsAndConfigKeyValues(spec, bag);
Set<String> keyNamesUsed = new LinkedHashSet<String>();
for (FlagConfigKeyAndValueRecord r: records) {
- // run through flags *and* config keys (may be overkill, but...)
+ // flags and config keys tracked separately, look at each (may be overkill but it's what we've always done)
+ Function<Maybe<Object>, Maybe<Object>> rawConvFn = Functions.identity();
if (r.getFlagMaybeValue().isPresent()) {
final String flag = r.getFlagName();
final ConfigKey<Object> key = (ConfigKey<Object>) r.getConfigKey();
if (key==null) ConfigKeys.newConfigKey(Object.class, flag);
final Object ownValueF = new SpecialFlagsTransformer(loader, encounteredRegisteredTypeIds).apply(r.getFlagMaybeValue().get());
+ Function<EntitySpec<?>, Maybe<Object>> rawEvalFn = new Function<EntitySpec<?>,Maybe<Object>>() {
+ @Override
+ public Maybe<Object> apply(EntitySpec<?> input) {
+ return spec.getFlags().containsKey(flag) ? Maybe.of((Object)spec.getFlags().get(flag)) : Maybe.absent();
+ }
+ };
Iterable<? extends ConfigValueAtContainer<EntitySpec<?>,Object>> ckvi = MutableList.of(
- new LazyContainerAndKeyValue<EntitySpec<?>,Object>(key, null, new Function<EntitySpec<?>,Maybe<Object>>() {
- @Override
- public Maybe<Object> apply(EntitySpec<?> input) {
- return spec.getFlags().containsKey(flag) ? Maybe.of((Object)spec.getFlags().get(flag)) : Maybe.absent();
- }
- }));
+ new LazyContainerAndKeyValue<EntitySpec<?>,Object>(key, null, rawEvalFn, rawConvFn));
- ConfigValueAtContainer<EntitySpec<?>,Object> combinedVal = getDefaultConfigInheritance().resolveInheriting(
- key, Maybe.ofAllowingNull(ownValueF), null,
- ckvi.iterator(), InheritanceContext.TYPE_DEFINITION);
+ ConfigValueAtContainer<EntitySpec<?>,Object> combinedVal = ConfigInheritances.resolveInheriting(
+ null, key, Maybe.ofAllowingNull(ownValueF), Maybe.<Object>absent(),
+ ckvi.iterator(), InheritanceContext.TYPE_DEFINITION, getDefaultConfigInheritance()).getWithoutError();
spec.configure(flag, combinedVal.get());
keyNamesUsed.add(flag);
@@ -316,17 +320,19 @@ public class BrooklynComponentTemplateResolver {
if (r.getConfigKeyMaybeValue().isPresent()) {
final ConfigKey<Object> key = (ConfigKey<Object>) r.getConfigKey();
final Object ownValueF = new SpecialFlagsTransformer(loader, encounteredRegisteredTypeIds).apply(r.getConfigKeyMaybeValue().get());
+
+ Function<EntitySpec<?>, Maybe<Object>> rawEvalFn = new Function<EntitySpec<?>,Maybe<Object>>() {
+ @Override
+ public Maybe<Object> apply(EntitySpec<?> input) {
+ return spec.getConfig().containsKey(key) ? Maybe.of(spec.getConfig().get(key)) : Maybe.absent();
+ }
+ };
Iterable<? extends ConfigValueAtContainer<EntitySpec<?>,Object>> ckvi = MutableList.of(
- new LazyContainerAndKeyValue<EntitySpec<?>,Object>(key, null, new Function<EntitySpec<?>,Maybe<Object>>() {
- @Override
- public Maybe<Object> apply(EntitySpec<?> input) {
- return spec.getConfig().containsKey(key) ? Maybe.of(spec.getConfig().get(key)) : Maybe.absent();
- }
- }));
+ new LazyContainerAndKeyValue<EntitySpec<?>,Object>(key, null, rawEvalFn, rawConvFn));
- ConfigValueAtContainer<EntitySpec<?>,Object> combinedVal = getDefaultConfigInheritance().resolveInheriting(
- key, Maybe.ofAllowingNull(ownValueF), null,
- ckvi.iterator(), InheritanceContext.TYPE_DEFINITION);
+ ConfigValueAtContainer<EntitySpec<?>,Object> combinedVal = ConfigInheritances.resolveInheriting(
+ null, key, Maybe.ofAllowingNull(ownValueF), Maybe.<Object>absent(),
+ ckvi.iterator(), InheritanceContext.TYPE_DEFINITION, getDefaultConfigInheritance()).getWithoutError();
spec.configure(key, combinedVal.get());
keyNamesUsed.add(key.getName());
@@ -341,7 +347,7 @@ public class BrooklynComponentTemplateResolver {
continue;
}
ConfigKey<?> key = entry.getValue();
- if (!ConfigKeys.isKeyReinheritable(key, InheritanceContext.TYPE_DEFINITION)) {
+ if (!ConfigInheritances.isKeyReinheritable(key, InheritanceContext.TYPE_DEFINITION)) {
spec.removeConfig(key);
spec.removeFlag(key.getName());
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigInheritanceYamlTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigInheritanceYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigInheritanceYamlTest.java
index 349adae..9a71aed 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigInheritanceYamlTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigInheritanceYamlTest.java
@@ -32,7 +32,6 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.core.config.MapConfigKey;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityAsserts;
-import org.apache.brooklyn.core.entity.internal.EntityConfigMap;
import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
@@ -221,16 +220,9 @@ public class ConfigInheritanceYamlTest extends AbstractYamlTest {
ImmutableMap.of("mykey", "myval", "templateOptions", ImmutableMap.of("myOptionsKey", "myOptionsVal")));
}
- /**
- * TODO This hangs because the attributeWhenReady self-reference is resolved against the entity
- * looking up the config value (i.e. the child). Therefore it waits for the TestEntity to have
- * a value for that sensor, but this never happens. The way to avoid this is to explicitly set
- * the component that the attributeWhenReady should apply to (e.g. see {@link #testInheritsParentConfigTask()}.
- *
- * Do we want to just exclude this test? Or do we want to "fix" it? Which entity should the
- * attributeWhenReady apply to?
- */
- @Test(groups={"Broken", "WIP"}, enabled=false)
+ // Fixed Sept 2016, attributeWhenReady self-reference is now resolved against the entity defining the config value.
+ // Prior to this it was resolved against the caller's scope.
+ @Test
public void testInheritsParentConfigTaskWithSelfScope() throws Exception {
String yaml = Joiner.on("\n").join(
"services:",
@@ -758,12 +750,8 @@ public class ConfigInheritanceYamlTest extends AbstractYamlTest {
ImmutableMap.of("mykey1", "myval1", "mykey2", "myval2", "mykey3", "myval3"));
}
- /**
- * TODO Has always failed, and probably hard to fix?! This is due to the way
- * {@link EntityConfigMap#setInheritedConfig(Map, org.apache.brooklyn.util.core.config.ConfigBag)} works:
- * the parent overrides the grandparent's config. So we only get mykey2+mykey3.
- */
- @Test(groups={"Broken", "WIP"})
+ // Fixed Sept 2016, inheritance is now computed with respect to defined keys and propagated upwards when traversing ancestors
+ @Test
public void testExtendsParentMultipleLevels() throws Exception {
addCatalogItems(
"brooklyn.catalog:",
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java
index c372a72..f1ea8eb 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ObjectsYamlTest.java
@@ -21,6 +21,7 @@ package org.apache.brooklyn.camp.brooklyn;
import static org.testng.Assert.assertEquals;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.brooklyn.api.entity.Entity;
@@ -33,6 +34,7 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
@@ -42,6 +44,8 @@ import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.common.base.Charsets;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.hash.HashCode;
import com.google.common.hash.Hashing;
@@ -182,6 +186,11 @@ public class ObjectsYamlTest extends AbstractYamlTest {
public <T> T set(HasConfigKey<T> key, Task<T> val) {
return set(key.getConfigKey(), val);
}
+
+ @Override
+ public Set<ConfigKey<?>> findKeys(Predicate<ConfigKey<?>> predicate) {
+ return MutableSet.copyOf(Iterables.filter(bag.getAllConfigAsConfigKeyMap().keySet(), predicate));
+ }
}
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/core/src/main/java/org/apache/brooklyn/core/config/BasicConfigInheritance.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/config/BasicConfigInheritance.java b/core/src/main/java/org/apache/brooklyn/core/config/BasicConfigInheritance.java
index edd8550..2ed7d48 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/BasicConfigInheritance.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/BasicConfigInheritance.java
@@ -18,45 +18,43 @@
*/
package org.apache.brooklyn.core.config;
-import java.util.Iterator;
import java.util.Map;
-import java.util.NoSuchElementException;
-
-import javax.annotation.Nullable;
import org.apache.brooklyn.config.ConfigInheritance;
+import org.apache.brooklyn.config.ConfigInheritances;
+import org.apache.brooklyn.config.ConfigInheritances.BasicConfigValueAtContainer;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.ConfigValueAtContainer;
-import org.apache.brooklyn.core.config.internal.BasicConfigValueAtContainer;
-import org.apache.brooklyn.core.config.internal.LazyContainerAndKeyValue;
import org.apache.brooklyn.util.collections.CollectionMerger;
+import org.apache.brooklyn.util.exceptions.ReferenceWithError;
import org.apache.brooklyn.util.guava.Maybe;
-import com.google.common.base.Function;
-
public class BasicConfigInheritance implements ConfigInheritance {
private static final long serialVersionUID = -5916548049057961051L;
+ public static final String CONFLICT_RESOLUTION_STRATEGY_DEEP_MERGE = "deep_merge";
+ public static final String CONFLICT_RESOLUTION_STRATEGY_OVERWRITE = "overwrite";
+
/** Indicates that a config key value should not be passed down from a container where it is defined.
* Unlike {@link #NEVER_INHERITED} these values can be passed down if set as anonymous keys at a container
* (ie the container does not expect it) to a container which does expect it, but it will not be passed down further.
* If the inheritor also defines a value the parent's value is ignored irrespective
* (as in {@link #OVERWRITE}; see {@link #NOT_REINHERITED_ELSE_DEEP_MERGE} if merging is desired). */
- public static BasicConfigInheritance NOT_REINHERITED = new BasicConfigInheritance(false,"overwrite",false);
+ public static BasicConfigInheritance NOT_REINHERITED = new BasicConfigInheritance(false,CONFLICT_RESOLUTION_STRATEGY_OVERWRITE,false);
/** As {@link #NOT_REINHERITED} but in cases where a value is inherited because a parent did not recognize it,
* if the inheritor also defines a value the two values should be merged. */
- public static BasicConfigInheritance NOT_REINHERITED_ELSE_DEEP_MERGE = new BasicConfigInheritance(false,"deep_merge",false);
+ public static BasicConfigInheritance NOT_REINHERITED_ELSE_DEEP_MERGE = new BasicConfigInheritance(false,CONFLICT_RESOLUTION_STRATEGY_DEEP_MERGE,false);
/** Indicates that a key's value should never be inherited, even if defined on a container that does not know the key.
* Most usages will prefer {@link #NOT_REINHERITED}. */
- public static BasicConfigInheritance NEVER_INHERITED = new BasicConfigInheritance(false,"overwrite",true);
+ public static BasicConfigInheritance NEVER_INHERITED = new BasicConfigInheritance(false,CONFLICT_RESOLUTION_STRATEGY_OVERWRITE,true);
/** Indicates that if a key has a value at both an ancestor and a descendant, the descendant and his descendants
* will prefer the value at the descendant. */
- public static BasicConfigInheritance OVERWRITE = new BasicConfigInheritance(true,"overwrite",false);
+ public static BasicConfigInheritance OVERWRITE = new BasicConfigInheritance(true,CONFLICT_RESOLUTION_STRATEGY_OVERWRITE,false);
/** Indicates that if a key has a value at both an ancestor and a descendant, the descendant and his descendants
* should attempt to merge the values. If the values are not mergable behaviour is undefined
* (and often the descendant's value will simply overwrite). */
- public static BasicConfigInheritance DEEP_MERGE = new BasicConfigInheritance(true,"deep_merge",false);
+ public static BasicConfigInheritance DEEP_MERGE = new BasicConfigInheritance(true,CONFLICT_RESOLUTION_STRATEGY_DEEP_MERGE,false);
// reinheritable? true/false; if false, children/descendants/inheritors will never see it; default true
protected final boolean isReinherited;
@@ -80,118 +78,89 @@ public class BasicConfigInheritance implements ConfigInheritance {
return null;
}
+
@Override
- public <TContainer,TValue> ConfigValueAtContainer<TContainer,TValue> resolveInheriting(
- @Nullable ConfigKey<TValue> key, Maybe<TValue> localValue, TContainer container,
- Iterator<? extends ConfigValueAtContainer<TContainer,TValue>> ancestorContainerKeyValues, ConfigInheritanceContext context) {
- ConfigInheritance inh = key==null ? null : key.getInheritanceByContext(context);
- if (inh==null) inh = this;
- if (inh!=this) return inh.resolveInheriting(key, localValue, container, ancestorContainerKeyValues, context);
-
- ConfigValueAtContainer<TContainer,TValue> v2 = null;
- if (OVERWRITE.conflictResolutionStrategy.equals(conflictResolutionStrategy) &&
- (localValue.isPresent() || useLocalDefaultValue)) {
- // don't inherit
- } else if (ancestorContainerKeyValues==null || !ancestorContainerKeyValues.hasNext()) {
- // nothing to inherit
- } else {
- // check whether parent allows us to get inherited value
- ConfigValueAtContainer<TContainer,TValue> c = ancestorContainerKeyValues.next();
- ConfigInheritance inh2 = c.getKey()==null ? null : c.getKey().getInheritanceByContext(context);
- if (inh2!=null && !ConfigKeys.isKeyReinheritable(c.getKey(), context)) {
- // can't inherit
- } else {
- // get inherited value
- if (inh2==null) inh2=this;
- v2 = inh2.resolveInheriting(c.getKey()!=null ? c.getKey() : null,
- c.isValueExplicitlySet() ? c.asMaybe() : Maybe.<TValue>absent(), c.getContainer(),
- ancestorContainerKeyValues, context);
- }
+ public <TContainer, TValue> boolean isReinheritable(ConfigValueAtContainer<TContainer, TValue> parent, ConfigInheritanceContext context) {
+ if (!equals(ConfigInheritances.findInheritance(parent, context, this)))
+ throw new IllegalStateException("Method can only be invoked on inheritance at "+parent);
+ return isReinherited();
+ }
+
+ @Override
+ public <TContainer,TValue> boolean considerParent(
+ ConfigValueAtContainer<TContainer,TValue> local,
+ ConfigValueAtContainer<TContainer,TValue> parent,
+ ConfigInheritanceContext context) {
+ if (!equals(ConfigInheritances.findInheritance(local, context, this)))
+ throw new IllegalStateException("Method can only be invoked on inheritance at "+local);
+ if (parent==null) return false;
+ if (CONFLICT_RESOLUTION_STRATEGY_OVERWRITE.equals(conflictResolutionStrategy)) {
+ // overwrite means ignore if there's an explicit value, or we're using the local default
+ return !local.isValueExplicitlySet() && !getUseLocalDefaultValue();
}
+ return true;
+ }
- BasicConfigValueAtContainer<TContainer,TValue> v = new BasicConfigValueAtContainer<TContainer,TValue>();
- v.setContainer(container);
- v.setKey(key);
+ @Override
+ public <TContainer,TValue> ReferenceWithError<ConfigValueAtContainer<TContainer,TValue>> resolveWithParent(
+ ConfigValueAtContainer<TContainer,TValue> local,
+ ConfigValueAtContainer<TContainer,TValue> parent,
+ ConfigInheritanceContext context) {
- Maybe<TValue> localValueOrConflictableDefault = localValue.isPresent() ? localValue :
- useLocalDefaultValue ? v.getDefaultValueMaybe() : Maybe.<TValue>absent();
- if (v2!=null && v2.isValueExplicitlySet() && !localValueOrConflictableDefault.isPresent()) return v2;
- if (v2==null || !v2.isValueExplicitlySet()) {
- v.setValueWasExplicitlySet(localValue.isPresent());
- v.setValue(v.isValueExplicitlySet() ? localValue : v.getDefaultValueMaybe());
- } else {
- v.setValue(resolveConflict(key, localValue, v2.asMaybe()));
- v.setValueWasExplicitlySet(true);
+ if (!parent.isValueExplicitlySet() && !getUseLocalDefaultValue())
+ return ReferenceWithError.newInstanceWithoutError(new BasicConfigValueAtContainer<TContainer,TValue>(local));
+
+ // parent explicitly set (or we might have to merge defaults),
+ // and by the contract of this method we can assume reinheritable
+ if (!local.isValueExplicitlySet() && !getUseLocalDefaultValue())
+ return ReferenceWithError.newInstanceWithoutError(new BasicConfigValueAtContainer<TContainer,TValue>(parent));
+
+ // both explicitly set or defaults applicable, and not overwriting; it should be merge
+ if (CONFLICT_RESOLUTION_STRATEGY_DEEP_MERGE.equals(conflictResolutionStrategy)) {
+ BasicConfigValueAtContainer<TContainer, TValue> result = new BasicConfigValueAtContainer<TContainer,TValue>(local);
+ ReferenceWithError<Maybe<? extends TValue>> resolvedValue = deepMerge(
+ local.isValueExplicitlySet() ? local.asMaybe() : local.getDefaultValue(),
+ parent.isValueExplicitlySet() ? parent.asMaybe() : parent.getDefaultValue());
+ result.setValue(resolvedValue.getWithoutError());
+ return ReferenceWithError.newInstanceThrowingError(result, resolvedValue.getError());
}
- return v;
+
+ return resolveWithParentCustomStrategy(local, parent, context);
}
- /** only invoked if there is an ancestor value; custom strategies can overwrite */
- protected <T> Maybe<T> resolveConflict(ConfigKey<T> key, Maybe<T> localValue, Maybe<T> ancestorValue) {
- if (OVERWRITE.conflictResolutionStrategy.equals(conflictResolutionStrategy)) {
- if (localValue.isPresent()) return localValue;
- if (useLocalDefaultValue) return (key==null || !key.hasDefaultValue()) ? Maybe.<T>absent() : Maybe.ofAllowingNull(key.getDefaultValue());
- return ancestorValue;
- }
- if (DEEP_MERGE.conflictResolutionStrategy.equals(conflictResolutionStrategy)) {
- localValue = localValue.isPresent() ? localValue :
- useLocalDefaultValue && key!=null && key.hasDefaultValue() ? Maybe.ofAllowingNull(key.getDefaultValue()) :
- Maybe.<T>absent();
- @SuppressWarnings("unchecked")
- Maybe<T> result = (Maybe<T>) deepMerge(localValue, ancestorValue);
- return result;
- }
- throw new IllegalStateException("Unknown config conflict resolution strategy '"+conflictResolutionStrategy+"' evaluating "+key);
+
+ protected <TContainer, TValue> ReferenceWithError<ConfigValueAtContainer<TContainer, TValue>> resolveWithParentCustomStrategy(
+ ConfigValueAtContainer<TContainer, TValue> local, ConfigValueAtContainer<TContainer, TValue> parent,
+ ConfigInheritanceContext context) {
+ throw new IllegalStateException("Unknown config conflict resolution strategy '"+conflictResolutionStrategy+"' evaluating "+local+"/"+parent);
}
- private static <T> Maybe<? extends T> deepMerge(Maybe<? extends T> val1, Maybe<? extends T> val2) {
+
+ private static <T> ReferenceWithError<Maybe<? extends T>> deepMerge(Maybe<? extends T> val1, Maybe<? extends T> val2) {
if (val2.isAbsent() || val2.isNull()) {
- return val1;
+ return ReferenceWithError.newInstanceWithoutError(val1);
} else if (val1.isAbsent()) {
- return val2;
+ return ReferenceWithError.newInstanceWithoutError(val2);
} else if (val1.isNull()) {
- return val1; // an explicit null means an override; don't merge
+ return ReferenceWithError.newInstanceWithoutError(val1); // an explicit null means an override; don't merge
} else if (val1.get() instanceof Map && val2.get() instanceof Map) {
@SuppressWarnings({ "unchecked", "rawtypes" })
Maybe<T> result = (Maybe)Maybe.of(CollectionMerger.builder().build().merge((Map<?,?>)val1.get(), (Map<?,?>)val2.get()));
- return result;
+ return ReferenceWithError.newInstanceWithoutError(result);
} else {
// cannot merge; just return val1
- return val1;
+ return ReferenceWithError.newInstanceThrowingError(val1, new IllegalArgumentException("Cannot merge '"+val1.get()+"' and '"+val2.get()+"'"));
}
}
-
- public static class AncestorContainerAndKeyValueIterator<TContainer,TValue> implements Iterator<ConfigValueAtContainer<TContainer,TValue>> {
- private TContainer lastContainer;
- private final Function<TContainer, ConfigKey<TValue>> keyFindingFunction;
- private final Function<TContainer, Maybe<TValue>> localEvaluationFunction;
- private final Function<TContainer, TContainer> parentFunction;
-
- public AncestorContainerAndKeyValueIterator(TContainer childContainer,
- Function<TContainer, ConfigKey<TValue>> keyFindingFunction,
- Function<TContainer, Maybe<TValue>> localEvaluationFunction,
- Function<TContainer, TContainer> parentFunction) {
- this.lastContainer = childContainer;
- this.keyFindingFunction = keyFindingFunction;
- this.localEvaluationFunction = localEvaluationFunction;
- this.parentFunction = parentFunction;
- }
-
- @Override
- public boolean hasNext() {
- return parentFunction.apply(lastContainer)!=null;
- }
-
- @Override
- public ConfigValueAtContainer<TContainer,TValue> next() {
- TContainer nextContainer = parentFunction.apply(lastContainer);
- if (nextContainer==null) throw new NoSuchElementException("Cannot search ancestors further than "+lastContainer);
- lastContainer = nextContainer;
- return new LazyContainerAndKeyValue<TContainer,TValue>(keyFindingFunction.apply(lastContainer), lastContainer, localEvaluationFunction);
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("This iterator does not support removal");
- }
+
+ public boolean isReinherited() {
+ return isReinherited;
+ }
+
+ public String getConflictResolutionStrategy() {
+ return conflictResolutionStrategy;
+ }
+
+ public boolean getUseLocalDefaultValue() {
+ return useLocalDefaultValue;
}
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java b/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
index 2743b80..6359907 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
@@ -22,26 +22,20 @@ import java.util.Map;
import javax.annotation.Nonnull;
-import org.apache.brooklyn.config.ConfigInheritance;
import org.apache.brooklyn.config.ConfigInheritance.ConfigInheritanceContext;
import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.config.ConfigValueAtContainer;
import org.apache.brooklyn.core.config.BasicConfigKey.BasicConfigKeyOverwriting;
-import org.apache.brooklyn.core.config.internal.LazyContainerAndKeyValue;
import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.core.sensor.TemplatedStringAttributeSensorAndConfigKey;
-import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.text.Strings;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.CaseFormat;
-import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.reflect.TypeToken;
@@ -289,35 +283,4 @@ public class ConfigKeys {
}
- /** determine whether a key is reinheritable from the point in the given inheritance hierarchy where it is introduced;
- * default is true, but some keys may define not being reinherited or may have that effective result
- * <p>
- * note that this does not mean a value should never be *inherited*;
- * callers should query with the key defined at a given point in a hierarchy,
- * so if a key is not defined at some point in the hierarchy
- * (eg not on a type in the type hierarchy, or not an an entity in the runtime management hierarchy)
- * then null should be passed and values will be reinheritable */
- public static <T> boolean isKeyReinheritable(final ConfigKey<T> key, final ConfigInheritanceContext context) {
- if (key==null) return true;
- ConfigInheritance inh = key.getInheritanceByContext(context);
- if (inh==null) return true;
- if (inh instanceof BasicConfigInheritance) {
- return ((BasicConfigInheritance)inh).isReinherited;
- }
-
- // evaluate by faking a parent who sets a value and seeing if it's reinherited
- Iterable<? extends ConfigValueAtContainer<Void,T>> ckvi = MutableList.of(
- new LazyContainerAndKeyValue<Void,T>(key, null, new Function<Void,Maybe<T>>() {
- @Override
- public Maybe<T> apply(Void input) {
- return Maybe.ofAllowingNull(null);
- }
- }));
-
- ConfigValueAtContainer<Void,T> combinedVal = BasicConfigInheritance.OVERWRITE.resolveInheriting(
- key, Maybe.<T>absent(), null,
- ckvi.iterator(), InheritanceContext.TYPE_DEFINITION);
- return combinedVal.isValueExplicitlySet();
- }
-
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/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 6c31b97..e964d24 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
@@ -20,31 +20,46 @@ package org.apache.brooklyn.core.config.internal;
import java.util.Collections;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Future;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
import org.apache.brooklyn.api.mgmt.ExecutionContext;
import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.config.ConfigInheritance;
+import org.apache.brooklyn.config.ConfigInheritances;
+import org.apache.brooklyn.config.ConfigInheritances.BasicConfigValueAtContainer;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
-import org.apache.brooklyn.config.ConfigMap;
+import org.apache.brooklyn.config.ConfigMap.ConfigMapWithInheritance;
+import org.apache.brooklyn.config.ConfigValueAtContainer;
+import org.apache.brooklyn.core.config.BasicConfigInheritance;
import org.apache.brooklyn.core.config.ConfigKeys;
+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.entity.internal.ConfigMapViewWithStringKeys;
import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
+import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.collections.MutableSet;
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.exceptions.ReferenceWithError;
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;
+import com.google.common.collect.Iterables;
-public abstract class AbstractConfigMapImpl implements ConfigMap {
+public abstract class AbstractConfigMapImpl<TContainer extends BrooklynObject> implements ConfigMapWithInheritance<TContainer> {
/*
* Changed Sept 2016 so that keys can determine inheritance strategy at every level in the hierarchy,
@@ -53,9 +68,10 @@ public abstract class AbstractConfigMapImpl implements ConfigMap {
private static final Logger LOG = LoggerFactory.getLogger(AbstractConfigMapImpl.class);
- protected final ConfigMapViewWithStringKeys mapViewWithStringKeys = new ConfigMapViewWithStringKeys(this);
+ @SuppressWarnings("deprecation")
+ protected final transient org.apache.brooklyn.core.entity.internal.ConfigMapViewWithStringKeys mapViewWithStringKeys = new org.apache.brooklyn.core.entity.internal.ConfigMapViewWithStringKeys(this);
- protected BrooklynObjectInternal bo;
+ protected TContainer bo;
/**
* Map of configuration information that is defined at start-up time for the entity. These
@@ -64,27 +80,30 @@ public abstract class AbstractConfigMapImpl implements ConfigMap {
*/
protected final Map<ConfigKey<?>,Object> ownConfig;
- protected AbstractConfigMapImpl(BrooklynObject bo) {
+ protected AbstractConfigMapImpl(TContainer 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;
+ protected AbstractConfigMapImpl(TContainer bo, Map<ConfigKey<?>, Object> storage) {
+ this.bo = bo;
this.ownConfig = storage;
}
- public BrooklynObjectInternal getBrooklynObject() {
+ public TContainer getContainer() {
return bo;
}
+ protected final BrooklynObjectInternal getBrooklynObject() {
+ return (BrooklynObjectInternal)bo;
+ }
+
public <T> T getConfig(ConfigKey<T> key) {
- return getConfigImpl(key).orNull();
+ return getConfigImpl(key, false).getWithoutError().get();
}
-
public <T> T getConfig(HasConfigKey<T> key) {
- return getConfigImpl(key.getConfigKey()).orNull();
+ return getConfigImpl(key.getConfigKey(), false).getWithoutError().get();
}
@Override
@@ -92,58 +111,38 @@ public abstract class AbstractConfigMapImpl implements ConfigMap {
return getConfigRaw(key, false);
}
- protected abstract <T> Maybe<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;
- }
+ @Override
+ public Map<ConfigKey<?>,Object> getAllConfigLocalRaw() {
+ Map<ConfigKey<?>,Object> result = new LinkedHashMap<ConfigKey<?>,Object>();
+ 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());
+ /** an immutable copy of the config visible at this entity, local and inherited (preferring local) */
+ @Override @Deprecated
+ public Map<ConfigKey<?>,Object> getAllConfig() {
+ Map<ConfigKey<?>,Object> result = new LinkedHashMap<ConfigKey<?>,Object>();
+ if (getParent()!=null)
+ result.putAll( getParentInternal().config().getInternalConfigMap().getAllConfig() );
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 */
+
+ /** Creates an immutable copy of the config visible at this entity, local and inherited (preferring local), including those that did not match config keys */
+ @Deprecated
+ public ConfigBag getAllConfigBag() {
+ ConfigBag result = ConfigBag.newInstance().putAll(ownConfig);
+ if (getParent()!=null) {
+ result.putIfAbsent(
+ ((AbstractConfigMapImpl<?>)getParentInternal().config().getInternalConfigMap()).getAllConfigBag() );
+ }
+ return result.seal();
+ }
+
+ /** As {@link #getLocalConfigRaw()} but in a {@link ConfigBag} for convenience */
public ConfigBag getLocalConfigBag() {
return ConfigBag.newInstance().putAll(ownConfig).seal();
}
@@ -170,7 +169,7 @@ public abstract class AbstractConfigMapImpl implements ConfigMap {
}
@SuppressWarnings("unchecked")
- public void addToLocalBag(Map<?,?> vals) {
+ public void putAll(Map<?,?> vals) {
// ConfigBag ownConfigBag = ConfigBag.newInstance().putAll(vals);
// ownConfig.putAll(ownConfigBag.getAllConfigAsConfigKeyMap());
// below seems more straightforward; should be the same.
@@ -188,45 +187,30 @@ public abstract class AbstractConfigMapImpl implements ConfigMap {
}
}
- public void removeFromLocalBag(String key) {
- // previously removed the string (?)
+ public void removeKey(String key) {
ownConfig.remove(ConfigKeys.newConfigKey(Object.class, key));
}
- public void removeFromLocalBag(ConfigKey<?> key) {
+ public void removeKey(ConfigKey<?> key) {
ownConfig.remove(key);
}
- protected abstract BrooklynObjectInternal getParent();
-
- @Override
+ protected final TContainer getParent() {
+ return getParentOfContainer(getContainer());
+ }
+
+ protected final BrooklynObjectInternal getParentInternal() {
+ return (BrooklynObjectInternal) getParent();
+ }
+
+ @Override @Deprecated
public Maybe<Object> getConfigRaw(ConfigKey<?> key, boolean includeInherited) {
- // TODO does not currently respect inheritance modes
+ // 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);
+ return getParentInternal().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) {
if ((v instanceof Future) || (v instanceof DeferredSupplier)) {
// no coercion for these (coerce on exit)
@@ -269,6 +253,219 @@ public abstract class AbstractConfigMapImpl implements ConfigMap {
return ownConfig.isEmpty();
}
+ protected ConfigInheritance getDefaultRuntimeInheritance() {
+ return BasicConfigInheritance.OVERWRITE;
+ }
+
+ public <T> ReferenceWithError<ConfigValueAtContainer<TContainer,T>> getConfigAndContainer(ConfigKey<T> key) {
+ return getConfigImpl(key, false);
+ }
+
+ protected abstract TContainer getParentOfContainer(TContainer container);
+
+ @Nullable protected final <T> ConfigKey<T> getKeyAtContainer(TContainer container, ConfigKey<T> queryKey) {
+ if (container==null) return null;
+ @SuppressWarnings("unchecked")
+ ConfigKey<T> candidate = (ConfigKey<T>) getKeyAtContainerImpl(container, queryKey);
+ return candidate;
+ }
+
+ @Nullable protected abstract <T> ConfigKey<?> getKeyAtContainerImpl(@Nonnull TContainer container, ConfigKey<T> queryKey);
+
+ protected Maybe<Object> getRawValueAtContainer(TContainer container, ConfigKey<? extends Object> configKey) {
+ return ((BrooklynObjectInternal)container).config().getInternalConfigMap().getConfigLocalRaw(configKey);
+ }
+ protected Maybe<Object> resolveRawValueFromContainer(TContainer container, ConfigKey<?> key, Object value) {
+ Map<ConfigKey<?>, Object> oc = ((AbstractConfigMapImpl<?>) ((BrooklynObjectInternal)container).config().getInternalConfigMap()).ownConfig;
+ if (key instanceof ConfigKeySelfExtracting) {
+ if (((ConfigKeySelfExtracting<?>)key).isSet(oc)) {
+ Map<ConfigKey<?>, ?> ownCopy;
+ synchronized (oc) {
+ // wasteful to make a copy to look up; maybe try once opportunistically?
+ ownCopy = MutableMap.copyOf(oc);
+ }
+ return Maybe.of((Object) ((ConfigKeySelfExtracting<?>) key).extractValue(ownCopy, getExecutionContext(container)) );
+ } else {
+ return Maybe.absent();
+ }
+ } else {
+ // all our keys are self-extracting
+ LOG.warn("Unexpected key type "+key+" ("+key.getClass()+") in "+bo+"; ignoring value");
+ return Maybe.absent();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected <T> T coerce(Object value, Class<T> type) {
+ if (type==null || value==null) return (T) value;
+ return (T) TypeCoercions.coerce(value, type);
+ }
+
+ protected <T> ReferenceWithError<ConfigValueAtContainer<TContainer,T>> getConfigImpl(final ConfigKey<T> queryKey, final boolean raw) {
+ // In case this entity class has overridden the given key (e.g. to set default), then retrieve this entity's key
+ Function<TContainer, ConfigKey<T>> keyFn = new Function<TContainer, ConfigKey<T>>() {
+ @Override public ConfigKey<T> apply(TContainer input) {
+ // should return null if the key is not known, to indicate selected inheritance rules from base key should take effect
+ return getKeyAtContainer(input, queryKey);
+ }
+ };
+ ConfigKey<T> ownKey = keyFn.apply(getContainer());
+ if (ownKey==null) ownKey = queryKey;
+ @SuppressWarnings("unchecked")
+ final Class<T> type = (Class<T>) ownKey.getType();
+
+ // takes type of own key (or query key if own key not available)
+ // takes default of own key if available and has default, else of query key
+
+ Function<Maybe<Object>, Maybe<T>> coerceFn = new Function<Maybe<Object>, Maybe<T>>() {
+ @SuppressWarnings("unchecked") @Override public Maybe<T> apply(Maybe<Object> input) {
+ if (raw || input==null || input.isAbsent()) return (Maybe<T>)input;
+ return Maybe.ofAllowingNull(coerce(input.get(), type));
+ }
+ };
+ // prefer default and type of ownKey
+ Maybe<T> defaultValue = raw ? Maybe.<T>absent() :
+ ownKey.hasDefaultValue() ? coerceFn.apply(Maybe.of((Object)ownKey.getDefaultValue())) :
+ queryKey.hasDefaultValue() ? coerceFn.apply(Maybe.of((Object)queryKey.getDefaultValue())) :
+ Maybe.<T>absent();
+
+ if (ownKey instanceof ConfigKeySelfExtracting) {
+
+ Function<TContainer, Maybe<Object>> lookupFn = new Function<TContainer, Maybe<Object>>() {
+ @Override public Maybe<Object> apply(TContainer input) {
+ Maybe<Object> result = getRawValueAtContainer(input, queryKey);
+ if (!raw) result = resolveRawValueFromContainer(input, queryKey, result);
+ return result;
+ }
+ };
+ Function<TContainer, TContainer> parentFn = new Function<TContainer, TContainer>() {
+ @Override public TContainer apply(TContainer input) {
+ return getParentOfContainer(input);
+ }
+ };
+ AncestorContainerAndKeyValueIterator<TContainer, T> ckvi = new AncestorContainerAndKeyValueIterator<TContainer,T>(
+ getContainer(), keyFn, lookupFn, coerceFn, parentFn);
+
+ return ConfigInheritances.resolveInheriting(
+ getContainer(), ownKey, coerceFn.apply(lookupFn.apply(getContainer())), defaultValue,
+ ckvi, InheritanceContext.RUNTIME_MANAGEMENT, getDefaultRuntimeInheritance());
+
+ } else {
+ String message = "Config key "+ownKey+" of "+getBrooklynObject()+" is not a ConfigKeySelfExtracting; cannot retrieve value; returning default";
+ LOG.warn(message);
+ return ReferenceWithError.newInstanceThrowingError(new BasicConfigValueAtContainer<TContainer,T>(getContainer(), ownKey, null, false,
+ defaultValue),
+ new IllegalStateException(message));
+ }
+ }
+
+ public List<ConfigValueAtContainer<TContainer,?>> getConfigAllInheritedRaw(ConfigKey<?> queryKey) {
+ List<ConfigValueAtContainer<TContainer, ?>> result = MutableList.of();
+ TContainer c = getContainer();
+ int count=0;
+
+ final InheritanceContext context = InheritanceContext.RUNTIME_MANAGEMENT;
+ ConfigInheritance currentInheritance = ConfigInheritances.findInheritance(queryKey, context, getDefaultRuntimeInheritance());
+
+ BasicConfigValueAtContainer<TContainer, Object> last = null;
+
+ while (c!=null) {
+ Maybe<Object> v = getRawValueAtContainer(c, queryKey);
+ BasicConfigValueAtContainer<TContainer, Object> next = new BasicConfigValueAtContainer<TContainer, Object>(c, getKeyAtContainer(c, queryKey), v);
+
+ if (last!=null && !currentInheritance.considerParent(last, next, context)) break;
+
+ currentInheritance = ConfigInheritances.findInheritance(next.getKey(), InheritanceContext.RUNTIME_MANAGEMENT, currentInheritance);
+ if (count>0 && !currentInheritance.isReinheritable(next, context)) break;
+
+ if (next.isValueExplicitlySet()) result.add(0, next);
+
+ last = next;
+ c = getParentOfContainer(c);
+ }
+
+ return result;
+ }
+
+ @Override
+ public Set<ConfigKey<?>> findKeys(Predicate<ConfigKey<?>> filter) {
+ MutableSet<ConfigKey<?>> result = MutableSet.of();
+ result.addAll(Iterables.filter(ownConfig.keySet(), filter));
+ // due to set semantics local should be added first, it prevents equal items from parent from being added on top
+ if (getParent()!=null) {
+ result.addAll( getParentInternal().config().getInternalConfigMap().findKeys(filter) );
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ public ReferenceWithError<ConfigValueAtContainer<TContainer,?>> getConfigInheritedRaw(ConfigKey<?> key) {
+ return (ReferenceWithError<ConfigValueAtContainer<TContainer,?>>) (ReferenceWithError<?>) getConfigImpl(key, true);
+ }
+
+ @Override
+ public Map<ConfigKey<?>, Object> getAllConfigInheritedRawValuesIgnoringErrors() {
+ Map<ConfigKey<?>, ReferenceWithError<ConfigValueAtContainer<TContainer, ?>>> input = getAllConfigInheritedRawWithErrors();
+ Map<ConfigKey<?>, Object> result = MutableMap.of();
+ for (Map.Entry<ConfigKey<?>, ReferenceWithError<ConfigValueAtContainer<TContainer, ?>>> pair: input.entrySet()) {
+ result.put(pair.getKey(), pair.getValue().getWithoutError().get());
+ }
+ return result;
+ }
+ @Override
+ public Map<ConfigKey<?>, ReferenceWithError<ConfigValueAtContainer<TContainer, ?>>> getAllConfigInheritedRawWithErrors() {
+ return getSelectedConfigInheritedRaw(false);
+ }
+
+ public Map<ConfigKey<?>,ReferenceWithError<ConfigValueAtContainer<TContainer,?>>> getAllReinheritableConfigRaw() {
+ return getSelectedConfigInheritedRaw(true);
+ }
+
+ protected Map<ConfigKey<?>,ReferenceWithError<ConfigValueAtContainer<TContainer,?>>> getSelectedConfigInheritedRaw(boolean onlyReinheritable) {
+ Map<ConfigKey<?>,ReferenceWithError<ConfigValueAtContainer<TContainer,?>>> parents = MutableMap.of();
+ if (getParent()!=null) {
+ @SuppressWarnings("unchecked")
+ Map<ConfigKey<?>,ReferenceWithError<ConfigValueAtContainer<TContainer,?>>> po = (Map<ConfigKey<?>,ReferenceWithError<ConfigValueAtContainer<TContainer,?>>>) (Map<?,?>)
+ getParentInternal().config().getInternalConfigMap().getAllReinheritableConfigRaw();
+ parents.putAll(po);
+ }
+
+ Map<ConfigKey<?>, Object> local = getAllConfigLocalRaw();
+
+ Map<ConfigKey<?>,ReferenceWithError<ConfigValueAtContainer<TContainer,?>>> result = MutableMap.of();
+
+ for (ConfigKey<?> k: local.keySet()) {
+ Object v = local.get(k);
+ ReferenceWithError<ConfigValueAtContainer<TContainer, ?>> vpr = parents.remove(k);
+ @SuppressWarnings("unchecked")
+ ConfigValueAtContainer<TContainer, Object> vp = vpr==null ? null : (ConfigValueAtContainer<TContainer,Object>) vpr.getWithoutError();
+ ConfigInheritance inh = ConfigInheritances.findInheritance(k, InheritanceContext.RUNTIME_MANAGEMENT, getDefaultRuntimeInheritance());
+ ConfigValueAtContainer<TContainer,Object> vl = new BasicConfigValueAtContainer<TContainer,Object>(getContainer(), k, Maybe.ofAllowingNull(v));
+ ReferenceWithError<ConfigValueAtContainer<TContainer, Object>> vlr = null;
+ if (inh.considerParent(vl, vp, InheritanceContext.RUNTIME_MANAGEMENT)) {
+ vlr = inh.resolveWithParent(vl, vp, InheritanceContext.RUNTIME_MANAGEMENT);
+ } else {
+ // no need to consider parent, just take vl
+ vlr = ReferenceWithError.newInstanceWithoutError(vl);
+ }
+ if (onlyReinheritable) {
+ if (ConfigInheritances.findInheritance(k, InheritanceContext.RUNTIME_MANAGEMENT, getDefaultRuntimeInheritance())
+ .isReinheritable(vl, InheritanceContext.RUNTIME_MANAGEMENT)) {
+ // continue
+ } else {
+ // skip this one
+ continue;
+ }
+ }
+ @SuppressWarnings("unchecked")
+ ReferenceWithError<ConfigValueAtContainer<TContainer, ?>> vlro = (ReferenceWithError<ConfigValueAtContainer<TContainer, ?>>) (ReferenceWithError<?>) vlr;
+ result.put(k, vlro);
+ }
+ result.putAll(parents);
+
+ return result;
+ }
+
@Override
public String toString() {
Map<ConfigKey<?>, Object> sanitizeConfig;
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/core/src/main/java/org/apache/brooklyn/core/config/internal/AncestorContainerAndKeyValueIterator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/config/internal/AncestorContainerAndKeyValueIterator.java b/core/src/main/java/org/apache/brooklyn/core/config/internal/AncestorContainerAndKeyValueIterator.java
index 62fb970..f20f0d0 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/internal/AncestorContainerAndKeyValueIterator.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/internal/AncestorContainerAndKeyValueIterator.java
@@ -30,16 +30,19 @@ import com.google.common.base.Function;
public class AncestorContainerAndKeyValueIterator<TContainer,TValue> implements Iterator<ConfigValueAtContainer<TContainer,TValue>> {
private TContainer lastContainer;
private final Function<TContainer, ConfigKey<TValue>> keyFindingFunction;
- private final Function<TContainer, Maybe<TValue>> localEvaluationFunction;
+ private final Function<TContainer, Maybe<Object>> lookupResolutionFunction;
+ private final Function<Maybe<Object>, Maybe<TValue>> coercionFunction;
private final Function<TContainer, TContainer> parentFunction;
public AncestorContainerAndKeyValueIterator(TContainer childContainer,
Function<TContainer, ConfigKey<TValue>> keyFindingFunction,
- Function<TContainer, Maybe<TValue>> localEvaluationFunction,
+ Function<TContainer, Maybe<Object>> lookupResolutionFunction,
+ Function<Maybe<Object>, Maybe<TValue>> coercionFunction,
Function<TContainer, TContainer> parentFunction) {
this.lastContainer = childContainer;
this.keyFindingFunction = keyFindingFunction;
- this.localEvaluationFunction = localEvaluationFunction;
+ this.lookupResolutionFunction = lookupResolutionFunction;
+ this.coercionFunction = coercionFunction;
this.parentFunction = parentFunction;
}
@@ -53,7 +56,8 @@ public class AncestorContainerAndKeyValueIterator<TContainer,TValue> implements
TContainer nextContainer = parentFunction.apply(lastContainer);
if (nextContainer==null) throw new NoSuchElementException("Cannot search ancestors further than "+lastContainer);
lastContainer = nextContainer;
- return new LazyContainerAndKeyValue<TContainer,TValue>(keyFindingFunction.apply(lastContainer), lastContainer, localEvaluationFunction);
+ return new LazyContainerAndKeyValue<TContainer,TValue>(keyFindingFunction.apply(lastContainer), lastContainer,
+ lookupResolutionFunction, coercionFunction);
}
@Override
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/core/src/main/java/org/apache/brooklyn/core/config/internal/BasicConfigValueAtContainer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/config/internal/BasicConfigValueAtContainer.java b/core/src/main/java/org/apache/brooklyn/core/config/internal/BasicConfigValueAtContainer.java
deleted file mode 100644
index 79041d4..0000000
--- a/core/src/main/java/org/apache/brooklyn/core/config/internal/BasicConfigValueAtContainer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.config.internal;
-
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.config.ConfigValueAtContainer;
-import org.apache.brooklyn.util.guava.Maybe;
-
-public class BasicConfigValueAtContainer<TContainer,TValue> implements ConfigValueAtContainer<TContainer,TValue> {
-
- TContainer container = null;
- Maybe<TValue> value = Maybe.absent();
- boolean valueWasExplicitlySet;
- ConfigKey<TValue> key = null;
-
- @Override public TContainer getContainer() { return container; }
- @Override public TValue get() { return value.orNull(); }
- @Override public Maybe<TValue> asMaybe() { return value; }
- @Override public boolean isValueExplicitlySet() { return valueWasExplicitlySet; }
- @Override public ConfigKey<TValue> getKey() { return key; }
- @Override public TValue getDefaultValue() { return getDefaultValueMaybe().orNull(); }
-
- public void setContainer(TContainer container) {
- this.container = container;
- }
- public void setValue(Maybe<TValue> value) {
- this.value = value;
- }
- public void setValueWasExplicitlySet(boolean valueWasExplicitlySet) {
- this.valueWasExplicitlySet = valueWasExplicitlySet;
- }
- public void setKey(ConfigKey<TValue> key) {
- this.key = key;
- }
-
- public Maybe<TValue> getDefaultValueMaybe() { return key!=null && key.hasDefaultValue() ? Maybe.ofAllowingNull(key.getDefaultValue()) : Maybe.<TValue>absent(); }
-
-}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/core/src/main/java/org/apache/brooklyn/core/config/internal/LazyContainerAndKeyValue.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/config/internal/LazyContainerAndKeyValue.java b/core/src/main/java/org/apache/brooklyn/core/config/internal/LazyContainerAndKeyValue.java
index df11735..fec13af 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/internal/LazyContainerAndKeyValue.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/internal/LazyContainerAndKeyValue.java
@@ -28,18 +28,23 @@ public class LazyContainerAndKeyValue<TContainer,TValue> implements ConfigValueA
private final TContainer container;
private final ConfigKey<TValue> key;
- private final Function<TContainer,Maybe<TValue>> evaluationFunction;
+ private final Function<TContainer,Maybe<Object>> lookupResolutionFunction;
+ private final Function<Maybe<Object>,Maybe<TValue>> conversionFunction;
private Maybe<TValue> resolved;
- public LazyContainerAndKeyValue(ConfigKey<TValue> key, TContainer container, Function<TContainer, Maybe<TValue>> evaluationFunction) {
+ public LazyContainerAndKeyValue(ConfigKey<TValue> key, TContainer container,
+ Function<TContainer, Maybe<Object>> lookupResolutionFunction,
+ Function<Maybe<Object>, Maybe<TValue>> conversionFunction) {
this.key = key;
this.container = container;
- this.evaluationFunction = evaluationFunction;
+ this.lookupResolutionFunction = lookupResolutionFunction;
+ this.conversionFunction = conversionFunction;
}
protected synchronized Maybe<TValue> resolve() {
if (resolved==null) {
- resolved = evaluationFunction.apply(getContainer());
+ resolved = conversionFunction.apply(
+ lookupResolutionFunction.apply(getContainer()));
}
return resolved;
}
@@ -52,13 +57,13 @@ public class LazyContainerAndKeyValue<TContainer,TValue> implements ConfigValueA
@Override
public TValue get() {
if (resolve().isPresent()) return resolve().get();
- return getDefaultValue();
+ return getDefaultValue().orNull();
}
@Override
public Maybe<TValue> asMaybe() {
if (resolve().isPresent()) return resolve();
- return getDefaultValueMaybe();
+ return getDefaultValue();
}
@Override
@@ -72,12 +77,8 @@ public class LazyContainerAndKeyValue<TContainer,TValue> implements ConfigValueA
}
@Override
- public TValue getDefaultValue() {
- return getDefaultValueMaybe().orNull();
- }
-
- public Maybe<TValue> getDefaultValueMaybe() {
+ public Maybe<TValue> getDefaultValue() {
if (key==null || !key.hasDefaultValue()) return Maybe.absent();
- return Maybe.of(key.getDefaultValue());
+ return conversionFunction.apply(Maybe.of((Object)key.getDefaultValue()));
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java b/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java
index 29c1480..1f46314 100644
--- a/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.core.effector.ssh;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.annotation.Nullable;
@@ -30,17 +31,16 @@ import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.StringConfigMap;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.ConfigPredicates;
import org.apache.brooklyn.core.config.ConfigUtils;
import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.effector.EffectorTasks;
import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory;
-import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.location.internal.LocationInternal;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.internal.ssh.SshTool;
import org.apache.brooklyn.util.core.task.Tasks;
@@ -53,7 +53,10 @@ import org.apache.brooklyn.util.core.task.ssh.internal.AbstractSshExecTaskFactor
import org.apache.brooklyn.util.core.task.ssh.internal.PlainSshExecTaskFactory;
import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.ssh.BashCommands;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
@@ -291,42 +294,42 @@ public class SshEffectorTasks {
* the SshTool is created or re-used by the SshMachineLocation making use of these properties */
@Beta
public static Map<String, Object> getSshFlags(Entity entity, Location optionalLocation) {
- ConfigBag allConfig = ConfigBag.newInstance();
+ Set<ConfigKey<?>> sshConfig = MutableSet.of();
- StringConfigMap globalConfig = ((EntityInternal)entity).getManagementContext().getConfig();
- allConfig.putAll(globalConfig.getAllConfig());
+ sshConfig.addAll(((EntityInternal)entity).config().findKeys(ConfigPredicates.nameStartsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)));
if (optionalLocation!=null)
- allConfig.putAll(((LocationInternal)optionalLocation).config().getBag());
+ sshConfig.addAll(optionalLocation.config().findKeys(ConfigPredicates.nameStartsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)));
- allConfig.putAll(((EntityInternal)entity).config().getBag());
+ StringConfigMap globalConfig = ((EntityInternal)entity).getManagementContext().getConfig();
+ sshConfig.addAll(globalConfig.findKeys(ConfigPredicates.nameStartsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)));
Map<String, Object> result = Maps.newLinkedHashMap();
- for (String keyS : allConfig.getAllConfig().keySet()) {
- if (keyS.startsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
- ConfigKey<?> key = ConfigKeys.newConfigKey(Object.class, keyS);
-
- Object val = allConfig.getStringKey(keyS);
-
- /*
- * NOV 2013 changing this to rely on config above being inserted in the right order,
- * so entity config will be preferred over location, and location over global.
- * If that is consistent then remove the lines below.
- * (We can also accept null entity and so combine with SshTasks.getSshFlags.)
- */
-
-// // have to use raw config to test whether the config is set
-// Object val = ((EntityInternal)entity).getConfigMap().getRawConfig(key);
-// if (val!=null) {
-// val = entity.getConfig(key);
-// } else {
-// val = globalConfig.getRawConfig(key);
-// if (val!=null) val = globalConfig.getConfig(key);
-// }
-// if (val!=null) {
- result.put(ConfigUtils.unprefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, key).getName(), val);
-// }
+ for (ConfigKey<?> key : sshConfig) {
+ /*
+ * Rely on config in the right order:
+ * entity config will be preferred over location, and location over global.
+ * (We can also accept null entity and so combine with SshTasks.getSshFlags.)
+ */
+
+ Maybe<Object> mv = ((EntityInternal)entity).config().getRaw(key);
+ Object v = null;
+ if (v==null && mv.isPresent()) {
+ v = entity.config().get(key);
+ }
+
+ if (mv.isAbsent() && optionalLocation!=null) {
+ mv = ((LocationInternal)optionalLocation).config().getRaw(key);
+ }
+ if (v==null && mv.isPresent()) {
+ v = optionalLocation.config().get(key);
+ }
+
+ if (mv.isAbsent()) {
+ v = globalConfig.getConfig(key);
}
+
+ result.put(ConfigUtils.unprefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, key).getName(), v);
}
return result;
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/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 8ba1bc3..6c5f73e 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
@@ -408,7 +408,7 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
if (!flags.isEmpty()) {
LOG.warn("Unsupported flags when configuring {}; storing: {}", this, flags);
- configsInternal.addToLocalBag(flags);
+ configsInternal.putAll(flags);
}
return this;
@@ -542,8 +542,8 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
if (iconUrl.isNull()) iconUrl.set(oldIconUrl);
configsInternal = new EntityConfigMap(this, managementContext.getStorage().<ConfigKey<?>, Object>getMap(getId()+"-config"));
- if (oldConfig.getLocalConfig().size() > 0) {
- configsInternal.setLocalConfig(oldConfig.getLocalConfig());
+ if (!oldConfig.isEmpty()) {
+ configsInternal.setLocalConfig(oldConfig.getAllConfigLocalRaw());
}
config().refreshInheritedConfig();
@@ -1212,7 +1212,7 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
ConfigConstraints.assertValid(AbstractEntity.this, key, val);
}
- protected AbstractConfigMapImpl getConfigsInternal() {
+ protected AbstractConfigMapImpl<?> getConfigsInternal() {
return configsInternal;
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/core/src/main/java/org/apache/brooklyn/core/entity/internal/ConfigMapViewWithStringKeys.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/internal/ConfigMapViewWithStringKeys.java b/core/src/main/java/org/apache/brooklyn/core/entity/internal/ConfigMapViewWithStringKeys.java
index 7d91af4..38f83c7 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/internal/ConfigMapViewWithStringKeys.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/internal/ConfigMapViewWithStringKeys.java
@@ -24,21 +24,23 @@ import java.util.Map;
import java.util.Set;
import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.config.ConfigMap;
import org.apache.brooklyn.core.config.BasicConfigKey;
-import com.google.common.annotations.Beta;
import com.google.common.collect.Sets;
/**
* Internal class that presents a view over a ConfigMap, so it looks like a Map (with the
* keys being the config key names).
+ *
+ * @deprecated since 0.10.0 removed support, no longer needed
*/
-@Beta
+@Deprecated
public class ConfigMapViewWithStringKeys implements Map<String,Object> {
- private org.apache.brooklyn.config.ConfigMap target;
+ private ConfigMap target;
- public ConfigMapViewWithStringKeys(org.apache.brooklyn.config.ConfigMap target) {
+ public ConfigMapViewWithStringKeys(ConfigMap target) {
this.target = target;
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/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 15f8ffa..400694e 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
@@ -26,28 +26,20 @@ 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.ConfigKey;
-import org.apache.brooklyn.config.ConfigValueAtContainer;
-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.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.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;
import com.google.common.collect.Maps;
-public class EntityConfigMap extends AbstractConfigMapImpl {
+public class EntityConfigMap extends AbstractConfigMapImpl<Entity> {
+ @SuppressWarnings("unused")
private static final Logger LOG = LoggerFactory.getLogger(EntityConfigMap.class);
public EntityConfigMap(EntityInternal entity) {
@@ -62,17 +54,17 @@ public class EntityConfigMap extends AbstractConfigMapImpl {
* @deprecated since 0.10.0 kept for serialization */ @Deprecated
private EntityInternal entity;
@Override
- public BrooklynObjectInternal getBrooklynObject() {
- BrooklynObjectInternal result = super.getBrooklynObject();
- if (result!=null) return result;
+ public EntityInternal getContainer() {
+ Entity result = super.getContainer();
+ if (result!=null) return (EntityInternal) result;
synchronized (this) {
- result = super.getBrooklynObject();
- if (result!=null) return result;
+ result = super.getContainer();
+ if (result!=null) return (EntityInternal) result;
bo = entity;
entity = null;
}
- return super.getBrooklynObject();
+ return (EntityInternal) super.getBrooklynObject();
}
protected EntityInternal getEntity() {
@@ -99,45 +91,19 @@ public class EntityConfigMap extends AbstractConfigMapImpl {
((EntityInternal)bo).getManagementSupport().getEntityChangeListener().onConfigChanged(key);
}
}
-
- @Override
- protected <T> Maybe<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(getEntity());
- if (ownKey==null) ownKey = key;
- LocalEvaluateKeyValue<Entity,T> evalFn = new LocalEvaluateKeyValue<Entity,T>(ownKey);
-
- if (ownKey instanceof ConfigKeySelfExtracting) {
- Maybe<T> ownExplicitValue = evalFn.apply(getEntity());
-
- AncestorContainerAndKeyValueIterator<Entity, T> ckvi = new AncestorContainerAndKeyValueIterator<Entity,T>(
- getEntity(), keyFn, evalFn, EntityFunctions.parent());
-
- ConfigValueAtContainer<Entity,T> result = getDefaultRuntimeInheritance().resolveInheriting(ownKey,
- ownExplicitValue, getEntity(),
- ckvi, InheritanceContext.RUNTIME_MANAGEMENT);
-
- return result.asMaybe();
- } else {
- LOG.warn("Config key {} of {} is not a ConfigKeySelfExtracting; cannot retrieve value; returning default", ownKey, getBrooklynObject());
- return Maybe.absent();
- }
- }
-
- private ConfigInheritance getDefaultRuntimeInheritance() {
- return BasicConfigInheritance.OVERWRITE;
+ @Override
+ protected Entity getParentOfContainer(Entity container) {
+ if (container==null) return null;
+ return container.getParent();
}
@Override
- protected BrooklynObjectInternal getParent() {
- return (EntityInternal) getEntity().getParent();
+ protected <T> ConfigKey<?> getKeyAtContainerImpl(Entity container, ConfigKey<T> queryKey) {
+ return container.getEntityType().getConfigKey(queryKey.getName());
}
-
- @Override
- // TODO deprecate or clarify syntax
+
+ @Override @Deprecated
public EntityConfigMap submap(Predicate<ConfigKey<?>> filter) {
EntityConfigMap m = new EntityConfigMap(getEntity(), Maps.<ConfigKey<?>, Object>newLinkedHashMap());
synchronized (ownConfig) {
@@ -153,9 +119,10 @@ public class EntityConfigMap extends AbstractConfigMapImpl {
return m;
}
+ @Deprecated
private void merge(EntityConfigMap local, EntityConfigMap parent) {
for (ConfigKey<?> k: parent.ownConfig.keySet()) {
- // TODO apply inheritance
+ // should apply inheritance; but only used in submap which is deprecated
if (!local.ownConfig.containsKey(k)) {
local.ownConfig.put(k, parent.ownConfig.get(k));
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0d655e05/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynPropertiesImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynPropertiesImpl.java b/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynPropertiesImpl.java
index 9ed6a17..03fb13d 100644
--- a/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynPropertiesImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynPropertiesImpl.java
@@ -19,7 +19,6 @@
package org.apache.brooklyn.core.internal;
import static com.google.common.base.Preconditions.checkNotNull;
-import groovy.lang.Closure;
import java.io.File;
import java.io.FileInputStream;
@@ -29,9 +28,11 @@ import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Properties;
+import java.util.Set;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
@@ -54,6 +55,8 @@ import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
+import groovy.lang.Closure;
+
/**
* TODO methods in this class are not thread safe.
* intention is that they are set during startup and not modified thereafter.
@@ -455,13 +458,29 @@ public class BrooklynPropertiesImpl extends LinkedHashMap implements BrooklynPro
}
@Override
- public Map<ConfigKey<?>, Object> getAllConfig() {
+ public Map<ConfigKey<?>,Object> getAllConfigLocalRaw() {
Map<ConfigKey<?>, Object> result = new LinkedHashMap<ConfigKey<?>, Object>();
for (Object entry: entrySet())
result.put(new BasicConfigKey<Object>(Object.class, ""+((Map.Entry)entry).getKey()), ((Map.Entry)entry).getValue());
return result;
}
+ @Override @Deprecated
+ public Map<ConfigKey<?>, Object> getAllConfig() {
+ return getAllConfigLocalRaw();
+ }
+
+ @Override
+ public Set<ConfigKey<?>> findKeys(Predicate<ConfigKey<?>> filter) {
+ Set<ConfigKey<?>> result = new LinkedHashSet<ConfigKey<?>>();
+ for (Object entry: entrySet()) {
+ ConfigKey<?> k = new BasicConfigKey<Object>(Object.class, ""+((Map.Entry)entry).getKey());
+ if (filter.apply(k))
+ result.add(new BasicConfigKey<Object>(Object.class, ""+((Map.Entry)entry).getKey()));
+ }
+ return result;
+ }
+
@Override
public BrooklynPropertiesImpl submap(Predicate<ConfigKey<?>> filter) {
BrooklynPropertiesImpl result = Factory.newEmpty();