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 2014/08/06 23:16:55 UTC
[03/11] git commit: add tags to BrooklynObject and to specs, with
tests that they get set and can be queried for all BO subtypes;
other cleanup to testing and deprection
add tags to BrooklynObject and to specs, with tests that they get set and can be queried for all BO subtypes; other cleanup to testing and deprection
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/72b52e1d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/72b52e1d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/72b52e1d
Branch: refs/heads/master
Commit: 72b52e1d0db028caa654c6169ec829d0bed7af9e
Parents: 4bbf3b4
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Aug 1 17:58:49 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Aug 5 10:40:41 2014 -0400
----------------------------------------------------------------------
.../basic/AbstractBrooklynObjectSpec.java | 20 ++
.../java/brooklyn/basic/BrooklynObject.java | 14 ++
.../brooklyn/entity/proxying/EntitySpec.java | 1 +
.../main/java/brooklyn/policy/EnricherSpec.java | 5 +
.../java/brooklyn/policy/EntityAdjunct.java | 31 ++-
.../main/java/brooklyn/policy/PolicySpec.java | 5 +
.../brooklyn/basic/AbstractBrooklynObject.java | 53 +++++
.../enricher/basic/AbstractEnricher.java | 5 +-
.../brooklyn/entity/basic/AbstractEntity.java | 37 +---
.../entity/proxying/InternalEntityFactory.java | 3 +
.../proxying/InternalLocationFactory.java | 4 +-
.../entity/proxying/InternalPolicyFactory.java | 4 +
.../rebind/BasicLocationRebindSupport.java | 2 +-
.../location/basic/AbstractLocation.java | 49 ++--
.../policy/basic/AbstractEntityAdjunct.java | 26 ++-
.../brooklyn/policy/basic/AbstractPolicy.java | 8 +-
.../enricher/basic/BasicEnricherTest.java | 93 ++++++++
.../enricher/basic/EnricherConfigTest.java | 148 +++++++++++++
.../brooklyn/entity/basic/EntitiesTest.java | 6 +-
.../location/basic/AbstractLocationTest.java | 9 +-
.../location/basic/LocationConfigTest.java | 3 +
.../brooklyn/policy/basic/BasicPolicyTest.java | 89 ++++++++
.../policy/basic/EnricherConfigTest.java | 169 --------------
.../policy/basic/PolicyConfigMapUsageTest.java | 222 -------------------
.../brooklyn/policy/basic/PolicyConfigTest.java | 202 +++++++++++++++++
.../BrooklynAssemblyTemplateInstantiator.java | 1 +
.../java/brooklyn/util/guava/TypeTokens.java | 19 ++
27 files changed, 776 insertions(+), 452 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/api/src/main/java/brooklyn/basic/AbstractBrooklynObjectSpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/basic/AbstractBrooklynObjectSpec.java b/api/src/main/java/brooklyn/basic/AbstractBrooklynObjectSpec.java
index d61e016..dc6642f 100644
--- a/api/src/main/java/brooklyn/basic/AbstractBrooklynObjectSpec.java
+++ b/api/src/main/java/brooklyn/basic/AbstractBrooklynObjectSpec.java
@@ -20,10 +20,14 @@ package brooklyn.basic;
import java.io.Serializable;
import java.lang.reflect.Modifier;
+import java.util.Set;
+import brooklyn.util.collections.MutableSet;
import brooklyn.util.exceptions.Exceptions;
import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
public abstract class AbstractBrooklynObjectSpec<T,K extends AbstractBrooklynObjectSpec<T,K>> implements Serializable {
@@ -31,6 +35,7 @@ public abstract class AbstractBrooklynObjectSpec<T,K extends AbstractBrooklynObj
private final Class<T> type;
private String displayName;
+ private Set<Object> tags = MutableSet.of();
protected AbstractBrooklynObjectSpec(Class<T> type) {
checkValidType(type);
@@ -54,6 +59,17 @@ public abstract class AbstractBrooklynObjectSpec<T,K extends AbstractBrooklynObj
return self();
}
+ public K tag(Object tag) {
+ tags.add(tag);
+ return self();
+ }
+
+ /** adds the given tags */
+ public K tags(Iterable<Object> tagsToAdd) {
+ Iterables.addAll(this.tags, tagsToAdd);
+ return self();
+ }
+
/**
* @return The type of the enricher
*/
@@ -68,6 +84,10 @@ public abstract class AbstractBrooklynObjectSpec<T,K extends AbstractBrooklynObj
return displayName;
}
+ public final Set<Object> getTags() {
+ return ImmutableSet.copyOf(tags);
+ }
+
// TODO Duplicates method in BasicEntityTypeRegistry and InternalEntityFactory.isNewStyleEntity
protected final void checkIsNewStyleImplementation(Class<?> implClazz) {
try {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/api/src/main/java/brooklyn/basic/BrooklynObject.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/basic/BrooklynObject.java b/api/src/main/java/brooklyn/basic/BrooklynObject.java
index 9e22f96..dd26528 100644
--- a/api/src/main/java/brooklyn/basic/BrooklynObject.java
+++ b/api/src/main/java/brooklyn/basic/BrooklynObject.java
@@ -18,14 +18,28 @@
*/
package brooklyn.basic;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+
import brooklyn.entity.trait.Identifiable;
/**
* Super-type of entity, location, policy and enricher.
*/
public interface BrooklynObject extends Identifiable {
+
/**
* A display name; recommended to be a concise single-line description.
*/
String getDisplayName();
+
+ /**
+ * A set of tags associated to this adjunct.
+ */
+ @Nonnull Set<Object> getTags();
+
+ /** whether the given object is contained as a tag */
+ boolean containsTag(Object tag);
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/api/src/main/java/brooklyn/entity/proxying/EntitySpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/entity/proxying/EntitySpec.java b/api/src/main/java/brooklyn/entity/proxying/EntitySpec.java
index daaa6c8..7410266 100644
--- a/api/src/main/java/brooklyn/entity/proxying/EntitySpec.java
+++ b/api/src/main/java/brooklyn/entity/proxying/EntitySpec.java
@@ -106,6 +106,7 @@ public class EntitySpec<T extends Entity> extends AbstractBrooklynObjectSpec<T,E
public static <T extends Entity> EntitySpec<T> create(EntitySpec<T> spec) {
EntitySpec<T> result = create(spec.getType())
.displayName(spec.getDisplayName())
+ .tags(spec.getTags())
.additionalInterfaces(spec.getAdditionalInterfaces())
.configure(spec.getConfig())
.configure(spec.getFlags())
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/api/src/main/java/brooklyn/policy/EnricherSpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/policy/EnricherSpec.java b/api/src/main/java/brooklyn/policy/EnricherSpec.java
index 43f1a85..f2cfdd4 100644
--- a/api/src/main/java/brooklyn/policy/EnricherSpec.java
+++ b/api/src/main/java/brooklyn/policy/EnricherSpec.java
@@ -84,6 +84,11 @@ public class EnricherSpec<T extends Enricher> extends AbstractBrooklynObjectSpec
checkIsNewStyleImplementation(type);
}
+ public EnricherSpec<T> uniqueTag(String uniqueTag) {
+ flags.put("uniqueTag", uniqueTag);
+ return this;
+ }
+
public EnricherSpec<T> configure(Map<?,?> val) {
for (Map.Entry<?, ?> entry: val.entrySet()) {
if (entry.getKey()==null) throw new NullPointerException("Null key not permitted");
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/api/src/main/java/brooklyn/policy/EntityAdjunct.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/policy/EntityAdjunct.java b/api/src/main/java/brooklyn/policy/EntityAdjunct.java
index fa05a2a..97acc08 100644
--- a/api/src/main/java/brooklyn/policy/EntityAdjunct.java
+++ b/api/src/main/java/brooklyn/policy/EntityAdjunct.java
@@ -18,15 +18,20 @@
*/
package brooklyn.policy;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
import brooklyn.basic.BrooklynObject;
/**
- * EntityAdjuncts are supplementary logic that can be attached to Entities, providing sensor enrichment
- * or enabling policy
+ * EntityAdjuncts are supplementary logic that can be attached to Entities,
+ * such as providing sensor enrichment or event-driven policy behavior
*/
public interface EntityAdjunct extends BrooklynObject {
/**
- * A unique id for this adjunct
+ * A unique id for this adjunct, typically created by the system with no meaning
*/
@Override
String getId();
@@ -43,7 +48,25 @@ public interface EntityAdjunct extends BrooklynObject {
boolean isDestroyed();
/**
- * Whether the adjunct is available
+ * Whether the adjunct is available/active
*/
boolean isRunning();
+
+ /**
+ * An optional tag used to identify adjuncts with a specific purpose, typically created by the caller.
+ * This is used to prevent multiple instances with the same purpose from being created,
+ * and to access and customize adjuncts so created.
+ * <p>
+ * This will be included in the call to {@link #getTags()}.
+ */
+ @Nullable String getUniqueTag();
+
+ /**
+ * A set of tags associated to this adjunct.
+ * <p>
+ * This will include {@link #getUniqueTag()} if that is set.
+ */
+ @Override
+ @Nonnull Set<Object> getTags();
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/api/src/main/java/brooklyn/policy/PolicySpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/policy/PolicySpec.java b/api/src/main/java/brooklyn/policy/PolicySpec.java
index ccce6e0..13206cf 100644
--- a/api/src/main/java/brooklyn/policy/PolicySpec.java
+++ b/api/src/main/java/brooklyn/policy/PolicySpec.java
@@ -84,6 +84,11 @@ public class PolicySpec<T extends Policy> extends AbstractBrooklynObjectSpec<T,P
checkIsNewStyleImplementation(type);
}
+ public PolicySpec<T> uniqueTag(String uniqueTag) {
+ flags.put("uniqueTag", uniqueTag);
+ return this;
+ }
+
public PolicySpec<T> configure(Map<?,?> val) {
for (Map.Entry<?, ?> entry: val.entrySet()) {
if (entry.getKey()==null) throw new NullPointerException("Null key not permitted");
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java b/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
index b64db51..e977fec 100644
--- a/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
+++ b/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
@@ -18,16 +18,69 @@
*/
package brooklyn.basic;
+import java.util.Set;
+
import brooklyn.util.flags.SetFromFlag;
import brooklyn.util.text.Identifiers;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+
public abstract class AbstractBrooklynObject implements BrooklynObjectInternal {
@SetFromFlag(value="id")
private String id = Identifiers.makeRandomId(8);
+ /** subclasses should synchronize on this for all access */
+ @SetFromFlag(value="tags")
+ protected Set<Object> tags = Sets.newLinkedHashSet();
+
@Override
public String getId() {
return id;
}
+
+ @Override
+ public Set<Object> getTags() {
+ synchronized (tags) {
+ return ImmutableSet.copyOf(tags);
+ }
+ }
+
+ public boolean addTag(Object tag) {
+ boolean result;
+ synchronized (tags) {
+ result = tags.add(tag);
+ }
+ onTagsChanged();
+ return result;
+ }
+
+ public boolean addTags(Iterable<Object> tags) {
+ boolean result;
+ synchronized (tags) {
+ result = Iterables.addAll(this.tags, tags);
+ }
+ onTagsChanged();
+ return result;
+ }
+
+ public boolean removeTag(Object tag) {
+ boolean result;
+ synchronized (tags) {
+ result = tags.remove(tag);
+ }
+ onTagsChanged();
+ return result;
+ }
+
+ public boolean containsTag(Object tag) {
+ synchronized (tags) {
+ return tags.contains(tag);
+ }
+ }
+
+ protected abstract void onTagsChanged();
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java b/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
index 6368866..df6a370 100644
--- a/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
+++ b/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
@@ -41,7 +41,7 @@ public abstract class AbstractEnricher extends AbstractEntityAdjunct implements
this(Maps.newLinkedHashMap());
}
- public AbstractEnricher(Map flags) {
+ public AbstractEnricher(Map<?,?> flags) {
super(flags);
enricherType = new EnricherTypeImpl(getAdjunctType());
@@ -62,9 +62,10 @@ public abstract class AbstractEnricher extends AbstractEntityAdjunct implements
@Override
protected void onChanged() {
- // TODO Could add EnricherChangeListener, similar to EntityChangeListener; should we do that?
+ // currently changes simply trigger re-persistence; there is no intermediate listener as we do for EntityChangeListener
if (getManagementContext() != null) {
getManagementContext().getRebindManager().getChangeListener().onChanged(this);
}
}
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
index 9ebb62f..19bbea1 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@ -34,7 +34,6 @@ import brooklyn.basic.AbstractBrooklynObject;
import brooklyn.config.ConfigKey;
import brooklyn.config.ConfigKey.HasConfigKey;
import brooklyn.enricher.basic.AbstractEnricher;
-import brooklyn.enricher.basic.Aggregator;
import brooklyn.entity.Application;
import brooklyn.entity.Effector;
import brooklyn.entity.Entity;
@@ -71,7 +70,6 @@ import brooklyn.management.internal.SubscriptionTracker;
import brooklyn.mementos.EntityMemento;
import brooklyn.policy.Enricher;
import brooklyn.policy.EnricherSpec;
-import brooklyn.policy.EntityAdjunct;
import brooklyn.policy.Policy;
import brooklyn.policy.PolicySpec;
import brooklyn.policy.basic.AbstractEntityAdjunct;
@@ -91,7 +89,6 @@ import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -175,7 +172,6 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
Map<String,Object> presentationAttributes = Maps.newLinkedHashMap();
Collection<AbstractPolicy> policies = Lists.newCopyOnWriteArrayList();
Collection<AbstractEnricher> enrichers = Lists.newCopyOnWriteArrayList();
- Set<Object> tags = Sets.newLinkedHashSet();
// FIXME we do not currently support changing parents, but to implement a cluster that can shrink we need to support at least
// orphaning (i.e. removing ownership). This flag notes if the entity has previously had a parent, and if an attempt is made to
@@ -1330,38 +1326,9 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
}
@Override
- public Set<Object> getTags() {
- synchronized (tags) {
- return ImmutableSet.copyOf(tags);
- }
- }
-
- @Override
- public boolean addTag(Object tag) {
- boolean result;
- synchronized (tags) {
- result = tags.add(tag);
- }
+ protected void onTagsChanged() {
getManagementSupport().getEntityChangeListener().onTagsChanged();
- return result;
- }
-
- @Override
- public boolean removeTag(Object tag) {
- boolean result;
- synchronized (tags) {
- result = tags.remove(tag);
- }
- getManagementSupport().getEntityChangeListener().onTagsChanged();
- return result;
- }
-
- @Override
- public boolean containsTag(Object tag) {
- synchronized (tags) {
- return tags.contains(tag);
- }
- }
+ }
@Override
protected void finalize() throws Throwable {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java b/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
index b5d7c0a..9cc05c3 100644
--- a/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
+++ b/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
@@ -169,6 +169,7 @@ public class InternalEntityFactory extends InternalFactory {
return entity;
}
+ @SuppressWarnings("deprecation")
protected <T extends Entity> T createEntityAndDescendantsUninitialized(EntitySpec<T> spec, Map<String,Entity> entitiesByEntityId, Map<String,EntitySpec<?>> specsByEntityId) {
if (spec.getFlags().containsKey("parent") || spec.getFlags().containsKey("owner")) {
throw new IllegalArgumentException("Spec's flags must not contain parent or owner; use spec.parent() instead for "+spec);
@@ -230,6 +231,7 @@ public class InternalEntityFactory extends InternalFactory {
if (spec.getDisplayName()!=null)
((AbstractEntity)entity).setDisplayName(spec.getDisplayName());
+ ((AbstractEntity)entity).addTags(spec.getTags());
((AbstractEntity)entity).configure(MutableMap.copyOf(spec.getFlags()));
for (Map.Entry<ConfigKey<?>, Object> entry : spec.getConfig().entrySet()) {
@@ -320,6 +322,7 @@ public class InternalEntityFactory extends InternalFactory {
* but that behaviour is deprecated.
*/
public <T extends Entity> T constructEntity(Class<? extends T> clazz, EntitySpec<T> spec) {
+ @SuppressWarnings("deprecation")
T entity = constructEntityImpl(clazz, spec.getFlags(), spec.getId());
if (((AbstractEntity)entity).getProxy() == null) ((AbstractEntity)entity).setProxy(createEntityProxy(spec, entity));
return entity;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java b/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
index 804b5d5..6a7b599 100644
--- a/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
+++ b/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
@@ -95,7 +95,9 @@ public class InternalLocationFactory extends InternalFactory {
managementContext.prePreManage(loc);
if (spec.getDisplayName()!=null)
- ((AbstractLocation)loc).setName(spec.getDisplayName());
+ ((AbstractLocation)loc).setDisplayName(spec.getDisplayName());
+
+ ((AbstractLocation)loc).addTags(spec.getTags());
if (isNewStyleLocation(clazz)) {
((AbstractLocation)loc).setManagementContext(managementContext);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java b/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java
index ebf13dd..76dd312 100644
--- a/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java
+++ b/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java
@@ -94,6 +94,8 @@ public class InternalPolicyFactory extends InternalFactory {
if (spec.getDisplayName()!=null)
((AbstractPolicy)pol).setDisplayName(spec.getDisplayName());
+ ((AbstractPolicy)pol).addTags(spec.getTags());
+
if (isNewStylePolicy(clazz)) {
((AbstractPolicy)pol).setManagementContext(managementContext);
Map<String, Object> config = ConfigBag.newInstance().putAll(spec.getFlags()).putAll(spec.getConfig()).getAllConfig();
@@ -129,6 +131,8 @@ public class InternalPolicyFactory extends InternalFactory {
if (spec.getDisplayName()!=null)
((AbstractEnricher)enricher).setDisplayName(spec.getDisplayName());
+ ((AbstractEnricher)enricher).addTags(spec.getTags());
+
if (isNewStyleEnricher(clazz)) {
((AbstractEnricher)enricher).setManagementContext(managementContext);
Map<String, Object> config = ConfigBag.newInstance().putAll(spec.getFlags()).putAll(spec.getConfig()).getAllConfig();
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
index 7e930ef..157ccca 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
@@ -69,7 +69,7 @@ public class BasicLocationRebindSupport implements RebindSupport<LocationMemento
// Note that the flags have been set in the constructor
// FIXME Relies on location.getLocalConfigBag being mutable (to modify the location's own config)
- location.setName(memento.getDisplayName());
+ location.setDisplayName(memento.getDisplayName());
location.getLocalConfigBag().putAll(memento.getLocationConfig()).markAll(
Sets.difference(memento.getLocationConfig().keySet(), memento.getLocationConfigUnused())).
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/AbstractLocation.java b/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
index 651a46b..e517d10 100644
--- a/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
@@ -57,6 +57,7 @@ import brooklyn.util.collections.SetFromLiveMap;
import brooklyn.util.config.ConfigBag;
import brooklyn.util.flags.FlagUtils;
import brooklyn.util.flags.TypeCoercions;
+import brooklyn.util.guava.TypeTokens;
import brooklyn.util.stream.Streams;
import com.google.common.base.Objects;
@@ -78,6 +79,8 @@ import com.google.common.collect.Sets;
*/
public abstract class AbstractLocation extends AbstractBrooklynObject implements LocationInternal, HasHostGeoInfo, Configurable {
+ private static final long serialVersionUID = -7495805474138619830L;
+
/** @deprecated since 0.7.0 shouldn't be public */
@Deprecated
public static final Logger LOG = LoggerFactory.getLogger(AbstractLocation.class);
@@ -138,7 +141,8 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
* <li>abbreviatedName
* </ul>
*/
- public AbstractLocation(Map properties) {
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public AbstractLocation(Map<?,?> properties) {
inConstruction = true;
_legacyConstruction = !InternalFactory.FactoryConstructionTracker.isConstructing();
if (!_legacyConstruction && properties!=null && !properties.isEmpty()) {
@@ -233,8 +237,8 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
* in this class, so initializers in subclasses will not have run when this overridden
* method is invoked.) If you require fields to be initialized you must do that in
* this method with a guard (as in FixedListMachineProvisioningLocation).
- */
- public void configure(Map properties) {
+ */
+ public void configure(Map<?,?> properties) {
assertNotYetManaged();
boolean firstTime = !configured.getAndSet(true);
@@ -272,7 +276,7 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
if (rawCodes instanceof CharSequence) {
codes = ImmutableSet.copyOf(Splitter.on(",").trimResults().split((CharSequence)rawCodes));
} else {
- codes = TypeCoercions.coerce(rawCodes, Set.class);
+ codes = TypeCoercions.coerce(rawCodes, TypeTokens.setOf(String.class));
}
configBag.put(LocationConfigKeys.ISO_3166, codes);
}
@@ -280,7 +284,7 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
// TODO ensure no callers rely on 'remove' semantics, and don't remove;
// or perhaps better use a config bag so we know what is used v unused
- private static Object removeIfPossible(Map map, Object key) {
+ private static Object removeIfPossible(Map<?,?> map, Object key) {
try {
return map.remove(key);
} catch (Exception e) {
@@ -385,6 +389,8 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
parent.set(newParent);
((AbstractLocation)parent.get()).addChild(this); // FIXME Nasty cast
}
+
+ onChanged();
}
@Override
@@ -399,6 +405,7 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
// 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(entityType.getConfigKey(key.getName()), key);
return ownKey.getDefaultValue();
@@ -442,18 +449,15 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
@Override
public <T> T setConfig(ConfigKey<T> key, T value) {
- return configBag.put(key, value);
- }
-
- /** @since 0.6.0 (?) - use getDisplayName */
- public void setName(String newName) {
- setDisplayName(newName);
- displayNameAutoGenerated = false;
+ T result = configBag.put(key, value);
+ onChanged();
+ return result;
}
public void setDisplayName(String newName) {
name.set(newName);
displayNameAutoGenerated = false;
+ onChanged();
}
@Override
@@ -487,6 +491,7 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
return child;
}
+ @SuppressWarnings("deprecation")
public void addChild(Location child) {
// Previously, setParent delegated to addChildLocation and we sometimes ended up with
// duplicate entries here. Instead this now uses a similar scheme to
@@ -508,7 +513,10 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
if (isManaged()) {
- Locations.manage(child, managementContext);
+ if (!managementContext.getLocationManager().isManaged(child)) {
+ // this deprecated call should be replaced with an internal interface call?
+ managementContext.getLocationManager().manage(child);
+ }
} else if (managementContext != null) {
if (((LocalLocationManager)managementContext.getLocationManager()).getLocationEvenIfPreManaged(child.getId()) == null) {
((ManagementContextInternal)managementContext).prePreManage(child);
@@ -517,6 +525,8 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
children.add(child);
child.setParent(this);
+
+ onChanged();
}
public boolean removeChild(Location child) {
@@ -534,9 +544,22 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
managementContext.getLocationManager().unmanage(child);
}
}
+ onChanged();
return removed;
}
+ @Override
+ protected void onTagsChanged() {
+ onChanged();
+ }
+
+ protected void onChanged() {
+ // currently changes simply trigger re-persistence; there is no intermediate listener as we do for EntityChangeListener
+ if (getManagementContext() != null) {
+ getManagementContext().getRebindManager().getChangeListener().onChanged(this);
+ }
+ }
+
/** Default String representation is simplified name of class, together with selected fields. */
@Override
public String toString() {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
index 9ca0e91..a53d9a5 100644
--- a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
@@ -26,6 +26,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.slf4j.Logger;
@@ -59,6 +60,7 @@ import brooklyn.util.flags.TypeCoercions;
import com.google.common.annotations.Beta;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
@@ -97,6 +99,9 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
protected transient SubscriptionTracker _subscriptionTracker;
private AtomicBoolean destroyed = new AtomicBoolean(false);
+
+ @SetFromFlag(value="uniqueTag")
+ protected String uniqueTag;
public AbstractEntityAdjunct() {
this(Collections.emptyMap());
@@ -262,6 +267,11 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
throw new UnsupportedOperationException("reconfiguring "+key+" unsupported for "+this);
}
+ @Override
+ protected void onTagsChanged() {
+ onChanged();
+ }
+
protected abstract void onChanged();
protected AdjunctType getAdjunctType() {
@@ -397,11 +407,25 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
public boolean isRunning() {
return !isDestroyed();
}
+
+ @Override
+ public String getUniqueTag() {
+ return uniqueTag;
+ }
+
+ @Override
+ public Set<Object> getTags() {
+ if (getUniqueTag()==null) return super.getTags();
+ synchronized (tags) {
+ return ImmutableSet.builder().addAll(tags).add(getUniqueTag()).build();
+ }
+ }
@Override
public String toString() {
- return Objects.toStringHelper(getClass())
+ return Objects.toStringHelper(getClass()).omitNullValues()
.add("name", name)
+ .add("uniqueTag", uniqueTag)
.add("running", isRunning())
.add("id", getId())
.toString();
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java b/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java
index 70fa44b..79269c6 100644
--- a/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java
@@ -54,7 +54,7 @@ public abstract class AbstractPolicy extends AbstractEntityAdjunct implements Po
this(Collections.emptyMap());
}
- public AbstractPolicy(Map flags) {
+ public AbstractPolicy(Map<?,?> flags) {
super(flags);
policyType = new PolicyTypeImpl(getAdjunctType());
@@ -80,6 +80,10 @@ public abstract class AbstractPolicy extends AbstractEntityAdjunct implements Po
@Override
public boolean isSuspended() {
+ if (suspended==null) {
+ // only if accessed during construction in super, e.g. by a call to toString in configure
+ return true;
+ }
return suspended.get();
}
@@ -96,7 +100,7 @@ public abstract class AbstractPolicy extends AbstractEntityAdjunct implements Po
@Override
protected void onChanged() {
- // TODO Could add PolicyChangeListener, similar to EntityChangeListener; should we do that?
+ // currently changes simply trigger re-persistence; there is no intermediate listener as we do for EntityChangeListener
if (getManagementContext() != null) {
getManagementContext().getRebindManager().getChangeListener().onChanged(this);
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/test/java/brooklyn/enricher/basic/BasicEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/enricher/basic/BasicEnricherTest.java b/core/src/test/java/brooklyn/enricher/basic/BasicEnricherTest.java
new file mode 100644
index 0000000..9d0fcf2
--- /dev/null
+++ b/core/src/test/java/brooklyn/enricher/basic/BasicEnricherTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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 brooklyn.enricher.basic;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.enricher.basic.AbstractEnricher;
+import brooklyn.entity.BrooklynAppUnitTestSupport;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.policy.EnricherSpec;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.flags.SetFromFlag;
+
+/**
+ * Test that enricher can be created and accessed, by construction and by spec
+ */
+public class BasicEnricherTest extends BrooklynAppUnitTestSupport {
+
+ // TODO These tests are a copy of BasicPolicyTest, which is a code smell.
+ // However, the src/main/java code does not contain as much duplication.
+
+ public static class MyEnricher extends AbstractEnricher {
+ @SetFromFlag("intKey")
+ public static final BasicConfigKey<Integer> INT_KEY = new BasicConfigKey<Integer>(Integer.class, "bkey", "b key");
+
+ @SetFromFlag("strKey")
+ public static final ConfigKey<String> STR_KEY = new BasicConfigKey<String>(String.class, "akey", "a key");
+ public static final ConfigKey<Integer> INT_KEY_WITH_DEFAULT = new BasicConfigKey<Integer>(Integer.class, "ckey", "c key", 1);
+ public static final ConfigKey<String> STR_KEY_WITH_DEFAULT = new BasicConfigKey<String>(String.class, "strKey", "str key", "str key default");
+
+ MyEnricher(Map<?,?> flags) {
+ super(flags);
+ }
+
+ public MyEnricher() {
+ super();
+ }
+ }
+
+ @Test
+ public void testAddInstance() throws Exception {
+ MyEnricher enricher = new MyEnricher();
+ enricher.setDisplayName("Bob");
+ enricher.setConfig(MyEnricher.STR_KEY, "aval");
+ enricher.setConfig(MyEnricher.INT_KEY, 2);
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getDisplayName(), "Bob");
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
+ assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
+ }
+
+ @Test
+ public void testAddSpec() throws Exception {
+ MyEnricher enricher = app.addEnricher(EnricherSpec.create(MyEnricher.class)
+ .displayName("Bob")
+ .configure(MyEnricher.STR_KEY, "aval").configure(MyEnricher.INT_KEY, 2));
+
+ assertEquals(enricher.getDisplayName(), "Bob");
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
+ assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
+ }
+
+ @Test
+ public void testTagsFromSpec() throws Exception {
+ MyEnricher enricher = app.addEnricher(EnricherSpec.create(MyEnricher.class).tag(99).uniqueTag("x"));
+
+ assertEquals(enricher.getTags(), MutableSet.of("x", 99));
+ assertEquals(enricher.getUniqueTag(), "x");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/test/java/brooklyn/enricher/basic/EnricherConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/enricher/basic/EnricherConfigTest.java b/core/src/test/java/brooklyn/enricher/basic/EnricherConfigTest.java
new file mode 100644
index 0000000..03677d9
--- /dev/null
+++ b/core/src/test/java/brooklyn/enricher/basic/EnricherConfigTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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 brooklyn.enricher.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import org.testng.annotations.Test;
+
+import brooklyn.enricher.basic.BasicEnricherTest.MyEnricher;
+import brooklyn.entity.BrooklynAppUnitTestSupport;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.util.collections.MutableMap;
+
+/**
+ * Test that configuration properties are usable and inherited correctly.
+ */
+public class EnricherConfigTest extends BrooklynAppUnitTestSupport {
+
+ // TODO These tests are a copy of PolicyConfigTest, which is a code smell.
+ // However, the src/main/java code does not contain as much duplication.
+
+ private BasicConfigKey<String> differentKey = new BasicConfigKey<String>(String.class, "differentkey", "diffval");
+
+ @Test
+ public void testConfigFlagsPassedInAtConstructionIsAvailable() throws Exception {
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put("strKey", "aval")
+ .put("intKey", 2)
+ .build());
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
+ assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
+ // this is set, because key name matches annotation on STR_KEY
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), "aval");
+ }
+
+ @Test
+ public void testUnknownConfigPassedInAtConstructionIsWarnedAndIgnored() throws Exception {
+ // TODO Also assert it's warned
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put(differentKey, "aval")
+ .build());
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(differentKey), null);
+ assertEquals(enricher.getEnricherType().getConfigKey(differentKey.getName()), null);
+ }
+
+ @Test
+ public void testConfigPassedInAtConstructionIsAvailable() throws Exception {
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put(MyEnricher.STR_KEY, "aval")
+ .put(MyEnricher.INT_KEY, 2)
+ .build());
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
+ assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
+ // this is not set (contrast with above)
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), MyEnricher.STR_KEY_WITH_DEFAULT.getDefaultValue());
+ }
+
+ @Test
+ public void testConfigSetToGroovyTruthFalseIsAvailable() throws Exception {
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put(MyEnricher.INT_KEY_WITH_DEFAULT, 0)
+ .build());
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.INT_KEY_WITH_DEFAULT), (Integer)0);
+ }
+
+ @Test
+ public void testConfigSetToNullIsAvailable() throws Exception {
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put(MyEnricher.STR_KEY_WITH_DEFAULT, null)
+ .build());
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), null);
+ }
+
+ @Test
+ public void testConfigCanBeSetOnEnricher() throws Exception {
+ MyEnricher enricher = new MyEnricher();
+ enricher.setConfig(MyEnricher.STR_KEY, "aval");
+ enricher.setConfig(MyEnricher.INT_KEY, 2);
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
+ assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
+ }
+
+ @Test
+ public void testConfigSetterOverridesConstructorValue() throws Exception {
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put(MyEnricher.STR_KEY, "aval")
+ .build());
+ enricher.setConfig(MyEnricher.STR_KEY, "diffval");
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "diffval");
+ }
+
+ @Test
+ public void testConfigCannotBeSetAfterApplicationIsStarted() throws Exception {
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put(MyEnricher.STR_KEY, "origval")
+ .build());
+ app.addEnricher(enricher);
+
+ try {
+ enricher.setConfig(MyEnricher.STR_KEY,"newval");
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // success
+ }
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "origval");
+ }
+
+ @Test
+ public void testConfigReturnsDefaultValueIfNotSet() throws Exception {
+ MyEnricher enricher = new MyEnricher();
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), "str key default");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java b/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
index 8acdf72..e9b3399 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
@@ -107,14 +107,17 @@ public class EntitiesTest extends BrooklynAppUnitTestSupport {
@Test
public void testCreateGetContainsAndRemoveTags() throws Exception {
entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)
+ .tag(2)
.addInitializer(EntityInitializers.addingTags("foo")));
entity.addTag(app);
+ Assert.assertTrue(entity.containsTag(app));
Assert.assertTrue(entity.containsTag("foo"));
+ Assert.assertTrue(entity.containsTag(2));
Assert.assertFalse(entity.containsTag("bar"));
- Assert.assertEquals(entity.getTags(), MutableSet.of(app, "foo"));
+ Assert.assertEquals(entity.getTags(), MutableSet.of(app, "foo", 2));
entity.removeTag("foo");
Assert.assertFalse(entity.containsTag("foo"));
@@ -122,6 +125,7 @@ public class EntitiesTest extends BrooklynAppUnitTestSupport {
Assert.assertTrue(entity.containsTag(entity.getParent()));
Assert.assertFalse(entity.containsTag(entity));
+ entity.removeTag(2);
Assert.assertEquals(entity.getTags(), MutableSet.of(app));
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java b/core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java
index 4993486..97fb633 100644
--- a/core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java
+++ b/core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java
@@ -36,6 +36,7 @@ import brooklyn.location.LocationSpec;
import brooklyn.management.ManagementContext;
import brooklyn.test.entity.LocalManagementContextForTests;
import brooklyn.util.collections.MutableMap;
+import brooklyn.util.collections.MutableSet;
import brooklyn.util.flags.SetFromFlag;
import com.google.common.collect.ImmutableList;
@@ -172,5 +173,11 @@ public class AbstractLocationTest {
ConcreteLocation loc = createConcrete();
assertEquals(loc.myfield, "mydefault");
}
-
+
+ @Test
+ public void testLocationTags() throws Exception {
+ LocationInternal loc = mgmt.getLocationManager().createLocation(LocationSpec.create(ConcreteLocation.class).tag("x"));
+ assertEquals(loc.getTags(), MutableSet.of("x"));
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/test/java/brooklyn/location/basic/LocationConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/LocationConfigTest.java b/core/src/test/java/brooklyn/location/basic/LocationConfigTest.java
index 3db4743..69f18a1 100644
--- a/core/src/test/java/brooklyn/location/basic/LocationConfigTest.java
+++ b/core/src/test/java/brooklyn/location/basic/LocationConfigTest.java
@@ -176,6 +176,7 @@ public class LocationConfigTest {
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");
@@ -185,6 +186,7 @@ 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");
@@ -192,6 +194,7 @@ 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");
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/test/java/brooklyn/policy/basic/BasicPolicyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/policy/basic/BasicPolicyTest.java b/core/src/test/java/brooklyn/policy/basic/BasicPolicyTest.java
new file mode 100644
index 0000000..1072bc8
--- /dev/null
+++ b/core/src/test/java/brooklyn/policy/basic/BasicPolicyTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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 brooklyn.policy.basic;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.BrooklynAppUnitTestSupport;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.policy.PolicySpec;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.flags.SetFromFlag;
+
+/**
+ * Test that policy can be created and accessed, by construction and by spec
+ */
+public class BasicPolicyTest extends BrooklynAppUnitTestSupport {
+
+ public static class MyPolicy extends AbstractPolicy {
+ @SetFromFlag("intKey")
+ public static final BasicConfigKey<Integer> INT_KEY = new BasicConfigKey<Integer>(Integer.class, "bkey", "b key");
+
+ @SetFromFlag("strKey")
+ public static final ConfigKey<String> STR_KEY = new BasicConfigKey<String>(String.class, "akey", "a key");
+ public static final ConfigKey<Integer> INT_KEY_WITH_DEFAULT = new BasicConfigKey<Integer>(Integer.class, "ckey", "c key", 1);
+ public static final ConfigKey<String> STR_KEY_WITH_DEFAULT = new BasicConfigKey<String>(String.class, "strKey", "str key", "str key default");
+
+ MyPolicy(Map<?,?> flags) {
+ super(flags);
+ }
+
+ public MyPolicy() {
+ super();
+ }
+ }
+
+ @Test
+ public void testAddInstance() throws Exception {
+ MyPolicy policy = new MyPolicy();
+ policy.setDisplayName("Bob");
+ policy.setConfig(MyPolicy.STR_KEY, "aval");
+ policy.setConfig(MyPolicy.INT_KEY, 2);
+ app.addPolicy(policy);
+
+ assertEquals(policy.getDisplayName(), "Bob");
+ assertEquals(policy.getConfig(MyPolicy.STR_KEY), "aval");
+ assertEquals(policy.getConfig(MyPolicy.INT_KEY), (Integer)2);
+ }
+
+ @Test
+ public void testAddSpec() throws Exception {
+ MyPolicy policy = app.addPolicy(PolicySpec.create(MyPolicy.class)
+ .displayName("Bob")
+ .configure(MyPolicy.STR_KEY, "aval").configure(MyPolicy.INT_KEY, 2));
+
+ assertEquals(policy.getDisplayName(), "Bob");
+ assertEquals(policy.getConfig(MyPolicy.STR_KEY), "aval");
+ assertEquals(policy.getConfig(MyPolicy.INT_KEY), (Integer)2);
+ }
+
+ @Test
+ public void testTagsFromSpec() throws Exception {
+ MyPolicy policy = app.addPolicy(PolicySpec.create(MyPolicy.class).tag(99).uniqueTag("x"));
+
+ assertEquals(policy.getTags(), MutableSet.of("x", 99));
+ assertEquals(policy.getUniqueTag(), "x");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/test/java/brooklyn/policy/basic/EnricherConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/policy/basic/EnricherConfigTest.java b/core/src/test/java/brooklyn/policy/basic/EnricherConfigTest.java
deleted file mode 100644
index c8dced8..0000000
--- a/core/src/test/java/brooklyn/policy/basic/EnricherConfigTest.java
+++ /dev/null
@@ -1,169 +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 brooklyn.policy.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-
-import java.util.Map;
-
-import org.testng.annotations.Test;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.enricher.basic.AbstractEnricher;
-import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.flags.SetFromFlag;
-
-/**
- * Test that configuration properties are usable and inherited correctly.
- */
-public class EnricherConfigTest extends BrooklynAppUnitTestSupport {
-
- // TODO These tests are a copy of PolicyConfigMapUsageTest, which is a code smell.
- // However, the src/main/java code does not contain as much duplication.
-
- public static class MyEnricher extends AbstractEnricher {
- @SetFromFlag("intKey")
- public static final BasicConfigKey<Integer> INT_KEY = new BasicConfigKey<Integer>(Integer.class, "bkey", "b key");
-
- @SetFromFlag("strKey")
- public static final ConfigKey<String> STR_KEY = new BasicConfigKey<String>(String.class, "akey", "a key");
- public static final ConfigKey<Integer> INT_KEY_WITH_DEFAULT = new BasicConfigKey<Integer>(Integer.class, "ckey", "c key", 1);
- public static final ConfigKey<String> STR_KEY_WITH_DEFAULT = new BasicConfigKey<String>(String.class, "strKey", "str key", "str key default");
-
- MyEnricher(Map flags) {
- super(flags);
- }
-
- MyEnricher() {
- super();
- }
- }
-
- private BasicConfigKey<String> differentKey = new BasicConfigKey<String>(String.class, "differentkey", "diffval");
-
- @Test
- public void testConfigFlagsPassedInAtConstructionIsAvailable() throws Exception {
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put("strKey", "aval")
- .put("intKey", 2)
- .build());
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
- assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
- // this is set, because key name matches annotation on STR_KEY
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), "aval");
- }
-
- @Test
- public void testUnknownConfigPassedInAtConstructionIsWarnedAndIgnored() throws Exception {
- // TODO Also assert it's warned
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put(differentKey, "aval")
- .build());
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(differentKey), null);
- assertEquals(enricher.getEnricherType().getConfigKey(differentKey.getName()), null);
- }
-
- @Test
- public void testConfigPassedInAtConstructionIsAvailable() throws Exception {
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put(MyEnricher.STR_KEY, "aval")
- .put(MyEnricher.INT_KEY, 2)
- .build());
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
- assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
- // this is not set (contrast with above)
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), MyEnricher.STR_KEY_WITH_DEFAULT.getDefaultValue());
- }
-
- @Test
- public void testConfigSetToGroovyTruthFalseIsAvailable() throws Exception {
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put(MyEnricher.INT_KEY_WITH_DEFAULT, 0)
- .build());
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.INT_KEY_WITH_DEFAULT), (Integer)0);
- }
-
- @Test
- public void testConfigSetToNullIsAvailable() throws Exception {
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put(MyEnricher.STR_KEY_WITH_DEFAULT, null)
- .build());
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), null);
- }
-
- @Test
- public void testConfigCanBeSetOnEnricher() throws Exception {
- MyEnricher enricher = new MyEnricher();
- enricher.setConfig(MyEnricher.STR_KEY, "aval");
- enricher.setConfig(MyEnricher.INT_KEY, 2);
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
- assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
- }
-
- @Test
- public void testConfigSetterOverridesConstructorValue() throws Exception {
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put(MyEnricher.STR_KEY, "aval")
- .build());
- enricher.setConfig(MyEnricher.STR_KEY, "diffval");
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "diffval");
- }
-
- @Test
- public void testConfigCannotBeSetAfterApplicationIsStarted() throws Exception {
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put(MyEnricher.STR_KEY, "origval")
- .build());
- app.addEnricher(enricher);
-
- try {
- enricher.setConfig(MyEnricher.STR_KEY,"newval");
- fail();
- } catch (UnsupportedOperationException e) {
- // success
- }
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "origval");
- }
-
- @Test
- public void testConfigReturnsDefaultValueIfNotSet() throws Exception {
- MyEnricher enricher = new MyEnricher();
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), "str key default");
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/test/java/brooklyn/policy/basic/PolicyConfigMapUsageTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/policy/basic/PolicyConfigMapUsageTest.java b/core/src/test/java/brooklyn/policy/basic/PolicyConfigMapUsageTest.java
deleted file mode 100644
index 05611d2..0000000
--- a/core/src/test/java/brooklyn/policy/basic/PolicyConfigMapUsageTest.java
+++ /dev/null
@@ -1,222 +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 brooklyn.policy.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-
-import org.testng.annotations.Test;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.test.entity.TestEntity;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.util.concurrent.Callables;
-
-/**
- * Test that configuration properties are usable and inherited correctly.
- */
-public class PolicyConfigMapUsageTest extends BrooklynAppUnitTestSupport {
- private static final int EARLY_RETURN_GRACE = 10;
-
- public static class MyPolicy extends AbstractPolicy {
- @SetFromFlag("intKey")
- public static final BasicConfigKey<Integer> INT_KEY = new BasicConfigKey<Integer>(Integer.class, "bkey", "b key");
-
- @SetFromFlag("strKey")
- public static final ConfigKey<String> STR_KEY = new BasicConfigKey<String>(String.class, "akey", "a key");
- public static final ConfigKey<Integer> INT_KEY_WITH_DEFAULT = new BasicConfigKey<Integer>(Integer.class, "ckey", "c key", 1);
- public static final ConfigKey<String> STR_KEY_WITH_DEFAULT = new BasicConfigKey<String>(String.class, "strKey", "str key", "str key default");
-
- MyPolicy(Map flags) {
- super(flags);
- }
-
- MyPolicy() {
- super();
- }
- }
-
- private BasicConfigKey<String> differentKey = new BasicConfigKey<String>(String.class, "differentkey", "diffval");
-
- @Test
- public void testConfigFlagsPassedInAtConstructionIsAvailable() throws Exception {
- MyPolicy policy = new MyPolicy(MutableMap.builder()
- .put("strKey", "aval")
- .put("intKey", 2)
- .build());
- app.addPolicy(policy);
-
- assertEquals(policy.getConfig(MyPolicy.STR_KEY), "aval");
- assertEquals(policy.getConfig(MyPolicy.INT_KEY), (Integer)2);
- // this is set, because key name matches annotation on STR_KEY
- assertEquals(policy.getConfig(MyPolicy.STR_KEY_WITH_DEFAULT), "aval");
- }
-
- @Test
- public void testUnknownConfigPassedInAtConstructionIsWarnedAndIgnored() throws Exception {
- // TODO Also assert it's warned
- MyPolicy policy = new MyPolicy(MutableMap.builder()
- .put(differentKey, "aval")
- .build());
- app.addPolicy(policy);
-
- assertEquals(policy.getConfig(differentKey), null);
- assertEquals(policy.getPolicyType().getConfigKey(differentKey.getName()), null);
- }
-
- @Test
- public void testConfigPassedInAtConstructionIsAvailable() throws Exception {
- MyPolicy policy = new MyPolicy(MutableMap.builder()
- .put(MyPolicy.STR_KEY, "aval")
- .put(MyPolicy.INT_KEY, 2)
- .build());
- app.addPolicy(policy);
-
- assertEquals(policy.getConfig(MyPolicy.STR_KEY), "aval");
- assertEquals(policy.getConfig(MyPolicy.INT_KEY), (Integer)2);
- // this is not set (contrast with above)
- assertEquals(policy.getConfig(MyPolicy.STR_KEY_WITH_DEFAULT), MyPolicy.STR_KEY_WITH_DEFAULT.getDefaultValue());
- }
-
- @Test
- public void testConfigSetToGroovyTruthFalseIsAvailable() throws Exception {
- MyPolicy policy = new MyPolicy(MutableMap.builder()
- .put(MyPolicy.INT_KEY_WITH_DEFAULT, 0)
- .build());
- app.addPolicy(policy);
-
- assertEquals(policy.getConfig(MyPolicy.INT_KEY_WITH_DEFAULT), (Integer)0);
- }
-
- @Test
- public void testConfigSetToNullIsAvailable() throws Exception {
- MyPolicy policy = new MyPolicy(MutableMap.builder()
- .put(MyPolicy.STR_KEY_WITH_DEFAULT, null)
- .build());
- app.addPolicy(policy);
-
- assertEquals(policy.getConfig(MyPolicy.STR_KEY_WITH_DEFAULT), null);
- }
-
- @Test
- public void testConfigCanBeSetOnPolicy() throws Exception {
- MyPolicy policy = new MyPolicy();
- policy.setConfig(MyPolicy.STR_KEY, "aval");
- policy.setConfig(MyPolicy.INT_KEY, 2);
- app.addPolicy(policy);
-
- assertEquals(policy.getConfig(MyPolicy.STR_KEY), "aval");
- assertEquals(policy.getConfig(MyPolicy.INT_KEY), (Integer)2);
- }
-
- @Test
- public void testConfigSetterOverridesConstructorValue() throws Exception {
- MyPolicy policy = new MyPolicy(MutableMap.builder()
- .put(MyPolicy.STR_KEY, "aval")
- .build());
- policy.setConfig(MyPolicy.STR_KEY, "diffval");
- app.addPolicy(policy);
-
- assertEquals(policy.getConfig(MyPolicy.STR_KEY), "diffval");
- }
-
- @Test
- public void testConfigCannotBeSetAfterApplicationIsStarted() throws Exception {
- MyPolicy policy = new MyPolicy(MutableMap.builder()
- .put(MyPolicy.STR_KEY, "origval")
- .build());
- app.addPolicy(policy);
-
- try {
- policy.setConfig(MyPolicy.STR_KEY,"newval");
- fail();
- } catch (UnsupportedOperationException e) {
- // success
- }
-
- assertEquals(policy.getConfig(MyPolicy.STR_KEY), "origval");
- }
-
- @Test
- public void testConfigReturnsDefaultValueIfNotSet() throws Exception {
- MyPolicy policy = new MyPolicy();
- app.addPolicy(policy);
-
- assertEquals(policy.getConfig(MyPolicy.STR_KEY_WITH_DEFAULT), "str key default");
- }
-
- // FIXME Should we support this now?
- @Test(enabled=false)
- public void testGetFutureConfigWhenReady() throws Exception {
- MyPolicy policy = new MyPolicy(MutableMap.builder()
- .put(TestEntity.CONF_NAME, DependentConfiguration.whenDone(Callables.returning("aval")))
- .build());
- app.addPolicy(policy);
-
- assertEquals(policy.getConfig(TestEntity.CONF_NAME), "aval");
- }
-
- // FIXME Should we support this now?
- @Test(enabled=false)
- public void testGetFutureConfigBlocksUntilReady() throws Exception {
- final CountDownLatch latch = new CountDownLatch(1);
- MyPolicy policy = new MyPolicy(MutableMap.builder()
- .put(TestEntity.CONF_NAME, DependentConfiguration.whenDone(new Callable<String>() {
- public String call() {
- try {
- latch.await(); return "aval";
- } catch (InterruptedException e) {
- throw Exceptions.propagate(e);
- }
- }}))
- .build());
- app.addPolicy(policy);
-
- Thread t = new Thread(new Runnable() {
- public void run() {
- try {
- Thread.sleep(10+EARLY_RETURN_GRACE); latch.countDown();
- } catch (InterruptedException e) {
- throw Exceptions.propagate(e);
- }
- }});
- try {
- long starttime = System.currentTimeMillis();
- t.start();
- assertEquals(policy.getConfig(TestEntity.CONF_NAME), "aval");
- long endtime = System.currentTimeMillis();
-
- assertTrue((endtime - starttime) >= 10, "starttime="+starttime+"; endtime="+endtime);
-
- } finally {
- t.interrupt();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/core/src/test/java/brooklyn/policy/basic/PolicyConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/policy/basic/PolicyConfigTest.java b/core/src/test/java/brooklyn/policy/basic/PolicyConfigTest.java
new file mode 100644
index 0000000..502881b
--- /dev/null
+++ b/core/src/test/java/brooklyn/policy/basic/PolicyConfigTest.java
@@ -0,0 +1,202 @@
+/*
+ * 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 brooklyn.policy.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+
+import org.testng.annotations.Test;
+
+import brooklyn.entity.BrooklynAppUnitTestSupport;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.event.basic.DependentConfiguration;
+import brooklyn.policy.basic.BasicPolicyTest.MyPolicy;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+
+import com.google.common.util.concurrent.Callables;
+
+/**
+ * Test that configuration properties are usable and inherited correctly.
+ */
+public class PolicyConfigTest extends BrooklynAppUnitTestSupport {
+ private static final int EARLY_RETURN_GRACE = 10;
+
+ private BasicConfigKey<String> differentKey = new BasicConfigKey<String>(String.class, "differentkey", "diffval");
+
+ @Test
+ public void testConfigFlagsPassedInAtConstructionIsAvailable() throws Exception {
+ MyPolicy policy = new MyPolicy(MutableMap.builder()
+ .put("strKey", "aval")
+ .put("intKey", 2)
+ .build());
+ app.addPolicy(policy);
+
+ assertEquals(policy.getConfig(MyPolicy.STR_KEY), "aval");
+ assertEquals(policy.getConfig(MyPolicy.INT_KEY), (Integer)2);
+ // this is set, because key name matches annotation on STR_KEY
+ assertEquals(policy.getConfig(MyPolicy.STR_KEY_WITH_DEFAULT), "aval");
+ }
+
+ @Test
+ public void testUnknownConfigPassedInAtConstructionIsWarnedAndIgnored() throws Exception {
+ // TODO Also assert it's warned
+ MyPolicy policy = new MyPolicy(MutableMap.builder()
+ .put(differentKey, "aval")
+ .build());
+ app.addPolicy(policy);
+
+ assertEquals(policy.getConfig(differentKey), null);
+ assertEquals(policy.getPolicyType().getConfigKey(differentKey.getName()), null);
+ }
+
+ @Test
+ public void testConfigPassedInAtConstructionIsAvailable() throws Exception {
+ MyPolicy policy = new MyPolicy(MutableMap.builder()
+ .put(MyPolicy.STR_KEY, "aval")
+ .put(MyPolicy.INT_KEY, 2)
+ .build());
+ app.addPolicy(policy);
+
+ assertEquals(policy.getConfig(MyPolicy.STR_KEY), "aval");
+ assertEquals(policy.getConfig(MyPolicy.INT_KEY), (Integer)2);
+ // this is not set (contrast with above)
+ assertEquals(policy.getConfig(MyPolicy.STR_KEY_WITH_DEFAULT), MyPolicy.STR_KEY_WITH_DEFAULT.getDefaultValue());
+ }
+
+ @Test
+ public void testConfigSetToGroovyTruthFalseIsAvailable() throws Exception {
+ MyPolicy policy = new MyPolicy(MutableMap.builder()
+ .put(MyPolicy.INT_KEY_WITH_DEFAULT, 0)
+ .build());
+ app.addPolicy(policy);
+
+ assertEquals(policy.getConfig(MyPolicy.INT_KEY_WITH_DEFAULT), (Integer)0);
+ }
+
+ @Test
+ public void testConfigSetToNullIsAvailable() throws Exception {
+ MyPolicy policy = new MyPolicy(MutableMap.builder()
+ .put(MyPolicy.STR_KEY_WITH_DEFAULT, null)
+ .build());
+ app.addPolicy(policy);
+
+ assertEquals(policy.getConfig(MyPolicy.STR_KEY_WITH_DEFAULT), null);
+ }
+
+ @Test
+ public void testConfigCanBeSetOnPolicy() throws Exception {
+ MyPolicy policy = new MyPolicy();
+ policy.setConfig(MyPolicy.STR_KEY, "aval");
+ policy.setConfig(MyPolicy.INT_KEY, 2);
+ app.addPolicy(policy);
+
+ assertEquals(policy.getConfig(MyPolicy.STR_KEY), "aval");
+ assertEquals(policy.getConfig(MyPolicy.INT_KEY), (Integer)2);
+ }
+
+ @Test
+ public void testConfigSetterOverridesConstructorValue() throws Exception {
+ MyPolicy policy = new MyPolicy(MutableMap.builder()
+ .put(MyPolicy.STR_KEY, "aval")
+ .build());
+ policy.setConfig(MyPolicy.STR_KEY, "diffval");
+ app.addPolicy(policy);
+
+ assertEquals(policy.getConfig(MyPolicy.STR_KEY), "diffval");
+ }
+
+ @Test
+ public void testConfigCannotBeSetAfterApplicationIsStarted() throws Exception {
+ MyPolicy policy = new MyPolicy(MutableMap.builder()
+ .put(MyPolicy.STR_KEY, "origval")
+ .build());
+ app.addPolicy(policy);
+
+ try {
+ policy.setConfig(MyPolicy.STR_KEY,"newval");
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // success
+ }
+
+ assertEquals(policy.getConfig(MyPolicy.STR_KEY), "origval");
+ }
+
+ @Test
+ public void testConfigReturnsDefaultValueIfNotSet() throws Exception {
+ MyPolicy policy = new MyPolicy();
+ app.addPolicy(policy);
+
+ assertEquals(policy.getConfig(MyPolicy.STR_KEY_WITH_DEFAULT), "str key default");
+ }
+
+ // FIXME Should we support this now?
+ @Test(enabled=false)
+ public void testGetFutureConfigWhenReady() throws Exception {
+ MyPolicy policy = new MyPolicy(MutableMap.builder()
+ .put(TestEntity.CONF_NAME, DependentConfiguration.whenDone(Callables.returning("aval")))
+ .build());
+ app.addPolicy(policy);
+
+ assertEquals(policy.getConfig(TestEntity.CONF_NAME), "aval");
+ }
+
+ // FIXME Should we support this now?
+ @Test(enabled=false)
+ public void testGetFutureConfigBlocksUntilReady() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ MyPolicy policy = new MyPolicy(MutableMap.builder()
+ .put(TestEntity.CONF_NAME, DependentConfiguration.whenDone(new Callable<String>() {
+ public String call() {
+ try {
+ latch.await(); return "aval";
+ } catch (InterruptedException e) {
+ throw Exceptions.propagate(e);
+ }
+ }}))
+ .build());
+ app.addPolicy(policy);
+
+ Thread t = new Thread(new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(10+EARLY_RETURN_GRACE); latch.countDown();
+ } catch (InterruptedException e) {
+ throw Exceptions.propagate(e);
+ }
+ }});
+ try {
+ long starttime = System.currentTimeMillis();
+ t.start();
+ assertEquals(policy.getConfig(TestEntity.CONF_NAME), "aval");
+ long endtime = System.currentTimeMillis();
+
+ assertTrue((endtime - starttime) >= 10, "starttime="+starttime+"; endtime="+endtime);
+
+ } finally {
+ t.interrupt();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
index 2457812..53e31e0 100644
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
+++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
@@ -142,6 +142,7 @@ public class BrooklynAssemblyTemplateInstantiator implements AssemblyTemplateSpe
// if promoted, apply the transformations done to the app
// (normally this will be done by the resolveSpec call above)
if (app.getDisplayName()==null) app.displayName(oldApp.getDisplayName());
+ app.tags(oldApp.getTags());
app.locations(oldApp.getLocations());
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/72b52e1d/utils/common/src/main/java/brooklyn/util/guava/TypeTokens.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/guava/TypeTokens.java b/utils/common/src/main/java/brooklyn/util/guava/TypeTokens.java
index ca69a97..d16d2df 100644
--- a/utils/common/src/main/java/brooklyn/util/guava/TypeTokens.java
+++ b/utils/common/src/main/java/brooklyn/util/guava/TypeTokens.java
@@ -18,6 +18,10 @@
*/
package brooklyn.util.guava;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
import javax.annotation.Nullable;
import com.google.common.reflect.TypeToken;
@@ -68,5 +72,20 @@ public class TypeTokens {
public static <T> Class<T> getRawRawType(TypeToken<T> token) {
return (Class)token.getRawType();
}
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static <T> TypeToken<Set<T>> setOf(Class<T> type) {
+ return (TypeToken) TypeToken.of(Set.class);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static <K,V> TypeToken<Map<K,V>> mapOf(Class<K> key, Class<V> value) {
+ return (TypeToken) TypeToken.of(Map.class);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static <T> TypeToken<List<T>> listOf(Class<T> type) {
+ return (TypeToken) TypeToken.of(List.class);
+ }
}