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/07 23:55:35 UTC
[1/9] git commit: Adds BrooklynType super-class
Repository: incubator-brooklyn
Updated Branches:
refs/heads/master 4891355f7 -> d4a6328eb
Adds BrooklynType super-class
- use PolicyDynamicType and EnricherDynamicType, deleting previous
classes.
- adds BrooklynTypes, deprecating old EntityTypes
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/d9594b36
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/d9594b36
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/d9594b36
Branch: refs/heads/master
Commit: d9594b36c1861d58fbb03ed9e2787234294c5dc4
Parents: 371a351
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 6 16:21:17 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 6 22:10:35 2014 +0100
----------------------------------------------------------------------
.../main/java/brooklyn/basic/BrooklynType.java | 54 ++++
.../main/java/brooklyn/entity/EntityType.java | 24 +-
.../main/java/brooklyn/policy/EnricherType.java | 24 +-
.../main/java/brooklyn/policy/PolicyType.java | 22 +-
.../brooklyn/basic/BrooklynDynamicType.java | 287 +++++++++++++++++++
.../brooklyn/basic/BrooklynTypeSnapshot.java | 100 +++++++
.../main/java/brooklyn/basic/BrooklynTypes.java | 119 ++++++++
.../enricher/basic/AbstractEnricher.java | 12 +-
.../enricher/basic/EnricherDynamicType.java | 39 +++
.../enricher/basic/EnricherTypeSnapshot.java | 39 +++
.../brooklyn/entity/basic/AbstractEntity.java | 2 -
.../entity/basic/EntityDynamicType.java | 252 ++--------------
.../entity/basic/EntityTypeSnapshot.java | 58 +---
.../java/brooklyn/entity/basic/EntityTypes.java | 86 +-----
.../entity/rebind/dto/BasicEntityMemento.java | 6 +-
.../entity/rebind/dto/MementosGenerators.java | 4 +-
.../brooklyn/policy/basic/AbstractPolicy.java | 14 +-
.../brooklyn/policy/basic/EnricherTypeImpl.java | 75 -----
.../policy/basic/PolicyDynamicType.java | 39 +++
.../brooklyn/policy/basic/PolicyTypeImpl.java | 75 -----
.../policy/basic/PolicyTypeSnapshot.java | 39 +++
.../rest/transform/CatalogTransformer.java | 4 +-
.../rest/util/BrooklynRestResourceUtils.java | 4 +-
23 files changed, 782 insertions(+), 596 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/api/src/main/java/brooklyn/basic/BrooklynType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/basic/BrooklynType.java b/api/src/main/java/brooklyn/basic/BrooklynType.java
new file mode 100644
index 0000000..fe1efe2
--- /dev/null
+++ b/api/src/main/java/brooklyn/basic/BrooklynType.java
@@ -0,0 +1,54 @@
+/*
+ * 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.basic;
+
+import java.io.Serializable;
+import java.util.Set;
+
+import brooklyn.config.ConfigKey;
+
+/**
+ * Gives type information for a {@link BrooklynObject}. It is an immutable snapshot.
+ *
+ * It reflects a given brooklyn object at the time the snapshot was created: if anything
+ * were added or removed on-the-fly then those changes will be included in subsequent
+ * snapshots. Therefore instances of a given class could have different {@link BrooklynType}s.
+ */
+public interface BrooklynType extends Serializable {
+
+ /**
+ * The type name of this entity (normally the fully qualified class name).
+ */
+ String getName();
+
+ /**
+ * The simple type name of this entity (normally the unqualified class name).
+ */
+ String getSimpleName();
+
+ /**
+ * ConfigKeys available on this entity.
+ */
+ Set<ConfigKey<?>> getConfigKeys();
+
+ /**
+ * The ConfigKey with the given name, or null if not found.
+ */
+ ConfigKey<?> getConfigKey(String name);
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/api/src/main/java/brooklyn/entity/EntityType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/entity/EntityType.java b/api/src/main/java/brooklyn/entity/EntityType.java
index 78d1d77..de8bdfe 100644
--- a/api/src/main/java/brooklyn/entity/EntityType.java
+++ b/api/src/main/java/brooklyn/entity/EntityType.java
@@ -18,10 +18,10 @@
*/
package brooklyn.entity;
-import java.io.Serializable;
import java.util.NoSuchElementException;
import java.util.Set;
+import brooklyn.basic.BrooklynType;
import brooklyn.config.ConfigKey;
import brooklyn.event.Sensor;
import brooklyn.util.guava.Maybe;
@@ -34,24 +34,9 @@ import brooklyn.util.guava.Maybe;
* snapshots. Therefore instances of a given class of entity could have different
* EntityTypes.
*/
-public interface EntityType extends Serializable {
+public interface EntityType extends BrooklynType {
/**
- * The type name of this entity (normally the fully qualified class name).
- */
- String getName();
-
- /**
- * The simple type name of this entity (normally the unqualified class name).
- */
- String getSimpleName();
-
- /**
- * ConfigKeys available on this entity.
- */
- Set<ConfigKey<?>> getConfigKeys();
-
- /**
* Sensors available on this entity.
*/
Set<Sensor<?>> getSensors();
@@ -77,11 +62,6 @@ public interface EntityType extends Serializable {
Effector<?> getEffector(String name, Class<?>... parameterTypes);
/**
- * The ConfigKey with the given name, or null if not found.
- */
- ConfigKey<?> getConfigKey(String name);
-
- /**
* The Sensor with the given name, or null if not found.
*/
Sensor<?> getSensor(String name);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/api/src/main/java/brooklyn/policy/EnricherType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/policy/EnricherType.java b/api/src/main/java/brooklyn/policy/EnricherType.java
index 35a1301..dc59423 100644
--- a/api/src/main/java/brooklyn/policy/EnricherType.java
+++ b/api/src/main/java/brooklyn/policy/EnricherType.java
@@ -18,10 +18,7 @@
*/
package brooklyn.policy;
-import java.io.Serializable;
-import java.util.Set;
-
-import brooklyn.config.ConfigKey;
+import brooklyn.basic.BrooklynType;
import com.google.common.annotations.Beta;
@@ -35,22 +32,5 @@ import com.google.common.annotations.Beta;
* @since 0.6
*/
@Beta
-public interface EnricherType extends Serializable {
-
- // TODO Consider merging this with PolicyType? Have a common super-type? It also has overlap with EntityType.
-
- /**
- * The type name of this policy (normally the fully qualified class name).
- */
- String getName();
-
- /**
- * ConfigKeys available on this policy.
- */
- Set<ConfigKey<?>> getConfigKeys();
-
- /**
- * The ConfigKey with the given name, or null if not found.
- */
- ConfigKey<?> getConfigKey(String name);
+public interface EnricherType extends BrooklynType {
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/api/src/main/java/brooklyn/policy/PolicyType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/policy/PolicyType.java b/api/src/main/java/brooklyn/policy/PolicyType.java
index 207d727..707b4aa 100644
--- a/api/src/main/java/brooklyn/policy/PolicyType.java
+++ b/api/src/main/java/brooklyn/policy/PolicyType.java
@@ -18,10 +18,7 @@
*/
package brooklyn.policy;
-import java.io.Serializable;
-import java.util.Set;
-
-import brooklyn.config.ConfigKey;
+import brooklyn.basic.BrooklynType;
import com.google.common.annotations.Beta;
@@ -35,20 +32,5 @@ import com.google.common.annotations.Beta;
* @since 0.5
*/
@Beta
-public interface PolicyType extends Serializable {
-
- /**
- * The type name of this policy (normally the fully qualified class name).
- */
- String getName();
-
- /**
- * ConfigKeys available on this policy.
- */
- Set<ConfigKey<?>> getConfigKeys();
-
- /**
- * The ConfigKey with the given name, or null if not found.
- */
- ConfigKey<?> getConfigKey(String name);
+public interface PolicyType extends BrooklynType {
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java b/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
new file mode 100644
index 0000000..637841e
--- /dev/null
+++ b/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
@@ -0,0 +1,287 @@
+/*
+ * 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.basic;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+import brooklyn.event.basic.BasicConfigKey.BasicConfigKeyOverwriting;
+import brooklyn.util.flags.FlagUtils;
+import brooklyn.util.javalang.Reflections;
+import brooklyn.util.text.Strings;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Lists;
+
+/**
+ * This is the actual type of a brooklyn object instance at runtime,
+ * which can change from the static {@link BrooklynType}, and can change over time;
+ * for this reason it does *not* implement BrooklynType, but
+ * callers can call {@link #getSnapshot()} to get a snapshot such instance.
+ */
+public abstract class BrooklynDynamicType<T extends BrooklynObject, AbstractT extends AbstractBrooklynObject> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BrooklynDynamicType.class);
+
+ protected final Class<? extends T> brooklynClass;
+ protected final AbstractT instance;
+ protected volatile String name;
+
+ /**
+ * Map of config keys (and their fields) on this instance, by name.
+ */
+ protected final Map<String,FieldAndValue<ConfigKey<?>>> configKeys = new ConcurrentHashMap<String, FieldAndValue<ConfigKey<?>>>();
+
+ private volatile BrooklynTypeSnapshot snapshot;
+ private final AtomicBoolean snapshotValid = new AtomicBoolean(false);
+
+ public BrooklynDynamicType(AbstractT instance) {
+ this((Class<? extends T>) instance.getClass(), instance);
+ }
+ public BrooklynDynamicType(Class<? extends T> clazz) {
+ this(clazz, null);
+ }
+ protected BrooklynDynamicType(Class<? extends T> clazz, AbstractT instance) {
+ this.brooklynClass = checkNotNull(clazz, "brooklyn class");
+ this.instance = instance;
+ // NB: official name is usu injected later, e.g. from AbstractEntity.setManagementContext
+ setName((clazz.getCanonicalName() == null) ? clazz.getName() : clazz.getCanonicalName());
+
+ String id = instance==null ? clazz.getName() : instance.getId();
+
+ buildConfigKeys(clazz, null, configKeys);
+ if (LOG.isTraceEnabled())
+ LOG.trace("Entity {} config keys: {}", id, Joiner.on(", ").join(configKeys.keySet()));
+
+ refreshSnapshot();
+ }
+
+ protected abstract BrooklynTypeSnapshot newSnapshot();
+
+ protected void invalidateSnapshot() {
+ snapshotValid.set(false);
+ }
+
+ public void setName(String name) {
+ if (Strings.isBlank(name)) {
+ throw new IllegalArgumentException("Invalid name "+(name == null ? "null" : "'"+name+"'")+"; name must be non-empty and not just white space");
+ }
+ this.name = name;
+ invalidateSnapshot();
+ }
+
+ public synchronized BrooklynType getSnapshot() {
+ return refreshSnapshot();
+ }
+
+ public Class<? extends T> getBrooklynClass() {
+ return brooklynClass;
+ }
+
+ // --------------------------------------------------
+
+ /**
+ * ConfigKeys available on this entity.
+ */
+ public Map<String,ConfigKey<?>> getConfigKeys() {
+ return Collections.unmodifiableMap(value(configKeys));
+ }
+
+ /**
+ * ConfigKeys available on this entity.
+ */
+ public ConfigKey<?> getConfigKey(String keyName) {
+ return value(configKeys.get(keyName));
+ }
+
+ /** field where a config key is defined, for use getting annotations. note annotations are not inherited. */
+ public Field getConfigKeyField(String keyName) {
+ return field(configKeys.get(keyName));
+ }
+
+ protected BrooklynTypeSnapshot refreshSnapshot() {
+ if (snapshotValid.compareAndSet(false, true)) {
+ snapshot = newSnapshot();
+ }
+ return snapshot;
+ }
+
+ /**
+ * Finds the config keys defined on the entity's class, statics and optionally any non-static (discouraged).
+ * Prefers keys which overwrite other keys, and prefers keys which are lower in the hierarchy;
+ * logs warnings if there are two conflicting keys which don't have an overwriting relationship.
+ */
+ protected static void buildConfigKeys(Class<? extends BrooklynObject> clazz, AbstractBrooklynObject optionalInstance,
+ Map<String, FieldAndValue<ConfigKey<?>>> configKeys) {
+ ListMultimap<String,FieldAndValue<ConfigKey<?>>> configKeysAll =
+ ArrayListMultimap.<String, FieldAndValue<ConfigKey<?>>>create();
+
+ for (Field f : FlagUtils.getAllFields(clazz)) {
+ boolean isConfigKey = ConfigKey.class.isAssignableFrom(f.getType());
+ if (!isConfigKey) {
+ if (!HasConfigKey.class.isAssignableFrom(f.getType())) {
+ // neither ConfigKey nor HasConfigKey
+ continue;
+ }
+ }
+ if (!Modifier.isStatic(f.getModifiers())) {
+ // require it to be static or we have an instance
+ LOG.warn("Discouraged use of non-static config key "+f+" defined in " + (optionalInstance!=null ? optionalInstance : clazz));
+ if (optionalInstance==null) continue;
+ }
+ try {
+ ConfigKey<?> k = isConfigKey ? (ConfigKey<?>) f.get(optionalInstance) :
+ ((HasConfigKey<?>)f.get(optionalInstance)).getConfigKey();
+
+ if (k==null) {
+ LOG.warn("no value defined for config key field (skipping): "+f);
+ } else {
+ configKeysAll.put(k.getName(), new FieldAndValue<ConfigKey<?>>(f, k));
+ }
+
+ } catch (IllegalAccessException e) {
+ LOG.warn("cannot access config key (skipping): "+f);
+ }
+ }
+ LinkedHashSet<String> keys = new LinkedHashSet<String>(configKeysAll.keys());
+ for (String kn: keys) {
+ List<FieldAndValue<ConfigKey<?>>> kk = Lists.newArrayList(configKeysAll.get(kn));
+ if (kk.size()>1) {
+ // remove anything which extends another value in the list
+ for (FieldAndValue<ConfigKey<?>> k: kk) {
+ ConfigKey<?> key = value(k);
+ if (key instanceof BasicConfigKeyOverwriting) {
+ ConfigKey<?> parent = ((BasicConfigKeyOverwriting<?>)key).getParentKey();
+ // find and remove the parent from consideration
+ for (FieldAndValue<ConfigKey<?>> k2: kk) {
+ if (value(k2) == parent)
+ configKeysAll.remove(kn, k2);
+ }
+ }
+ }
+ kk = Lists.newArrayList(configKeysAll.get(kn));
+ }
+ // multiple keys, not overwriting; if their values are the same then we don't mind
+ FieldAndValue<ConfigKey<?>> best = null;
+ for (FieldAndValue<ConfigKey<?>> k: kk) {
+ if (best==null) {
+ best=k;
+ } else {
+ Field lower = Reflections.inferSubbestField(k.field, best.field);
+ ConfigKey<? extends Object> lowerV = lower==null ? null : lower.equals(k.field) ? k.value : best.value;
+ if (best.value == k.value) {
+ // same value doesn't matter which we take (but take lower if there is one)
+ if (LOG.isTraceEnabled())
+ LOG.trace("multiple definitions for config key {} on {}; same value {}; " +
+ "from {} and {}, preferring {}",
+ new Object[] {
+ best.value.getName(), optionalInstance!=null ? optionalInstance : clazz,
+ best.value.getDefaultValue(),
+ k.field, best.field, lower});
+ best = new FieldAndValue<ConfigKey<?>>(lower!=null ? lower : best.field, best.value);
+ } else if (lower!=null) {
+ // different value, but one clearly lower (in type hierarchy)
+ if (LOG.isTraceEnabled())
+ LOG.trace("multiple definitions for config key {} on {}; " +
+ "from {} and {}, preferring lower {}, value {}",
+ new Object[] {
+ best.value.getName(), optionalInstance!=null ? optionalInstance : clazz,
+ k.field, best.field, lower,
+ lowerV.getDefaultValue() });
+ best = new FieldAndValue<ConfigKey<?>>(lower, lowerV);
+ } else {
+ // different value, neither one lower than another in hierarchy
+ LOG.warn("multiple ambiguous definitions for config key {} on {}; " +
+ "from {} and {}, values {} and {}; " +
+ "keeping latter (arbitrarily)",
+ new Object[] {
+ best.value.getName(), optionalInstance!=null ? optionalInstance : clazz,
+ k.field, best.field,
+ k.value.getDefaultValue(), best.value.getDefaultValue() });
+ // (no change)
+ }
+ }
+ }
+ if (best==null) {
+ // shouldn't happen
+ LOG.error("Error - no matching config key from "+kk+" in class "+clazz+", even though had config key name "+kn);
+ continue;
+ } else {
+ configKeys.put(best.value.getName(), best);
+ }
+ }
+ }
+
+ protected static class FieldAndValue<V> {
+ public final Field field;
+ public final V value;
+ public FieldAndValue(Field field, V value) {
+ this.field = field;
+ this.value = value;
+ }
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this).add("field", field).add("value", value).toString();
+ }
+ }
+
+ protected static <V> V value(FieldAndValue<V> fv) {
+ if (fv==null) return null;
+ return fv.value;
+ }
+
+ protected static Field field(FieldAndValue<?> fv) {
+ if (fv==null) return null;
+ return fv.field;
+ }
+
+ @SuppressWarnings("unused")
+ protected static <V> Collection<V> value(Collection<FieldAndValue<V>> fvs) {
+ List<V> result = new ArrayList<V>();
+ for (FieldAndValue<V> fv: fvs) result.add(value(fv));
+ return result;
+ }
+
+ protected static <K,V> Map<K,V> value(Map<K,FieldAndValue<V>> fvs) {
+ Map<K,V> result = new LinkedHashMap<K,V>();
+ for (K key: fvs.keySet())
+ result.put(key, value(fvs.get(key)));
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/basic/BrooklynTypeSnapshot.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/BrooklynTypeSnapshot.java b/core/src/main/java/brooklyn/basic/BrooklynTypeSnapshot.java
new file mode 100644
index 0000000..61e31a0
--- /dev/null
+++ b/core/src/main/java/brooklyn/basic/BrooklynTypeSnapshot.java
@@ -0,0 +1,100 @@
+/*
+ * 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.basic;
+
+import java.util.Map;
+import java.util.Set;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.util.text.Strings;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+public class BrooklynTypeSnapshot implements BrooklynType {
+ private static final long serialVersionUID = 4670930188951106009L;
+
+ private final String name;
+ private transient volatile String simpleName;
+ private final Map<String, ConfigKey<?>> configKeys;
+ private final Set<ConfigKey<?>> configKeysSet;
+
+ protected BrooklynTypeSnapshot(String name, Map<String, ConfigKey<?>> configKeys) {
+ this.name = name;
+ this.configKeys = ImmutableMap.copyOf(configKeys);
+ this.configKeysSet = ImmutableSet.copyOf(this.configKeys.values());
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ private String toSimpleName(String name) {
+ String simpleName = name.substring(name.lastIndexOf(".")+1);
+ if (Strings.isBlank(simpleName)) simpleName = name.trim();
+ return Strings.makeValidFilename(simpleName);
+ }
+
+ @Override
+ public String getSimpleName() {
+ String sn = simpleName;
+ if (sn==null) {
+ sn = toSimpleName(getName());
+ simpleName = sn;
+ }
+ return sn;
+ }
+
+ @Override
+ public Set<ConfigKey<?>> getConfigKeys() {
+ return configKeysSet;
+ }
+
+ @Override
+ public ConfigKey<?> getConfigKey(String name) {
+ return configKeys.get(name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name, configKeys);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (!(obj instanceof BrooklynTypeSnapshot)) return false;
+ BrooklynTypeSnapshot o = (BrooklynTypeSnapshot) obj;
+
+ return Objects.equal(name, o.name) && Objects.equal(configKeys, o.configKeys);
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper().toString();
+ }
+
+ protected ToStringHelper toStringHelper() {
+ return Objects.toStringHelper(name)
+ .add("configKeys", configKeys);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/basic/BrooklynTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/BrooklynTypes.java b/core/src/main/java/brooklyn/basic/BrooklynTypes.java
new file mode 100644
index 0000000..c2052c7
--- /dev/null
+++ b/core/src/main/java/brooklyn/basic/BrooklynTypes.java
@@ -0,0 +1,119 @@
+/*
+ * 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.basic;
+
+import java.util.Map;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.EntityDynamicType;
+import brooklyn.event.Sensor;
+import brooklyn.util.exceptions.Exceptions;
+
+import com.google.common.collect.Maps;
+
+public class BrooklynTypes {
+
+ private static class ImmutableEntityType extends EntityDynamicType {
+ public ImmutableEntityType(Class<? extends Entity> clazz) {
+ super(clazz);
+ }
+ @Override
+ public void setName(String name) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public void addSensor(Sensor<?> newSensor) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public void addSensorIfAbsent(Sensor<?> newSensor) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public Sensor<?> addSensorIfAbsentWithoutPublishing(Sensor<?> newSensor) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public void addSensors(Iterable<? extends Sensor<?>> newSensors) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public boolean removeSensor(Sensor<?> sensor) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public Sensor<?> removeSensor(String sensorName) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ private static final Map<Class,BrooklynDynamicType<?,?>> cache = Maps.newConcurrentMap();
+
+ public static EntityDynamicType getDefinedEntityType(Class<? extends Entity> entityClass) {
+ return (EntityDynamicType) BrooklynTypes.getDefinedBrooklynType(entityClass);
+ }
+
+ private static BrooklynDynamicType<?,?> getDefinedBrooklynType(Class<? extends BrooklynObject> brooklynClass) {
+ BrooklynDynamicType<?,?> t = cache.get(brooklynClass);
+ if (t!=null) return t;
+ return loadDefinedBrooklynType(brooklynClass);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static synchronized BrooklynDynamicType<?,?> loadDefinedBrooklynType(Class<? extends BrooklynObject> brooklynClass) {
+ BrooklynDynamicType<?,?> type = cache.get(brooklynClass);
+ if (type != null) return type;
+
+ if (Entity.class.isAssignableFrom(brooklynClass)) {
+ type = new ImmutableEntityType((Class<? extends Entity>)brooklynClass);
+ } else {
+ throw new IllegalStateException("Invalid brooklyn type "+brooklynClass);
+ }
+ cache.put(brooklynClass, type);
+ return type;
+ }
+
+ public static Map<String, ConfigKey<?>> getDefinedConfigKeys(Class<? extends BrooklynObject> brooklynClass) {
+ return getDefinedBrooklynType(brooklynClass).getConfigKeys();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Map<String, ConfigKey<?>> getDefinedConfigKeys(String brooklynTypeName) {
+ try {
+ return getDefinedConfigKeys((Class<? extends BrooklynObject>) Class.forName(brooklynTypeName));
+ } catch (ClassNotFoundException e) {
+ throw Exceptions.propagate(e);
+ }
+ }
+
+ public static Map<String, Sensor<?>> getDefinedSensors(Class<? extends Entity> entityClass) {
+ return getDefinedEntityType(entityClass).getSensors();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Map<String, Sensor<?>> getDefinedSensors(String entityTypeName) {
+ try {
+ return getDefinedSensors((Class<? extends Entity>) Class.forName(entityTypeName));
+ } catch (ClassNotFoundException e) {
+ throw Exceptions.propagate(e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/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..68120d9 100644
--- a/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
+++ b/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
@@ -26,7 +26,6 @@ import brooklyn.mementos.EnricherMemento;
import brooklyn.policy.Enricher;
import brooklyn.policy.EnricherType;
import brooklyn.policy.basic.AbstractEntityAdjunct;
-import brooklyn.policy.basic.EnricherTypeImpl;
import com.google.common.collect.Maps;
@@ -35,15 +34,16 @@ import com.google.common.collect.Maps;
*/
public abstract class AbstractEnricher extends AbstractEntityAdjunct implements Enricher {
- private final EnricherType enricherType;
-
+ private final EnricherDynamicType enricherType;
+
public AbstractEnricher() {
this(Maps.newLinkedHashMap());
}
- public AbstractEnricher(Map flags) {
+ public AbstractEnricher(Map<?,?> flags) {
super(flags);
- enricherType = new EnricherTypeImpl(getAdjunctType());
+
+ enricherType = new EnricherDynamicType(this);
if (isLegacyConstruction() && !isLegacyNoConstructionInit()) {
init();
@@ -57,7 +57,7 @@ public abstract class AbstractEnricher extends AbstractEntityAdjunct implements
@Override
public EnricherType getEnricherType() {
- return enricherType;
+ return enricherType.getSnapshot();
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java b/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java
new file mode 100644
index 0000000..9217c3d
--- /dev/null
+++ b/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java
@@ -0,0 +1,39 @@
+/*
+ * 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 brooklyn.basic.BrooklynDynamicType;
+import brooklyn.policy.Enricher;
+import brooklyn.policy.EnricherType;
+
+public class EnricherDynamicType extends BrooklynDynamicType<Enricher, AbstractEnricher> {
+
+ public EnricherDynamicType(AbstractEnricher enricher) {
+ super(enricher);
+ }
+
+ public EnricherType getSnapshot() {
+ return (EnricherType) super.getSnapshot();
+ }
+
+ @Override
+ protected EnricherTypeSnapshot newSnapshot() {
+ return new EnricherTypeSnapshot(name, value(configKeys));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/enricher/basic/EnricherTypeSnapshot.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/enricher/basic/EnricherTypeSnapshot.java b/core/src/main/java/brooklyn/enricher/basic/EnricherTypeSnapshot.java
new file mode 100644
index 0000000..86e1f26
--- /dev/null
+++ b/core/src/main/java/brooklyn/enricher/basic/EnricherTypeSnapshot.java
@@ -0,0 +1,39 @@
+/*
+ * 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 java.util.Map;
+
+import brooklyn.basic.BrooklynTypeSnapshot;
+import brooklyn.config.ConfigKey;
+import brooklyn.policy.EnricherType;
+
+public class EnricherTypeSnapshot extends BrooklynTypeSnapshot implements EnricherType {
+ private static final long serialVersionUID = 4670930188951106009L;
+
+ EnricherTypeSnapshot(String name, Map<String, ConfigKey<?>> configKeys) {
+ super(name, configKeys);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ return (obj instanceof EnricherTypeSnapshot) && super.equals(obj);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/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..3b8baec 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;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java b/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java
index 468e538..14500d3 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java
@@ -21,21 +21,15 @@ package brooklyn.entity.basic;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicBoolean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import brooklyn.config.ConfigKey;
+import brooklyn.basic.BrooklynDynamicType;
import brooklyn.config.ConfigKey.HasConfigKey;
import brooklyn.entity.Effector;
import brooklyn.entity.Entity;
@@ -47,18 +41,11 @@ import brooklyn.entity.effector.EffectorTasks.EffectorTaskFactory;
import brooklyn.entity.effector.EffectorWithBody;
import brooklyn.entity.effector.Effectors;
import brooklyn.event.Sensor;
-import brooklyn.event.basic.BasicConfigKey.BasicConfigKeyOverwriting;
-import brooklyn.util.flags.FlagUtils;
import brooklyn.util.javalang.Reflections;
-import brooklyn.util.text.Strings;
import com.google.common.annotations.Beta;
import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
import com.google.common.base.Throwables;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/** This is the actual type of an entity instance at runtime,
@@ -66,14 +53,10 @@ import com.google.common.collect.Maps;
* for this reason it does *not* implement EntityType, but
* callers can call {@link #getSnapshot()} to get a snapshot such instance
*/
-public class EntityDynamicType {
+public class EntityDynamicType extends BrooklynDynamicType<Entity, AbstractEntity> {
private static final Logger LOG = LoggerFactory.getLogger(EntityDynamicType.class);
- private final Class<? extends Entity> entityClass;
- private final AbstractEntity entity;
- private volatile String name;
-
/**
* Effectors on this entity, by name.
*/
@@ -85,14 +68,6 @@ public class EntityDynamicType {
*/
private final ConcurrentMap<String,Sensor<?>> sensors = new ConcurrentHashMap<String, Sensor<?>>();
- /**
- * Map of config keys (and their fields) on this entity, by name.
- */
- private final Map<String,FieldAndValue<ConfigKey<?>>> configKeys = new ConcurrentHashMap<String, FieldAndValue<ConfigKey<?>>>();
-
- private volatile EntityTypeSnapshot snapshot;
- private final AtomicBoolean snapshotValid = new AtomicBoolean(false);
-
public EntityDynamicType(AbstractEntity entity) {
this(entity.getClass(), entity);
}
@@ -100,11 +75,7 @@ public class EntityDynamicType {
this(clazz, null);
}
private EntityDynamicType(Class<? extends Entity> clazz, AbstractEntity entity) {
- this.entityClass = clazz;
- this.entity = entity;
- // NB: official name is usu injected later, from AbstractEntity.setManagementContext
- setName((clazz.getCanonicalName() == null) ? clazz.getName() : clazz.getCanonicalName());
-
+ super(clazz, entity);
String id = entity==null ? clazz.getName() : entity.getId();
effectors.putAll(findEffectors(clazz, null));
@@ -115,29 +86,21 @@ public class EntityDynamicType {
if (LOG.isTraceEnabled())
LOG.trace("Entity {} sensors: {}", id, Joiner.on(", ").join(sensors.keySet()));
- buildConfigKeys(clazz, null, configKeys);
- if (LOG.isTraceEnabled())
- LOG.trace("Entity {} config keys: {}", id, Joiner.on(", ").join(configKeys.keySet()));
-
refreshSnapshot();
}
- public void setName(String name) {
- if (Strings.isBlank(name)) {
- throw new IllegalArgumentException("Invalid name "+(name == null ? "null" : "'"+name+"'")+"; name must be non-empty and not just white space");
- }
- this.name = name;
- snapshotValid.set(false);
- }
-
- public synchronized EntityType getSnapshot() {
- return refreshSnapshot();
- }
-
+ /**
+ * @deprecated since 0.7; unused code; instead use {@link #getBrooklynClass()}
+ */
+ @Deprecated
public Class<? extends Entity> getEntityClass() {
- return entityClass;
+ return super.getBrooklynClass();
}
+ public EntityType getSnapshot() {
+ return (EntityType) super.getSnapshot();
+ }
+
// --------------------------------------------------
/**
@@ -160,11 +123,11 @@ public class EntityDynamicType {
@Beta
public void addEffector(Effector<?> newEffector) {
Effector<?> oldEffector = effectors.put(newEffector.getName(), newEffector);
- snapshotValid.set(false);
+ invalidateSnapshot();
if (oldEffector!=null)
- entity.emit(AbstractEntity.EFFECTOR_CHANGED, newEffector.getName());
+ instance.emit(AbstractEntity.EFFECTOR_CHANGED, newEffector.getName());
else
- entity.emit(AbstractEntity.EFFECTOR_ADDED, newEffector.getName());
+ instance.emit(AbstractEntity.EFFECTOR_ADDED, newEffector.getName());
}
/** Adds an effector with an explicit body */
@@ -199,8 +162,8 @@ public class EntityDynamicType {
*/
public void addSensor(Sensor<?> newSensor) {
sensors.put(newSensor.getName(), newSensor);
- snapshotValid.set(false);
- entity.emit(AbstractEntity.SENSOR_ADDED, newSensor);
+ invalidateSnapshot();
+ instance.emit(AbstractEntity.SENSOR_ADDED, newSensor);
}
/**
@@ -215,14 +178,14 @@ public class EntityDynamicType {
public void addSensorIfAbsent(Sensor<?> newSensor) {
Sensor<?> prev = addSensorIfAbsentWithoutPublishing(newSensor);
if (prev == null) {
- entity.emit(AbstractEntity.SENSOR_ADDED, newSensor);
+ instance.emit(AbstractEntity.SENSOR_ADDED, newSensor);
}
}
public Sensor<?> addSensorIfAbsentWithoutPublishing(Sensor<?> newSensor) {
Sensor<?> prev = sensors.putIfAbsent(newSensor.getName(), newSensor);
if (prev == null) {
- snapshotValid.set(false);
+ invalidateSnapshot();
}
return prev;
}
@@ -233,8 +196,8 @@ public class EntityDynamicType {
public Sensor<?> removeSensor(String sensorName) {
Sensor<?> result = sensors.remove(sensorName);
if (result != null) {
- snapshotValid.set(false);
- entity.emit(AbstractEntity.SENSOR_REMOVED, result);
+ invalidateSnapshot();
+ instance.emit(AbstractEntity.SENSOR_REMOVED, result);
}
return result;
}
@@ -248,32 +211,9 @@ public class EntityDynamicType {
// --------------------------------------------------
- // --------------------------------------------------
-
- /**
- * ConfigKeys available on this entity.
- */
- public Map<String,ConfigKey<?>> getConfigKeys() {
- return Collections.unmodifiableMap(value(configKeys));
- }
-
- /**
- * ConfigKeys available on this entity.
- */
- public ConfigKey<?> getConfigKey(String keyName) {
- return value(configKeys.get(keyName));
- }
-
- /** field where a config key is defined, for use getting annotations. note annotations are not inherited. */
- public Field getConfigKeyField(String keyName) {
- return field(configKeys.get(keyName));
- }
-
- private EntityTypeSnapshot refreshSnapshot() {
- if (snapshotValid.compareAndSet(false, true)) {
- snapshot = new EntityTypeSnapshot(name, value(configKeys), sensors, effectors.values());
- }
- return snapshot;
+ @Override
+ protected EntityTypeSnapshot newSnapshot() {
+ return new EntityTypeSnapshot(name, value(configKeys), sensors, effectors.values());
}
/**
@@ -375,148 +315,4 @@ public class EntityDynamicType {
throw Throwables.propagate(e);
}
}
-
- /**
- * Finds the config keys defined on the entity's class, statics and optionally any non-static (discouraged).
- * Prefers keys which overwrite other keys, and prefers keys which are lower in the hierarchy;
- * logs warnings if there are two conflicting keys which don't have an overwriting relationship.
- */
- protected static void buildConfigKeys(Class<? extends Entity> clazz, AbstractEntity optionalEntity,
- Map<String, FieldAndValue<ConfigKey<?>>> configKeys) {
- ListMultimap<String,FieldAndValue<ConfigKey<?>>> configKeysAll =
- ArrayListMultimap.<String, FieldAndValue<ConfigKey<?>>>create();
-
- for (Field f : FlagUtils.getAllFields(clazz)) {
- boolean isConfigKey = ConfigKey.class.isAssignableFrom(f.getType());
- if (!isConfigKey) {
- if (!HasConfigKey.class.isAssignableFrom(f.getType())) {
- // neither ConfigKey nor HasConfigKey
- continue;
- }
- }
- if (!Modifier.isStatic(f.getModifiers())) {
- // require it to be static or we have an instance
- LOG.warn("Discouraged use of non-static config key "+f+" defined in " + (optionalEntity!=null ? optionalEntity : clazz));
- if (optionalEntity==null) continue;
- }
- try {
- ConfigKey<?> k = isConfigKey ? (ConfigKey<?>) f.get(optionalEntity) :
- ((HasConfigKey<?>)f.get(optionalEntity)).getConfigKey();
-
- if (k==null) {
- LOG.warn("no value defined for config key field (skipping): "+f);
- } else {
- configKeysAll.put(k.getName(), new FieldAndValue<ConfigKey<?>>(f, k));
- }
-
- } catch (IllegalAccessException e) {
- LOG.warn("cannot access config key (skipping): "+f);
- }
- }
- LinkedHashSet<String> keys = new LinkedHashSet<String>(configKeysAll.keys());
- for (String kn: keys) {
- List<FieldAndValue<ConfigKey<?>>> kk = Lists.newArrayList(configKeysAll.get(kn));
- if (kk.size()>1) {
- // remove anything which extends another value in the list
- for (FieldAndValue<ConfigKey<?>> k: kk) {
- ConfigKey<?> key = value(k);
- if (key instanceof BasicConfigKeyOverwriting) {
- ConfigKey<?> parent = ((BasicConfigKeyOverwriting<?>)key).getParentKey();
- // find and remove the parent from consideration
- for (FieldAndValue<ConfigKey<?>> k2: kk) {
- if (value(k2) == parent)
- configKeysAll.remove(kn, k2);
- }
- }
- }
- kk = Lists.newArrayList(configKeysAll.get(kn));
- }
- // multiple keys, not overwriting; if their values are the same then we don't mind
- FieldAndValue<ConfigKey<?>> best = null;
- for (FieldAndValue<ConfigKey<?>> k: kk) {
- if (best==null) {
- best=k;
- } else {
- Field lower = Reflections.inferSubbestField(k.field, best.field);
- ConfigKey<? extends Object> lowerV = lower==null ? null : lower.equals(k.field) ? k.value : best.value;
- if (best.value == k.value) {
- // same value doesn't matter which we take (but take lower if there is one)
- if (LOG.isTraceEnabled())
- LOG.trace("multiple definitions for config key {} on {}; same value {}; " +
- "from {} and {}, preferring {}",
- new Object[] {
- best.value.getName(), optionalEntity!=null ? optionalEntity : clazz,
- best.value.getDefaultValue(),
- k.field, best.field, lower});
- best = new FieldAndValue<ConfigKey<?>>(lower!=null ? lower : best.field, best.value);
- } else if (lower!=null) {
- // different value, but one clearly lower (in type hierarchy)
- if (LOG.isTraceEnabled())
- LOG.trace("multiple definitions for config key {} on {}; " +
- "from {} and {}, preferring lower {}, value {}",
- new Object[] {
- best.value.getName(), optionalEntity!=null ? optionalEntity : clazz,
- k.field, best.field, lower,
- lowerV.getDefaultValue() });
- best = new FieldAndValue<ConfigKey<?>>(lower, lowerV);
- } else {
- // different value, neither one lower than another in hierarchy
- LOG.warn("multiple ambiguous definitions for config key {} on {}; " +
- "from {} and {}, values {} and {}; " +
- "keeping latter (arbitrarily)",
- new Object[] {
- best.value.getName(), optionalEntity!=null ? optionalEntity : clazz,
- k.field, best.field,
- k.value.getDefaultValue(), best.value.getDefaultValue() });
- // (no change)
- }
- }
- }
- if (best==null) {
- // shouldn't happen
- LOG.error("Error - no matching config key from "+kk+" in class "+clazz+", even though had config key name "+kn);
- continue;
- } else {
- configKeys.put(best.value.getName(), best);
- }
- }
- }
-
- private static class FieldAndValue<V> {
- public final Field field;
- public final V value;
- public FieldAndValue(Field field, V value) {
- this.field = field;
- this.value = value;
- }
- @Override
- public String toString() {
- return Objects.toStringHelper(this).add("field", field).add("value", value).toString();
- }
- }
-
- private static <V> V value(FieldAndValue<V> fv) {
- if (fv==null) return null;
- return fv.value;
- }
-
- private static Field field(FieldAndValue<?> fv) {
- if (fv==null) return null;
- return fv.field;
- }
-
- @SuppressWarnings("unused")
- private static <V> Collection<V> value(Collection<FieldAndValue<V>> fvs) {
- List<V> result = new ArrayList<V>();
- for (FieldAndValue<V> fv: fvs) result.add(value(fv));
- return result;
- }
-
- private static <K,V> Map<K,V> value(Map<K,FieldAndValue<V>> fvs) {
- Map<K,V> result = new LinkedHashMap<K,V>();
- for (K key: fvs.keySet())
- result.put(key, value(fvs.get(key)));
- return result;
- }
-
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/entity/basic/EntityTypeSnapshot.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityTypeSnapshot.java b/core/src/main/java/brooklyn/entity/basic/EntityTypeSnapshot.java
index d0832f2..2395d66 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityTypeSnapshot.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityTypeSnapshot.java
@@ -24,66 +24,35 @@ import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import brooklyn.basic.BrooklynTypeSnapshot;
import brooklyn.config.ConfigKey;
import brooklyn.entity.Effector;
import brooklyn.entity.EntityType;
import brooklyn.entity.ParameterType;
import brooklyn.event.Sensor;
import brooklyn.util.guava.Maybe;
-import brooklyn.util.text.Strings;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
-public class EntityTypeSnapshot implements EntityType {
+public class EntityTypeSnapshot extends BrooklynTypeSnapshot implements EntityType {
private static final long serialVersionUID = 4670930188951106009L;
- private final String name;
- private transient volatile String simpleName;
- private final Map<String, ConfigKey<?>> configKeys;
private final Map<String, Sensor<?>> sensors;
private final Set<Effector<?>> effectors;
- private final Set<ConfigKey<?>> configKeysSet;
private final Set<Sensor<?>> sensorsSet;
EntityTypeSnapshot(String name, Map<String, ConfigKey<?>> configKeys, Map<String, Sensor<?>> sensors, Collection<Effector<?>> effectors) {
- this.name = name;
- this.configKeys = ImmutableMap.copyOf(configKeys);
+ super(name, configKeys);
this.sensors = ImmutableMap.copyOf(sensors);
this.effectors = ImmutableSet.copyOf(effectors);
- this.configKeysSet = ImmutableSet.copyOf(this.configKeys.values());
this.sensorsSet = ImmutableSet.copyOf(this.sensors.values());
}
@Override
- public String getName() {
- return name;
- }
-
- private String toSimpleName(String name) {
- String simpleName = name.substring(name.lastIndexOf(".")+1);
- if (Strings.isBlank(simpleName)) simpleName = name.trim();
- return Strings.makeValidFilename(simpleName);
- }
-
- @Override
- public String getSimpleName() {
- String sn = simpleName;
- if (sn==null) {
- sn = toSimpleName(getName());
- simpleName = sn;
- }
- return sn;
- }
-
- @Override
- public Set<ConfigKey<?>> getConfigKeys() {
- return configKeysSet;
- }
-
- @Override
public Set<Sensor<?>> getSensors() {
return sensorsSet;
}
@@ -124,12 +93,6 @@ public class EntityTypeSnapshot implements EntityType {
throw new NoSuchElementException("No matching effector "+name+"("+Joiner.on(", ").join(parameterTypes)+") on entity "+getName());
}
-
- @Override
- public ConfigKey<?> getConfigKey(String name) {
- return configKeys.get(name);
- }
-
@Override
public Sensor<?> getSensor(String name) {
return sensors.get(name);
@@ -142,7 +105,7 @@ public class EntityTypeSnapshot implements EntityType {
@Override
public int hashCode() {
- return Objects.hashCode(name, configKeys, sensors, effectors);
+ return Objects.hashCode(super.hashCode(), sensors, effectors);
}
@Override
@@ -151,16 +114,13 @@ public class EntityTypeSnapshot implements EntityType {
if (!(obj instanceof EntityTypeSnapshot)) return false;
EntityTypeSnapshot o = (EntityTypeSnapshot) obj;
- return Objects.equal(name, o.name) && Objects.equal(configKeys, o.configKeys) &&
- Objects.equal(sensors, o.sensors) && Objects.equal(effectors, o.effectors);
+ return super.equals(obj) && Objects.equal(sensors, o.sensors) && Objects.equal(effectors, o.effectors);
}
@Override
- public String toString() {
- return Objects.toStringHelper(name)
- .add("configKeys", configKeys)
+ protected ToStringHelper toStringHelper() {
+ return super.toStringHelper()
.add("sensors", sensors)
- .add("effectors", effectors)
- .toString();
+ .add("effectors", effectors);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/entity/basic/EntityTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityTypes.java b/core/src/main/java/brooklyn/entity/basic/EntityTypes.java
index 6fc047a..9970538 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityTypes.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityTypes.java
@@ -18,85 +18,11 @@
*/
package brooklyn.entity.basic;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import brooklyn.basic.BrooklynTypes;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.event.Sensor;
-import brooklyn.util.exceptions.Exceptions;
-
-public class EntityTypes {
-
- private static class ImmutableEntityType extends EntityDynamicType {
- public ImmutableEntityType(Class<? extends Entity> clazz) {
- super(clazz);
- }
- @Override
- public void addSensor(Sensor<?> newSensor) {
- throw new UnsupportedOperationException();
- }
- @Override
- public void addSensorIfAbsent(Sensor<?> newSensor) {
- throw new UnsupportedOperationException();
- }
- @Override
- public Sensor<?> addSensorIfAbsentWithoutPublishing(Sensor<?> newSensor) {
- throw new UnsupportedOperationException();
- }
- @Override
- public void addSensors(Iterable<? extends Sensor<?>> newSensors) {
- throw new UnsupportedOperationException();
- }
- @Override
- public boolean removeSensor(Sensor<?> sensor) {
- throw new UnsupportedOperationException();
- }
- @Override
- public Sensor<?> removeSensor(String sensorName) {
- throw new UnsupportedOperationException();
- }
- }
-
- @SuppressWarnings("rawtypes")
- private static final Map<Class,ImmutableEntityType> cache = new LinkedHashMap<Class,ImmutableEntityType>();
-
- public static EntityDynamicType getDefinedEntityType(Class<? extends Entity> entityClass) {
- ImmutableEntityType t = cache.get(entityClass);
- if (t!=null) return t;
- return loadDefinedEntityType(entityClass);
- }
-
- private static synchronized EntityDynamicType loadDefinedEntityType(Class<? extends Entity> entityClass) {
- ImmutableEntityType type = cache.get(entityClass);
- if (type!=null) return type;
- type = new ImmutableEntityType(entityClass);
- cache.put(entityClass, type);
- return type;
- }
-
- public static Map<String, ConfigKey<?>> getDefinedConfigKeys(Class<? extends Entity> entityClass) {
- return getDefinedEntityType(entityClass).getConfigKeys();
- }
- @SuppressWarnings("unchecked")
- public static Map<String, ConfigKey<?>> getDefinedConfigKeys(String entityTypeName) {
- try {
- return getDefinedConfigKeys((Class<? extends Entity>) Class.forName(entityTypeName));
- } catch (ClassNotFoundException e) {
- throw Exceptions.propagate(e);
- }
- }
-
- public static Map<String, Sensor<?>> getDefinedSensors(Class<? extends Entity> entityClass) {
- return getDefinedEntityType(entityClass).getSensors();
- }
- @SuppressWarnings("unchecked")
- public static Map<String, Sensor<?>> getDefinedSensors(String entityTypeName) {
- try {
- return getDefinedSensors((Class<? extends Entity>) Class.forName(entityTypeName));
- } catch (ClassNotFoundException e) {
- throw Exceptions.propagate(e);
- }
- }
-
+/**
+ * @deprecated since 0.7.0; use {@link BrooklynTypes}
+ */
+@Deprecated
+public class EntityTypes extends BrooklynTypes {
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java b/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java
index c2f3104..680b1bf 100644
--- a/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java
+++ b/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java
@@ -26,12 +26,12 @@ import java.util.Map;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
+import brooklyn.basic.BrooklynTypes;
import brooklyn.config.ConfigKey;
import brooklyn.entity.Effector;
import brooklyn.entity.Entity;
import brooklyn.entity.basic.AbstractEntity;
import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityTypes;
import brooklyn.entity.rebind.RebindSupport;
import brooklyn.event.AttributeSensor;
import brooklyn.event.Sensor;
@@ -176,7 +176,7 @@ public class BasicEntityMemento extends AbstractTreeNodeMemento implements Entit
if (staticConfigKeys==null) {
@SuppressWarnings("unchecked")
Class<? extends Entity> clazz = (Class<? extends Entity>) getTypeClass();
- staticConfigKeys = (clazz == null) ? EntityTypes.getDefinedConfigKeys(getType()) : EntityTypes.getDefinedConfigKeys(clazz);
+ staticConfigKeys = (clazz == null) ? BrooklynTypes.getDefinedConfigKeys(getType()) : BrooklynTypes.getDefinedConfigKeys(clazz);
}
return staticConfigKeys;
}
@@ -193,7 +193,7 @@ public class BasicEntityMemento extends AbstractTreeNodeMemento implements Entit
if (staticSensorKeys==null) {
@SuppressWarnings("unchecked")
Class<? extends Entity> clazz = (Class<? extends Entity>) getTypeClass();
- staticSensorKeys = (clazz == null) ? EntityTypes.getDefinedSensors(getType()) : EntityTypes.getDefinedSensors(clazz);
+ staticSensorKeys = (clazz == null) ? BrooklynTypes.getDefinedSensors(getType()) : BrooklynTypes.getDefinedSensors(clazz);
}
return staticSensorKeys;
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
index be1f27d..66d9aab 100644
--- a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
+++ b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
@@ -24,6 +24,7 @@ import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.Set;
+import brooklyn.basic.BrooklynTypes;
import brooklyn.config.ConfigKey;
import brooklyn.enricher.basic.AbstractEnricher;
import brooklyn.entity.Application;
@@ -31,7 +32,6 @@ import brooklyn.entity.Entity;
import brooklyn.entity.Group;
import brooklyn.entity.basic.EntityDynamicType;
import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.basic.EntityTypes;
import brooklyn.entity.rebind.TreeUtils;
import brooklyn.event.AttributeSensor;
import brooklyn.location.Location;
@@ -99,7 +99,7 @@ public class MementosGenerators {
}
public static BasicEntityMemento.Builder newEntityMementoBuilder(Entity entity) {
- EntityDynamicType definedType = EntityTypes.getDefinedEntityType(entity.getClass());
+ EntityDynamicType definedType = BrooklynTypes.getDefinedEntityType(entity.getClass());
BasicEntityMemento.Builder builder = BasicEntityMemento.builder();
builder.id = entity.getId();
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/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..1da196e 100644
--- a/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java
@@ -44,19 +44,17 @@ public abstract class AbstractPolicy extends AbstractEntityAdjunct implements Po
protected String policyStatus;
protected AtomicBoolean suspended = new AtomicBoolean(false);
- /**
- * The config values of this entity. Updating this map should be done
- * via getConfig/setConfig.
- */
- private final PolicyType policyType;
+ private final PolicyDynamicType policyType;
public AbstractPolicy() {
this(Collections.emptyMap());
}
- public AbstractPolicy(Map flags) {
+ public AbstractPolicy(Map<?,?> flags) {
super(flags);
- policyType = new PolicyTypeImpl(getAdjunctType());
+
+ // TODO Don't let `this` reference escape during construction
+ policyType = new PolicyDynamicType(this);
if (isLegacyConstruction() && !isLegacyNoConstructionInit()) {
init();
@@ -65,7 +63,7 @@ public abstract class AbstractPolicy extends AbstractEntityAdjunct implements Po
@Override
public PolicyType getPolicyType() {
- return policyType;
+ return policyType.getSnapshot();
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/policy/basic/EnricherTypeImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/policy/basic/EnricherTypeImpl.java b/core/src/main/java/brooklyn/policy/basic/EnricherTypeImpl.java
deleted file mode 100644
index f09d800..0000000
--- a/core/src/main/java/brooklyn/policy/basic/EnricherTypeImpl.java
+++ /dev/null
@@ -1,75 +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 java.util.Set;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.policy.EnricherType;
-
-import com.google.common.base.Objects;
-
-/**
- * This is the actual type of an enricher instance.
- */
-public class EnricherTypeImpl implements EnricherType {
- private static final long serialVersionUID = 668629178669109738L;
-
- private final AdjunctType delegate;
-
- public EnricherTypeImpl(AdjunctType delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public String getName() {
- return delegate.getName();
- }
-
- @Override
- public Set<ConfigKey<?>> getConfigKeys() {
- return delegate.getConfigKeys();
- }
-
- @Override
- public ConfigKey<?> getConfigKey(String name) {
- return delegate.getConfigKey(name);
- }
-
- @Override
- public int hashCode() {
- return delegate.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (!(obj instanceof EnricherType)) return false;
- EnricherType o = (EnricherType) obj;
-
- return Objects.equal(getName(), o.getName()) && Objects.equal(getConfigKeys(), o.getConfigKeys());
- }
-
- @Override
- public String toString() {
- return Objects.toStringHelper(getName())
- .add("configKeys", getConfigKeys())
- .toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java b/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java
new file mode 100644
index 0000000..6c99240
--- /dev/null
+++ b/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java
@@ -0,0 +1,39 @@
+/*
+ * 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 brooklyn.basic.BrooklynDynamicType;
+import brooklyn.policy.Policy;
+import brooklyn.policy.PolicyType;
+
+public class PolicyDynamicType extends BrooklynDynamicType<Policy, AbstractPolicy> {
+
+ public PolicyDynamicType(AbstractPolicy policy) {
+ super(policy);
+ }
+
+ public PolicyType getSnapshot() {
+ return (PolicyType) super.getSnapshot();
+ }
+
+ @Override
+ protected PolicyTypeSnapshot newSnapshot() {
+ return new PolicyTypeSnapshot(name, value(configKeys));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/policy/basic/PolicyTypeImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/policy/basic/PolicyTypeImpl.java b/core/src/main/java/brooklyn/policy/basic/PolicyTypeImpl.java
deleted file mode 100644
index eddb5d5..0000000
--- a/core/src/main/java/brooklyn/policy/basic/PolicyTypeImpl.java
+++ /dev/null
@@ -1,75 +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 java.util.Set;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.policy.PolicyType;
-
-import com.google.common.base.Objects;
-
-/**
- * This is the actual type of a policy instance at runtime.
- */
-public class PolicyTypeImpl implements PolicyType {
- private static final long serialVersionUID = -7370390838599315481L;
-
- private final AdjunctType delegate;
-
- public PolicyTypeImpl(AdjunctType delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public String getName() {
- return delegate.getName();
- }
-
- @Override
- public Set<ConfigKey<?>> getConfigKeys() {
- return delegate.getConfigKeys();
- }
-
- @Override
- public ConfigKey<?> getConfigKey(String name) {
- return delegate.getConfigKey(name);
- }
-
- @Override
- public int hashCode() {
- return delegate.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (!(obj instanceof PolicyType)) return false;
- PolicyType o = (PolicyType) obj;
-
- return Objects.equal(getName(), o.getName()) && Objects.equal(getConfigKeys(), o.getConfigKeys());
- }
-
- @Override
- public String toString() {
- return Objects.toStringHelper(getName())
- .add("configKeys", getConfigKeys())
- .toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java b/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java
new file mode 100644
index 0000000..ed36adb
--- /dev/null
+++ b/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java
@@ -0,0 +1,39 @@
+/*
+ * 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 java.util.Map;
+
+import brooklyn.basic.BrooklynTypeSnapshot;
+import brooklyn.config.ConfigKey;
+import brooklyn.policy.PolicyType;
+
+public class PolicyTypeSnapshot extends BrooklynTypeSnapshot implements PolicyType {
+ private static final long serialVersionUID = 4670930188951106009L;
+
+ PolicyTypeSnapshot(String name, Map<String, ConfigKey<?>> configKeys) {
+ super(name, configKeys);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ return (obj instanceof PolicyTypeSnapshot) && super.equals(obj);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/usage/rest-server/src/main/java/brooklyn/rest/transform/CatalogTransformer.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/transform/CatalogTransformer.java b/usage/rest-server/src/main/java/brooklyn/rest/transform/CatalogTransformer.java
index a69f94d..33dc4d9 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/transform/CatalogTransformer.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/transform/CatalogTransformer.java
@@ -24,13 +24,13 @@ import java.util.Set;
import org.slf4j.LoggerFactory;
+import brooklyn.basic.BrooklynTypes;
import brooklyn.catalog.CatalogItem;
import brooklyn.config.ConfigKey;
import brooklyn.entity.Effector;
import brooklyn.entity.Entity;
import brooklyn.entity.EntityType;
import brooklyn.entity.basic.EntityDynamicType;
-import brooklyn.entity.basic.EntityTypes;
import brooklyn.entity.proxying.EntitySpec;
import brooklyn.event.Sensor;
import brooklyn.policy.Policy;
@@ -56,7 +56,7 @@ public class CatalogTransformer {
public static CatalogEntitySummary catalogEntitySummary(BrooklynRestResourceUtils b, CatalogItem<? extends Entity,EntitySpec<?>> item) {
EntitySpec<?> spec = b.getCatalog().createSpec(item);
- EntityDynamicType typeMap = EntityTypes.getDefinedEntityType(spec.getType());
+ EntityDynamicType typeMap = BrooklynTypes.getDefinedEntityType(spec.getType());
EntityType type = typeMap.getSnapshot();
Set<EntityConfigSummary> config = Sets.newTreeSet(SummaryComparators.nameComparator());
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d9594b36/usage/rest-server/src/main/java/brooklyn/rest/util/BrooklynRestResourceUtils.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/util/BrooklynRestResourceUtils.java b/usage/rest-server/src/main/java/brooklyn/rest/util/BrooklynRestResourceUtils.java
index b2dba14..7075fa5 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/util/BrooklynRestResourceUtils.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/util/BrooklynRestResourceUtils.java
@@ -38,6 +38,7 @@ import javax.ws.rs.core.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import brooklyn.basic.BrooklynTypes;
import brooklyn.catalog.BrooklynCatalog;
import brooklyn.catalog.CatalogItem;
import brooklyn.config.ConfigKey;
@@ -50,7 +51,6 @@ import brooklyn.entity.basic.BasicApplication;
import brooklyn.entity.basic.Entities;
import brooklyn.entity.basic.EntityInternal;
import brooklyn.entity.basic.EntityLocal;
-import brooklyn.entity.basic.EntityTypes;
import brooklyn.entity.trait.Startable;
import brooklyn.location.Location;
import brooklyn.location.LocationRegistry;
@@ -393,7 +393,7 @@ public class BrooklynRestResourceUtils {
private Map<?,?> convertFlagsToKeys(Class<? extends Entity> javaType, Map<?, ?> config) {
if (config==null || config.isEmpty() || javaType==null) return config;
- Map<String, ConfigKey<?>> configKeys = EntityTypes.getDefinedConfigKeys(javaType);
+ Map<String, ConfigKey<?>> configKeys = BrooklynTypes.getDefinedConfigKeys(javaType);
Map<Object,Object> result = new LinkedHashMap<Object,Object>();
for (Map.Entry<?,?> entry: config.entrySet()) {
log.debug("Setting key {} to {} for REST creation of {}", new Object[] { entry.getKey(), entry.getValue(), javaType});
[5/9] git commit: Add persisted getTags to BrooklynObject
Posted by he...@apache.org.
Add persisted getTags to BrooklynObject
- no longer just Entity
- deprecate tag methods on Entity (getTags/addTags/etc), and now have
getTagSupport() so that the Entity interface doesn’t get as cluttered.
- adds requestPersist() to AbstractBrooklynObject
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/fed8ee6f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/fed8ee6f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/fed8ee6f
Branch: refs/heads/master
Commit: fed8ee6f078d79d2a9e9e9ef3e239bf861db7dd4
Parents: d9594b3
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 6 21:29:34 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 6 23:17:46 2014 +0100
----------------------------------------------------------------------
.../java/brooklyn/basic/BrooklynObject.java | 28 ++++++++
api/src/main/java/brooklyn/entity/Entity.java | 29 ++++++---
.../java/brooklyn/mementos/EntityMemento.java | 3 -
.../main/java/brooklyn/mementos/Memento.java | 3 +
.../brooklyn/basic/AbstractBrooklynObject.java | 47 ++++++++++++++
.../brooklyn/basic/BrooklynDynamicType.java | 10 +--
.../enricher/basic/AbstractEnricher.java | 7 +-
.../brooklyn/entity/basic/AbstractEntity.java | 24 ++-----
.../entity/basic/EntityInitializers.java | 2 +-
.../rebind/BasicEnricherRebindSupport.java | 11 +++-
.../entity/rebind/BasicEntityRebindSupport.java | 2 +-
.../rebind/BasicLocationRebindSupport.java | 7 ++
.../entity/rebind/BasicPolicyRebindSupport.java | 10 ++-
.../entity/rebind/dto/AbstractMemento.java | 11 +++-
.../entity/rebind/dto/BasicEntityMemento.java | 7 --
.../entity/rebind/dto/MementosGenerators.java | 67 ++++++++++----------
.../location/basic/AbstractLocation.java | 8 +++
.../policy/basic/AbstractEntityAdjunct.java | 17 ++---
.../brooklyn/policy/basic/AbstractPolicy.java | 8 +++
.../brooklyn/entity/basic/EntitiesTest.java | 18 +++---
.../entity/rebind/RebindEnricherTest.java | 14 ++++
.../entity/rebind/RebindEntityTest.java | 14 ++--
.../entity/rebind/RebindLocationTest.java | 17 ++++-
.../entity/rebind/RebindPolicyTest.java | 25 ++++++--
.../brooklyn/rest/resources/EntityResource.java | 14 ++--
.../rest/resources/EntityResourceTest.java | 11 +---
26 files changed, 280 insertions(+), 134 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/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..44cd489 100644
--- a/api/src/main/java/brooklyn/basic/BrooklynObject.java
+++ b/api/src/main/java/brooklyn/basic/BrooklynObject.java
@@ -18,8 +18,14 @@
*/
package brooklyn.basic;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+
import brooklyn.entity.trait.Identifiable;
+import com.google.common.collect.ImmutableMap;
+
/**
* Super-type of entity, location, policy and enricher.
*/
@@ -28,4 +34,26 @@ public interface BrooklynObject extends Identifiable {
* A display name; recommended to be a concise single-line description.
*/
String getDisplayName();
+
+ /**
+ * Tags are arbitrary objects which can be attached to an entity for subsequent reference.
+ * They must not be null (as {@link ImmutableMap} may be used under the covers; also there is little point!);
+ * and they should be amenable to our persistence (on-disk serialization) and our JSON serialization in the REST API.
+ */
+ TagSupport getTagSupport();
+
+ public static interface TagSupport {
+ /**
+ * @return An immutable copy of the set of tags on this entity.
+ * Note {@link #containsTag(Object)} will be more efficient,
+ * and {@link #addTag(Object)} and {@link #removeTag(Object)} will not work on the returned set.
+ */
+ Set<Object> getTags();
+
+ boolean containsTag(@Nonnull Object tag);
+
+ boolean addTag(@Nonnull Object tag);
+
+ boolean removeTag(@Nonnull Object tag);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/api/src/main/java/brooklyn/entity/Entity.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/entity/Entity.java b/api/src/main/java/brooklyn/entity/Entity.java
index c792067..88a10fa 100644
--- a/api/src/main/java/brooklyn/entity/Entity.java
+++ b/api/src/main/java/brooklyn/entity/Entity.java
@@ -38,8 +38,6 @@ import brooklyn.policy.Policy;
import brooklyn.policy.PolicySpec;
import brooklyn.util.guava.Maybe;
-import com.google.common.collect.ImmutableMap;
-
/**
* The basic interface for a Brooklyn entity.
* <p>
@@ -246,16 +244,27 @@ public interface Entity extends BrooklynObject {
boolean removeEnricher(Enricher enricher);
/**
- * Tags are arbitrary objects which can be attached to an entity for subsequent reference.
- * They must not be null (as {@link ImmutableMap} may be used under the covers; also there is little point!);
- * and they should be amenable to our persistence (on-disk serialization) and our JSON serialization in the REST API.
- *
- * @return An immutable copy of the set of tags on this entity.
- * Note {@link #containsTag(Object)} will be more efficient,
- * and {@link #addTag(Object)} and {@link #removeTag(Object)} will not work. */
+ * @since 0.7
+ * @deprecated since 0.7; see {@link #getTagSupport()}
+ */
+ @Deprecated
Set<Object> getTags();
+ /**
+ * @since 0.7
+ * @deprecated since 0.7; see {@link #getTagSupport()}
+ */
+ @Deprecated
boolean addTag(@Nonnull Object tag);
+ /**
+ * @since 0.7
+ * @deprecated since 0.7; see {@link #getTagSupport()}
+ */
+ @Deprecated
boolean removeTag(@Nonnull Object tag);
+ /**
+ * @since 0.7
+ * @deprecated since 0.7; see {@link #getTagSupport()}
+ */
+ @Deprecated
boolean containsTag(@Nonnull Object tag);
-
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/api/src/main/java/brooklyn/mementos/EntityMemento.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/mementos/EntityMemento.java b/api/src/main/java/brooklyn/mementos/EntityMemento.java
index 6f0ef78..c0547d4 100644
--- a/api/src/main/java/brooklyn/mementos/EntityMemento.java
+++ b/api/src/main/java/brooklyn/mementos/EntityMemento.java
@@ -72,7 +72,4 @@ public interface EntityMemento extends Memento, TreeNode {
* The ids of the enrichers of this entity.
*/
public Collection<String> getEnrichers();
-
- public Collection<Object> getTags();
-
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/api/src/main/java/brooklyn/mementos/Memento.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/mementos/Memento.java b/api/src/main/java/brooklyn/mementos/Memento.java
index a83bde8..be8b629 100644
--- a/api/src/main/java/brooklyn/mementos/Memento.java
+++ b/api/src/main/java/brooklyn/mementos/Memento.java
@@ -19,6 +19,7 @@
package brooklyn.mementos;
import java.io.Serializable;
+import java.util.Collection;
import java.util.Map;
import brooklyn.entity.rebind.RebindSupport;
@@ -69,4 +70,6 @@ public interface Memento extends Serializable {
* previously calling {@code EntityTypes.getDefinedSensors(getType())}.
*/
public Class<?> getTypeClass();
+
+ public Collection<Object> getTags();
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/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..7cc1ffd 100644
--- a/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
+++ b/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
@@ -18,16 +18,63 @@
*/
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.Sets;
+
public abstract class AbstractBrooklynObject implements BrooklynObjectInternal {
@SetFromFlag(value="id")
private String id = Identifiers.makeRandomId(8);
+ private final Set<Object> tags = Sets.newLinkedHashSet();
+
+ protected abstract void requestPersist();
+
@Override
public String getId() {
return id;
}
+
+ public TagSupport getTagSupport() {
+ return new TagSupport() {
+ @Override
+ public Set<Object> getTags() {
+ synchronized (tags) {
+ return ImmutableSet.copyOf(tags);
+ }
+ }
+
+ @Override
+ public boolean containsTag(Object tag) {
+ synchronized (tags) {
+ return tags.contains(tag);
+ }
+ }
+
+ @Override
+ public boolean addTag(Object tag) {
+ boolean result;
+ synchronized (tags) {
+ result = tags.add(tag);
+ }
+ requestPersist();
+ return result;
+ }
+
+ @Override
+ public boolean removeTag(Object tag) {
+ boolean result;
+ synchronized (tags) {
+ result = tags.remove(tag);
+ }
+ requestPersist();
+ return result;
+ }
+ };
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java b/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
index 637841e..0ae7400 100644
--- a/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
+++ b/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
@@ -79,16 +79,12 @@ public abstract class BrooklynDynamicType<T extends BrooklynObject, AbstractT ex
protected BrooklynDynamicType(Class<? extends T> clazz, AbstractT instance) {
this.brooklynClass = checkNotNull(clazz, "brooklyn class");
this.instance = instance;
- // NB: official name is usu injected later, e.g. from AbstractEntity.setManagementContext
- setName((clazz.getCanonicalName() == null) ? clazz.getName() : clazz.getCanonicalName());
-
- String id = instance==null ? clazz.getName() : instance.getId();
+ // NB: official name is usually injected later, e.g. from AbstractEntity.setManagementContext
+ this.name = (clazz.getCanonicalName() == null) ? clazz.getName() : clazz.getCanonicalName();
buildConfigKeys(clazz, null, configKeys);
if (LOG.isTraceEnabled())
- LOG.trace("Entity {} config keys: {}", id, Joiner.on(", ").join(configKeys.keySet()));
-
- refreshSnapshot();
+ LOG.trace("Entity {} config keys: {}", (instance==null ? clazz.getName() : instance.getId()), Joiner.on(", ").join(configKeys.keySet()));
}
protected abstract BrooklynTypeSnapshot newSnapshot();
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/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 68120d9..e029ab2 100644
--- a/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
+++ b/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
@@ -62,7 +62,12 @@ public abstract class AbstractEnricher extends AbstractEntityAdjunct implements
@Override
protected void onChanged() {
- // TODO Could add EnricherChangeListener, similar to EntityChangeListener; should we do that?
+ requestPersist();
+ }
+
+ @Override
+ protected void requestPersist() {
+ // TODO Could add PolicyChangeListener, similar to EntityChangeListener; should we do that?
if (getManagementContext() != null) {
getManagementContext().getRebindManager().getChangeListener().onChanged(this);
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/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 3b8baec..e2c84fa 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@ -89,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;
@@ -173,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
@@ -1329,36 +1327,22 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
@Override
public Set<Object> getTags() {
- synchronized (tags) {
- return ImmutableSet.copyOf(tags);
- }
+ return getTagSupport().getTags();
}
@Override
public boolean addTag(Object tag) {
- boolean result;
- synchronized (tags) {
- result = tags.add(tag);
- }
- getManagementSupport().getEntityChangeListener().onTagsChanged();
- return result;
+ return getTagSupport().addTag(tag);
}
@Override
public boolean removeTag(Object tag) {
- boolean result;
- synchronized (tags) {
- result = tags.remove(tag);
- }
- getManagementSupport().getEntityChangeListener().onTagsChanged();
- return result;
+ return getTagSupport().removeTag(tag);
}
@Override
public boolean containsTag(Object tag) {
- synchronized (tags) {
- return tags.contains(tag);
- }
+ return getTagSupport().containsTag(tag);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/core/src/main/java/brooklyn/entity/basic/EntityInitializers.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityInitializers.java b/core/src/main/java/brooklyn/entity/basic/EntityInitializers.java
index 3571b5a..a2f4186 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityInitializers.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityInitializers.java
@@ -36,7 +36,7 @@ public class EntityInitializers {
@Override
public void apply(EntityLocal entity) {
for (Object tag: tags)
- entity.addTag(tag);
+ entity.getTagSupport().addTag(tag);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/core/src/main/java/brooklyn/entity/rebind/BasicEnricherRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicEnricherRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicEnricherRebindSupport.java
index 0fc1584..167d684 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicEnricherRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicEnricherRebindSupport.java
@@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory;
import brooklyn.enricher.basic.AbstractEnricher;
import brooklyn.entity.rebind.dto.MementosGenerators;
import brooklyn.mementos.EnricherMemento;
+import brooklyn.mementos.Memento;
import brooklyn.util.config.ConfigBag;
import brooklyn.util.flags.FlagUtils;
@@ -39,7 +40,7 @@ public class BasicEnricherRebindSupport implements RebindSupport<EnricherMemento
@Override
public EnricherMemento getMemento() {
- EnricherMemento memento = MementosGenerators.newEnricherMementoBuilder(enricher).build();
+ EnricherMemento memento = MementosGenerators.newEnricherMemento(enricher);
if (LOG.isTraceEnabled()) LOG.trace("Creating memento for enricher: {}", memento.toVerboseString());
return memento;
}
@@ -57,11 +58,17 @@ public class BasicEnricherRebindSupport implements RebindSupport<EnricherMemento
ConfigBag configBag = ConfigBag.newInstance(memento.getConfig());
FlagUtils.setFieldsFromFlags(enricher, configBag);
FlagUtils.setAllConfigKeys(enricher, configBag, false);
-
+ addTags(rebindContext, memento);
doReconstruct(rebindContext, memento);
((AbstractEnricher)enricher).rebind();
}
+ protected void addTags(RebindContext rebindContext, Memento memento) {
+ for (Object tag : memento.getTags()) {
+ enricher.getTagSupport().addTag(tag);
+ }
+ }
+
@Override
public void addPolicies(RebindContext rebindContext, EnricherMemento Memento) {
throw new UnsupportedOperationException();
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
index 62cff7b..bdb87e2 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
@@ -175,7 +175,7 @@ public class BasicEntityRebindSupport implements RebindSupport<EntityMemento> {
protected void addTags(RebindContext rebindContext, EntityMemento memento) {
for (Object tag : memento.getTags()) {
- entity.addTag(tag);
+ entity.getTagSupport().addTag(tag);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/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..fd5610c 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
@@ -104,12 +104,19 @@ public class BasicLocationRebindSupport implements RebindSupport<LocationMemento
setParent(rebindContext, memento);
addChildren(rebindContext, memento);
+ addTags(rebindContext, memento);
location.init(); // TODO deprecated calling init; will be deleted
location.rebind();
doReconstruct(rebindContext, memento);
}
+ protected void addTags(RebindContext rebindContext, LocationMemento memento) {
+ for (Object tag : memento.getTags()) {
+ location.getTagSupport().addTag(tag);
+ }
+ }
+
@Override
public void addPolicies(RebindContext rebindContext, LocationMemento Memento) {
throw new UnsupportedOperationException();
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java
index cac7996..228b5ba 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java
@@ -22,6 +22,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import brooklyn.entity.rebind.dto.MementosGenerators;
+import brooklyn.mementos.Memento;
import brooklyn.mementos.PolicyMemento;
import brooklyn.policy.basic.AbstractPolicy;
import brooklyn.util.config.ConfigBag;
@@ -39,7 +40,7 @@ public class BasicPolicyRebindSupport implements RebindSupport<PolicyMemento> {
@Override
public PolicyMemento getMemento() {
- PolicyMemento memento = MementosGenerators.newPolicyMementoBuilder(policy).build();
+ PolicyMemento memento = MementosGenerators.newPolicyMemento(policy);
if (LOG.isTraceEnabled()) LOG.trace("Creating memento for policy: {}", memento.toVerboseString());
return memento;
}
@@ -57,11 +58,18 @@ public class BasicPolicyRebindSupport implements RebindSupport<PolicyMemento> {
ConfigBag configBag = ConfigBag.newInstance(memento.getConfig());
FlagUtils.setFieldsFromFlags(policy, configBag);
FlagUtils.setAllConfigKeys(policy, configBag, false);
+ addTags(rebindContext, memento);
doReconstruct(rebindContext, memento);
((AbstractPolicy)policy).rebind();
}
+ protected void addTags(RebindContext rebindContext, Memento memento) {
+ for (Object tag : memento.getTags()) {
+ policy.getTagSupport().addTag(tag);
+ }
+ }
+
@Override
public void addPolicies(RebindContext rebindContext, PolicyMemento Memento) {
throw new UnsupportedOperationException();
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/core/src/main/java/brooklyn/entity/rebind/dto/AbstractMemento.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/AbstractMemento.java b/core/src/main/java/brooklyn/entity/rebind/dto/AbstractMemento.java
index 90aad94..67e35da 100644
--- a/core/src/main/java/brooklyn/entity/rebind/dto/AbstractMemento.java
+++ b/core/src/main/java/brooklyn/entity/rebind/dto/AbstractMemento.java
@@ -30,6 +30,7 @@ import brooklyn.mementos.Memento;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
public abstract class AbstractMemento implements Memento, Serializable {
@@ -43,7 +44,8 @@ public abstract class AbstractMemento implements Memento, Serializable {
protected Class<?> typeClass;
protected String displayName;
protected Map<String, Object> fields = Maps.newLinkedHashMap();
-
+ protected List<Object> tags = Lists.newArrayList();
+
@SuppressWarnings("unchecked")
protected B self() {
return (B) this;
@@ -55,6 +57,7 @@ public abstract class AbstractMemento implements Memento, Serializable {
typeClass = other.getTypeClass();
displayName = other.getDisplayName();
fields.putAll(other.getCustomFields());
+ tags.addAll(other.getTags());
return self();
}
public B brooklynVersion(String val) {
@@ -85,6 +88,7 @@ public abstract class AbstractMemento implements Memento, Serializable {
private String type;
private String id;
private String displayName;
+ private List<Object> tags;
private transient Class<?> typeClass;
@@ -100,6 +104,7 @@ public abstract class AbstractMemento implements Memento, Serializable {
typeClass = builder.typeClass;
displayName = builder.displayName;
setCustomFields(builder.fields);
+ tags = toPersistedList(builder.tags);
}
// "fields" is not included as a field here, so that it is serialized after selected subclass fields
@@ -136,6 +141,10 @@ public abstract class AbstractMemento implements Memento, Serializable {
return displayName;
}
+ public List<Object> getTags() {
+ return fromPersistedList(tags);
+ }
+
@Deprecated
@Override
public Object getCustomField(String name) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java b/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java
index 680b1bf..30eb653 100644
--- a/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java
+++ b/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java
@@ -70,7 +70,6 @@ public class BasicEntityMemento extends AbstractTreeNodeMemento implements Entit
protected List<String> enrichers = Lists.newArrayList();
protected List<String> members = Lists.newArrayList();
protected List<Effector<?>> effectors = Lists.newArrayList();
- protected List<Object> tags = Lists.newArrayList();
public Builder from(EntityMemento other) {
super.from((TreeNode)other);
@@ -104,7 +103,6 @@ public class BasicEntityMemento extends AbstractTreeNodeMemento implements Entit
private Map<String, Object> attributes;
private List<String> policies;
private List<String> enrichers;
- private List<Object> tags;
// TODO can we move some of these to entity type, or remove/re-insert those which are final statics?
private Map<String, ConfigKey<?>> configKeys;
@@ -133,7 +131,6 @@ public class BasicEntityMemento extends AbstractTreeNodeMemento implements Entit
policies = toPersistedList(builder.policies);
enrichers = toPersistedList(builder.enrichers);
members = toPersistedList(builder.members);
- tags = toPersistedList(builder.tags);
effectors = toPersistedList(builder.effectors);
@@ -278,10 +275,6 @@ public class BasicEntityMemento extends AbstractTreeNodeMemento implements Entit
return fromPersistedList(members);
}
- public List<Object> getTags() {
- return fromPersistedList(tags);
- }
-
@Override
public List<String> getLocations() {
return fromPersistedList(locations);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
index 66d9aab..79600da 100644
--- a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
+++ b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
@@ -24,6 +24,7 @@ import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.Set;
+import brooklyn.basic.BrooklynObject;
import brooklyn.basic.BrooklynTypes;
import brooklyn.config.ConfigKey;
import brooklyn.enricher.basic.AbstractEnricher;
@@ -60,7 +61,10 @@ public class MementosGenerators {
/**
* Walks the contents of a ManagementContext, to create a corresponding memento.
+ *
+ * @deprecated since 0.7.0; will be moved to test code; generate each entity/location memento separately
*/
+ @Deprecated
public static BrooklynMemento newBrooklynMemento(ManagementContext managementContext) {
BrooklynMementoImpl.Builder builder = BrooklynMementoImpl.builder();
@@ -97,16 +101,17 @@ public class MementosGenerators {
public static EntityMemento newEntityMemento(Entity entity) {
return newEntityMementoBuilder(entity).build();
}
-
+
+ /**
+ * @deprecated since 0.7.0; use {@link #newEntityMemento(Enricher)} instead
+ */
+ @Deprecated
public static BasicEntityMemento.Builder newEntityMementoBuilder(Entity entity) {
- EntityDynamicType definedType = BrooklynTypes.getDefinedEntityType(entity.getClass());
BasicEntityMemento.Builder builder = BasicEntityMemento.builder();
+ populateBrooklynObjectMementoBuilder(entity, builder);
+
+ EntityDynamicType definedType = BrooklynTypes.getDefinedEntityType(entity.getClass());
- builder.id = entity.getId();
- builder.displayName = entity.getDisplayName();
- builder.type = entity.getClass().getName();
- builder.typeClass = entity.getClass();
-
// TODO the dynamic attributeKeys and configKeys are computed in the BasicEntityMemento
// whereas effectors are computed here -- should be consistent!
// (probably best to compute attrKeys and configKeys here)
@@ -157,10 +162,6 @@ public class MementosGenerators {
builder.enrichers.add(enricher.getId());
}
- for (Object tag : entity.getTags()) {
- builder.tags.add(tag);
- }
-
Entity parentEntity = entity.getParent();
builder.parent = (parentEntity != null) ? parentEntity.getId() : null;
@@ -195,8 +196,13 @@ public class MementosGenerators {
return newLocationMementoBuilder(location).build();
}
+ /**
+ * @deprecated since 0.7.0; use {@link #newLocationMemento(Enricher)} instead
+ */
+ @Deprecated
public static BasicLocationMemento.Builder newLocationMementoBuilder(Location location) {
BasicLocationMemento.Builder builder = BasicLocationMemento.builder();
+ populateBrooklynObjectMementoBuilder(location, builder);
Set<String> nonPersistableFlagNames = MutableMap.<String,Object>builder()
.putAll(FlagUtils.getFieldsWithFlagsWithModifiers(location, Modifier.TRANSIENT))
@@ -211,10 +217,6 @@ public class MementosGenerators {
.build();
ConfigBag persistableConfig = new ConfigBag().copy( ((AbstractLocation)location).getLocalConfigBag() ).removeAll(nonPersistableFlagNames);
- builder.type = location.getClass().getName();
- builder.typeClass = location.getClass();
- builder.id = location.getId();
- builder.displayName = location.getDisplayName();
builder.copyConfig(persistableConfig);
builder.locationConfig.putAll(persistableFlags);
@@ -242,16 +244,8 @@ public class MementosGenerators {
* Given a policy, extracts its state for serialization.
*/
public static PolicyMemento newPolicyMemento(Policy policy) {
- return newPolicyMementoBuilder(policy).build();
- }
-
- public static BasicPolicyMemento.Builder newPolicyMementoBuilder(Policy policy) {
BasicPolicyMemento.Builder builder = BasicPolicyMemento.builder();
-
- builder.type = policy.getClass().getName();
- builder.typeClass = policy.getClass();
- builder.id = policy.getId();
- builder.displayName = policy.getDisplayName();
+ populateBrooklynObjectMementoBuilder(policy, builder);
// TODO persist config keys as well? Or only support those defined on policy class;
// current code will lose the ConfigKey type on rebind for anything not defined on class.
@@ -271,7 +265,7 @@ public class MementosGenerators {
.build();
builder.config.putAll(persistableFlags);
- return builder;
+ return builder.build();
}
public static Function<Policy, PolicyMemento> policyMementoFunction() {
@@ -288,17 +282,9 @@ public class MementosGenerators {
* Given an enricher, extracts its state for serialization.
*/
public static EnricherMemento newEnricherMemento(Enricher enricher) {
- return newEnricherMementoBuilder(enricher).build();
- }
-
- public static BasicEnricherMemento.Builder newEnricherMementoBuilder(Enricher enricher) {
BasicEnricherMemento.Builder builder = BasicEnricherMemento.builder();
+ populateBrooklynObjectMementoBuilder(enricher, builder);
- builder.type = enricher.getClass().getName();
- builder.typeClass = enricher.getClass();
- builder.id = enricher.getId();
- builder.displayName = enricher.getDisplayName();
-
// TODO persist config keys as well? Or only support those defined on policy class;
// current code will lose the ConfigKey type on rebind for anything not defined on class.
// Whereas entities support that.
@@ -317,9 +303,20 @@ public class MementosGenerators {
.build();
builder.config.putAll(persistableFlags);
- return builder;
+ return builder.build();
}
+ private static void populateBrooklynObjectMementoBuilder(BrooklynObject instance, AbstractMemento.Builder<?> builder) {
+ builder.id = instance.getId();
+ builder.displayName = instance.getDisplayName();
+ builder.type = instance.getClass().getName();
+ builder.typeClass = instance.getClass();
+
+ for (Object tag : instance.getTagSupport().getTags()) {
+ builder.tags.add(tag);
+ }
+ }
+
protected static Object configValueToPersistable(Object value) {
// TODO Swapping an attributeWhenReady task for the actual value, if completed.
// Long-term, want to just handle task-persistence properly.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/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..9c0317e 100644
--- a/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
@@ -565,6 +565,14 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
@Override
+ public void requestPersist() {
+ // TODO Could add LocationChangeListener, similar to EntityChangeListener; should we do that?
+ if (getManagementContext() != null) {
+ getManagementContext().getRebindManager().getChangeListener().onChanged(this);
+ }
+ }
+
+ @Override
public RebindSupport<LocationMemento> getRebindSupport() {
return new BasicLocationRebindSupport(this);
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/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..39524f8 100644
--- a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
@@ -69,6 +69,7 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
private static final Logger log = LoggerFactory.getLogger(AbstractEntityAdjunct.class);
private volatile ManagementContext managementContext;
+
protected Map<String,Object> leftoverProperties = Maps.newLinkedHashMap();
private boolean _legacyConstruction;
@@ -179,6 +180,14 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
return _legacyConstruction;
}
+ public void setManagementContext(ManagementContext managementContext) {
+ this.managementContext = managementContext;
+ }
+
+ protected ManagementContext getManagementContext() {
+ return managementContext;
+ }
+
/**
* Used for legacy-style policies/enrichers on rebind, to indicate that init() should not be called.
* Will likely be deleted in a future release; should not be called apart from by framework code.
@@ -188,14 +197,6 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
return _legacyNoConstructionInit;
}
- public void setManagementContext(ManagementContext managementContext) {
- this.managementContext = managementContext;
- }
-
- protected ManagementContext getManagementContext() {
- return managementContext;
- }
-
/**
* Called by framework (in new-style policies where PolicySpec was used) after configuring etc,
* but before a reference to this policy is shared.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/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 1da196e..52fa5b9 100644
--- a/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java
@@ -101,6 +101,14 @@ public abstract class AbstractPolicy extends AbstractEntityAdjunct implements Po
}
@Override
+ protected void requestPersist() {
+ // TODO Could add PolicyChangeListener, similar to EntityChangeListener; should we do that?
+ if (getManagementContext() != null) {
+ getManagementContext().getRebindManager().getChangeListener().onChanged(this);
+ }
+ }
+
+ @Override
public RebindSupport<PolicyMemento> getRebindSupport() {
return new BasicPolicyRebindSupport(this);
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/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..999c168 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
@@ -109,20 +109,20 @@ public class EntitiesTest extends BrooklynAppUnitTestSupport {
entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)
.addInitializer(EntityInitializers.addingTags("foo")));
- entity.addTag(app);
+ entity.getTagSupport().addTag(app);
- Assert.assertTrue(entity.containsTag("foo"));
- Assert.assertFalse(entity.containsTag("bar"));
+ Assert.assertTrue(entity.getTagSupport().containsTag("foo"));
+ Assert.assertFalse(entity.getTagSupport().containsTag("bar"));
- Assert.assertEquals(entity.getTags(), MutableSet.of(app, "foo"));
+ Assert.assertEquals(entity.getTagSupport().getTags(), MutableSet.of(app, "foo"));
- entity.removeTag("foo");
- Assert.assertFalse(entity.containsTag("foo"));
+ entity.getTagSupport().removeTag("foo");
+ Assert.assertFalse(entity.getTagSupport().containsTag("foo"));
- Assert.assertTrue(entity.containsTag(entity.getParent()));
- Assert.assertFalse(entity.containsTag(entity));
+ Assert.assertTrue(entity.getTagSupport().containsTag(entity.getParent()));
+ Assert.assertFalse(entity.getTagSupport().containsTag(entity));
- Assert.assertEquals(entity.getTags(), MutableSet.of(app));
+ Assert.assertEquals(entity.getTagSupport().getTags(), MutableSet.of(app));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
index a2bdbb7..d8273ca 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
@@ -47,6 +47,7 @@ import brooklyn.location.LocationSpec;
import brooklyn.location.basic.SimulatedLocation;
import brooklyn.policy.Enricher;
import brooklyn.policy.EnricherSpec;
+import brooklyn.test.Asserts;
import brooklyn.test.EntityTestUtils;
import brooklyn.test.entity.TestApplication;
import brooklyn.test.entity.TestEntity;
@@ -57,6 +58,7 @@ import brooklyn.util.text.StringFunctions;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
public class RebindEnricherTest extends RebindTestFixtureWithApp {
@@ -200,6 +202,18 @@ public class RebindEnricherTest extends RebindTestFixtureWithApp {
assertFalse(newEnricher.isRebinding());
}
+ @Test
+ public void testPolicyTags() throws Exception {
+ Enricher origEnricher = origApp.addEnricher(EnricherSpec.create(MyEnricher.class));
+ origEnricher.getTagSupport().addTag("foo");
+ origEnricher.getTagSupport().addTag(origApp);
+
+ newApp = rebind();
+ Enricher newEnricher = Iterables.getOnlyElement(newApp.getEnrichers());
+
+ Asserts.assertEqualsIgnoringOrder(newEnricher.getTagSupport().getTags(), ImmutableSet.of("foo", newApp));
+ }
+
public static class EnricherChecksIsRebinding extends AbstractEnricher {
boolean isRebindingValWhenRebinding;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
index 1292dea..1886619 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
@@ -277,17 +277,17 @@ public class RebindEntityTest extends RebindTestFixtureWithApp {
@Test
public void testEntityTags() throws Exception {
MyEntity origE = origApp.createAndManageChild(EntitySpec.create(MyEntity.class));
- origE.addTag("foo");
- origE.addTag(origApp);
+ origE.getTagSupport().addTag("foo");
+ origE.getTagSupport().addTag(origApp);
newApp = rebind(false);
MyEntity newE = Iterables.getOnlyElement( Entities.descendants(newApp, MyEntity.class) );
- assertTrue(newE.containsTag("foo"), "tags are "+newE.getTags());
- assertFalse(newE.containsTag("bar"));
- assertTrue(newE.containsTag(newE.getParent()));
- assertTrue(newE.containsTag(origApp));
- assertEquals(newE.getTags(), MutableSet.of("foo", newE.getParent()));
+ assertTrue(newE.getTagSupport().containsTag("foo"), "tags are "+newE.getTagSupport().getTags());
+ assertFalse(newE.getTagSupport().containsTag("bar"));
+ assertTrue(newE.getTagSupport().containsTag(newE.getParent()));
+ assertTrue(newE.getTagSupport().containsTag(origApp));
+ assertEquals(newE.getTagSupport().getTags(), MutableSet.of("foo", newE.getParent()));
}
public static class ReffingEntity {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java
index 32342ca..d47a987 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java
@@ -40,6 +40,7 @@ import brooklyn.location.Location;
import brooklyn.location.LocationSpec;
import brooklyn.location.basic.AbstractLocation;
import brooklyn.mementos.LocationMemento;
+import brooklyn.test.Asserts;
import brooklyn.test.entity.TestApplication;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.flags.SetFromFlag;
@@ -47,6 +48,7 @@ import brooklyn.util.flags.SetFromFlag;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
public class RebindLocationTest extends RebindTestFixtureWithApp {
@@ -236,7 +238,7 @@ public class RebindLocationTest extends RebindTestFixtureWithApp {
MyLocation origLoc = origManagementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class));
origApp.start(ImmutableList.of(origLoc));
- newApp = (TestApplication) rebind();
+ newApp = rebind();
MyLocation newLoc = (MyLocation) Iterables.get(newApp.getLocations(), 0);
assertNull(newLoc.getAllConfigBag().getStringKey("id"));
@@ -254,6 +256,19 @@ public class RebindLocationTest extends RebindTestFixtureWithApp {
assertFalse(newLoc.isRebinding());
}
+ @Test
+ public void testLocationTags() throws Exception {
+ Location origLoc = origManagementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class));
+ origLoc.getTagSupport().addTag("foo");
+ origLoc.getTagSupport().addTag(origApp);
+ origApp.start(ImmutableList.of(origLoc));
+
+ newApp = rebind();
+ Location newLoc = (Location) newManagementContext.getLocationManager().getLocation(origLoc.getId());
+
+ Asserts.assertEqualsIgnoringOrder(newLoc.getTagSupport().getTags(), ImmutableSet.of("foo", newApp));
+ }
+
public static class LocationChecksIsRebinding extends AbstractLocation {
boolean isRebindingValWhenRebinding;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
index 35acb2e..90d700b 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
@@ -40,14 +40,17 @@ import brooklyn.location.Location;
import brooklyn.location.basic.Locations;
import brooklyn.mementos.BrooklynMementoManifest;
import brooklyn.policy.EnricherSpec;
+import brooklyn.policy.Policy;
import brooklyn.policy.PolicySpec;
import brooklyn.policy.basic.AbstractPolicy;
+import brooklyn.test.Asserts;
import brooklyn.test.entity.TestApplication;
import brooklyn.test.entity.TestEntity;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.flags.SetFromFlag;
import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
public class RebindPolicyTest extends RebindTestFixtureWithApp {
@@ -90,7 +93,7 @@ public class RebindPolicyTest extends RebindTestFixtureWithApp {
assertTrue(origPolicy.initCalled);
assertFalse(origPolicy.rebindCalled);
- TestApplication newApp = rebind();
+ newApp = rebind();
MyPolicy newPolicy = (MyPolicy) Iterables.getOnlyElement(newApp.getPolicies());
assertEquals(newPolicy.myfield, "myFieldVal");
@@ -107,7 +110,7 @@ public class RebindPolicyTest extends RebindTestFixtureWithApp {
.configure(MyPolicy.MY_CONFIG_WITH_SETFROMFLAG_WITH_SHORT_NAME, "myVal for setFromFlag withShortName")
.configure(MyPolicy.MY_CONFIG_WITHOUT_SETFROMFLAG, "myVal for witout setFromFlag"));
- newApp = (TestApplication) rebind();
+ newApp = rebind();
MyPolicy newPolicy = (MyPolicy) Iterables.getOnlyElement(newApp.getPolicies());
assertEquals(newPolicy.getConfig(MyPolicy.MY_CONFIG_WITH_SETFROMFLAG_NO_SHORT_NAME), "myVal for with setFromFlag noShortName");
@@ -156,7 +159,7 @@ public class RebindPolicyTest extends RebindTestFixtureWithApp {
public void testReboundConfigDoesNotContainId() throws Exception {
MyPolicy policy = origApp.addPolicy(PolicySpec.create(MyPolicy.class));
- newApp = (TestApplication) rebind();
+ newApp = rebind();
MyPolicy newPolicy = (MyPolicy) Iterables.getOnlyElement(newApp.getPolicies());
assertNull(newPolicy.getConfig(ConfigKeys.newStringConfigKey("id")));
@@ -169,7 +172,7 @@ public class RebindPolicyTest extends RebindTestFixtureWithApp {
.configure(MyPolicyReconfigurable.MY_CONFIG, "oldval"));
policy.setConfig(MyPolicyReconfigurable.MY_CONFIG, "newval");
- newApp = (TestApplication) rebind();
+ newApp = rebind();
MyPolicyReconfigurable newPolicy = (MyPolicyReconfigurable) Iterables.getOnlyElement(newApp.getPolicies());
assertEquals(newPolicy.getConfig(MyPolicyReconfigurable.MY_CONFIG), "newval");
@@ -179,13 +182,25 @@ public class RebindPolicyTest extends RebindTestFixtureWithApp {
public void testIsRebinding() throws Exception {
origApp.addPolicy(PolicySpec.create(PolicyChecksIsRebinding.class));
- newApp = (TestApplication) rebind();
+ newApp = rebind();
PolicyChecksIsRebinding newPolicy = (PolicyChecksIsRebinding) Iterables.getOnlyElement(newApp.getPolicies());
assertTrue(newPolicy.isRebindingValWhenRebinding());
assertFalse(newPolicy.isRebinding());
}
+ @Test
+ public void testPolicyTags() throws Exception {
+ Policy origPolicy = origApp.addPolicy(PolicySpec.create(MyPolicy.class));
+ origPolicy.getTagSupport().addTag("foo");
+ origPolicy.getTagSupport().addTag(origApp);
+
+ newApp = rebind();
+ Policy newPolicy = Iterables.getOnlyElement(newApp.getPolicies());
+
+ Asserts.assertEqualsIgnoringOrder(newPolicy.getTagSupport().getTags(), ImmutableSet.of("foo", newApp));
+ }
+
// Previously, policy+enricher was added to entity as part of entity.reconstitute, so other entities might not
// have been initialised and the relationships not set. If a policy immediately looked at entity's children or
// at another entity, then it might find those entities' state uninitialised.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java
index 05b1908..d4d3962 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java
@@ -18,8 +18,8 @@
*/
package brooklyn.rest.resources;
-import static javax.ws.rs.core.Response.Status.ACCEPTED;
import static javax.ws.rs.core.Response.status;
+import static javax.ws.rs.core.Response.Status.ACCEPTED;
import java.net.URI;
import java.util.LinkedList;
@@ -31,11 +31,6 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Lists;
-import com.google.common.io.Files;
-
import brooklyn.entity.Entity;
import brooklyn.entity.basic.BrooklynTaskTags;
import brooklyn.entity.basic.EntityLocal;
@@ -55,6 +50,11 @@ import brooklyn.rest.util.WebResourceUtils;
import brooklyn.util.ResourceUtils;
import brooklyn.util.collections.MutableList;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Lists;
+import com.google.common.io.Files;
+
public class EntityResource extends AbstractBrooklynRestResource implements EntityApi {
@Override
@@ -104,7 +104,7 @@ public class EntityResource extends AbstractBrooklynRestResource implements Enti
@Override
public List<Object> listTags(String applicationId, String entityId) {
Entity entity = brooklyn().getEntity(applicationId, entityId);
- return MutableList.copyOf(entity.getTags());
+ return MutableList.copyOf(entity.getTagSupport().getTags());
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fed8ee6f/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityResourceTest.java b/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityResourceTest.java
index 9c56e81..bedf61b 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityResourceTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/resources/EntityResourceTest.java
@@ -24,16 +24,11 @@ import javax.annotation.Nullable;
import javax.ws.rs.core.MediaType;
import org.testng.Assert;
-import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-import brooklyn.config.render.RendererHints;
-import brooklyn.config.render.TestRendererHints;
import brooklyn.entity.Entity;
import brooklyn.entity.basic.EntityInternal;
-import brooklyn.event.AttributeSensor;
-import brooklyn.rest.api.SensorApi;
import brooklyn.rest.domain.ApplicationSpec;
import brooklyn.rest.domain.EntitySpec;
import brooklyn.rest.testing.BrooklynRestResourceTest;
@@ -79,7 +74,7 @@ public class EntityResourceTest extends BrooklynRestResourceTest {
@Test
public void testTagsSanity() throws Exception {
- entity.addTag("foo");
+ entity.getTagSupport().addTag("foo");
ClientResponse response = client().resource(entityEndpoint + "/tags")
.accept(MediaType.APPLICATION_JSON)
@@ -93,8 +88,8 @@ public class EntityResourceTest extends BrooklynRestResourceTest {
// TODO any entity or complex object should be cleaned up as part of WebResourceUtils call
@Test(groups="WIP")
public void testTagsDoNotSerializeTooMuch() throws Exception {
- entity.addTag("foo");
- entity.addTag(entity.getParent());
+ entity.getTagSupport().addTag("foo");
+ entity.getTagSupport().addTag(entity.getParent());
ClientResponse response = client().resource(entityEndpoint + "/tags")
.accept(MediaType.APPLICATION_JSON)
[3/9] git commit: Push managementContext up to AbstractBrooklynObject
Posted by he...@apache.org.
Push managementContext up to AbstractBrooklynObject
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/5c5ed962
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/5c5ed962
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/5c5ed962
Branch: refs/heads/master
Commit: 5c5ed962397958c763b2b0fbc2146f713a286d27
Parents: fed8ee6
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 6 21:38:48 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 6 23:17:46 2014 +0100
----------------------------------------------------------------------
.../brooklyn/basic/AbstractBrooklynObject.java | 12 ++++++++
.../brooklyn/entity/basic/AbstractEntity.java | 1 +
.../location/basic/AbstractLocation.java | 29 ++++++++------------
.../policy/basic/AbstractEntityAdjunct.java | 10 -------
4 files changed, 24 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5c5ed962/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 7cc1ffd..e11e4b9 100644
--- a/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
+++ b/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
@@ -20,6 +20,8 @@ package brooklyn.basic;
import java.util.Set;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.internal.ManagementContextInternal;
import brooklyn.util.flags.SetFromFlag;
import brooklyn.util.text.Identifiers;
@@ -33,8 +35,18 @@ public abstract class AbstractBrooklynObject implements BrooklynObjectInternal {
private final Set<Object> tags = Sets.newLinkedHashSet();
+ private volatile ManagementContext managementContext;
+
protected abstract void requestPersist();
+ public void setManagementContext(ManagementContextInternal managementContext) {
+ this.managementContext = managementContext;
+ }
+
+ public ManagementContext getManagementContext() {
+ return managementContext;
+ }
+
@Override
public String getId() {
return id;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5c5ed962/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 e2c84fa..8cf279c 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@ -409,6 +409,7 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
}
public void setManagementContext(ManagementContextInternal managementContext) {
+ super.setManagementContext(managementContext);
getManagementSupport().setManagementContext(managementContext);
entityType.setName(getEntityTypeName());
if (displayNameAutoGenerated) displayName.set(getEntityType().getSimpleName()+":"+Strings.maxlen(getId(), 4));
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5c5ed962/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 9c0317e..f6657c8 100644
--- a/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
@@ -49,7 +49,6 @@ import brooklyn.location.Location;
import brooklyn.location.LocationSpec;
import brooklyn.location.geo.HasHostGeoInfo;
import brooklyn.location.geo.HostGeoInfo;
-import brooklyn.management.ManagementContext;
import brooklyn.management.internal.LocalLocationManager;
import brooklyn.management.internal.ManagementContextInternal;
import brooklyn.mementos.LocationMemento;
@@ -101,7 +100,6 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
private ConfigBag configBag = new ConfigBag();
- private volatile ManagementContext managementContext;
private volatile boolean managed;
private boolean _legacyConstruction;
@@ -169,14 +167,14 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
protected void assertNotYetManaged() {
- if (!inConstruction && (managementContext != null && managementContext.getLocationManager().isManaged(this))) {
+ if (!inConstruction && Locations.isManaged(this)) {
LOG.warn("Configuration being made to {} after deployment; may not be supported in future versions", this);
}
//throw new IllegalStateException("Cannot set configuration "+key+" on active location "+this)
}
public void setManagementContext(ManagementContextInternal managementContext) {
- this.managementContext = managementContext;
+ super.setManagementContext(managementContext);
if (displayNameAutoGenerated && getId() != null) name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4)));
Location oldParent = parent.get();
@@ -214,11 +212,6 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
}
- @Override
- public ManagementContext getManagementContext() {
- return managementContext;
- }
-
/**
* Will set fields from flags. The unused configuration can be found via the
* {@linkplain ConfigBag#getUnusedConfig()}.
@@ -320,7 +313,7 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
public boolean isManaged() {
- return managementContext != null && managed;
+ return getManagementContext() != null && managed;
}
public void onManagementStarted() {
@@ -330,8 +323,8 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
public void onManagementStopped() {
this.managed = false;
- if (managementContext.isRunning()) {
- BrooklynStorage storage = ((ManagementContextInternal)managementContext).getStorage();
+ if (getManagementContext().isRunning()) {
+ BrooklynStorage storage = ((ManagementContextInternal)getManagementContext()).getStorage();
storage.remove(getId()+"-parent");
storage.remove(getId()+"-children");
storage.remove(getId()+"-creationTime");
@@ -482,7 +475,7 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
protected <T extends Location> T addChild(LocationSpec<T> spec) {
- T child = managementContext.getLocationManager().createLocation(spec);
+ T child = getManagementContext().getLocationManager().createLocation(spec);
addChild(child);
return child;
}
@@ -508,10 +501,10 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
if (isManaged()) {
- Locations.manage(child, managementContext);
- } else if (managementContext != null) {
- if (((LocalLocationManager)managementContext.getLocationManager()).getLocationEvenIfPreManaged(child.getId()) == null) {
- ((ManagementContextInternal)managementContext).prePreManage(child);
+ Locations.manage(child, getManagementContext());
+ } else if (getManagementContext() != null) {
+ if (((LocalLocationManager)getManagementContext().getLocationManager()).getLocationEvenIfPreManaged(child.getId()) == null) {
+ ((ManagementContextInternal)getManagementContext()).prePreManage(child);
}
}
@@ -531,7 +524,7 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
child.setParent(null);
if (isManaged()) {
- managementContext.getLocationManager().unmanage(child);
+ getManagementContext().getLocationManager().unmanage(child);
}
}
return removed;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5c5ed962/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 39524f8..fed1fd2 100644
--- a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
@@ -68,8 +68,6 @@ import com.google.common.collect.Maps;
public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject implements BrooklynObjectInternal, EntityAdjunct, Configurable {
private static final Logger log = LoggerFactory.getLogger(AbstractEntityAdjunct.class);
- private volatile ManagementContext managementContext;
-
protected Map<String,Object> leftoverProperties = Maps.newLinkedHashMap();
private boolean _legacyConstruction;
@@ -180,14 +178,6 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
return _legacyConstruction;
}
- public void setManagementContext(ManagementContext managementContext) {
- this.managementContext = managementContext;
- }
-
- protected ManagementContext getManagementContext() {
- return managementContext;
- }
-
/**
* Used for legacy-style policies/enrichers on rebind, to indicate that init() should not be called.
* Will likely be deleted in a future release; should not be called apart from by framework code.
[8/9] git commit: Move isRebinding up to AbstractBrooklynObject
Posted by he...@apache.org.
Move isRebinding up to AbstractBrooklynObject
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/79b49a9c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/79b49a9c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/79b49a9c
Branch: refs/heads/master
Commit: 79b49a9cc0d9dd4d026b7e8690baa2cd77f9e6c1
Parents: 6cb55b5
Author: Aled Sage <al...@gmail.com>
Authored: Thu Aug 7 13:42:18 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Aug 7 13:43:33 2014 +0100
----------------------------------------------------------------------
core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java | 5 +++++
core/src/main/java/brooklyn/entity/basic/AbstractEntity.java | 4 ----
.../src/main/java/brooklyn/location/basic/AbstractLocation.java | 5 -----
.../main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java | 4 ----
4 files changed, 5 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/79b49a9c/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 8396ec7..b15e73d 100644
--- a/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
+++ b/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
@@ -26,6 +26,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import brooklyn.entity.proxying.InternalFactory;
+import brooklyn.entity.rebind.RebindManagerImpl;
import brooklyn.management.ManagementContext;
import brooklyn.management.internal.ManagementContextInternal;
import brooklyn.util.config.ConfigBag;
@@ -138,6 +139,10 @@ public abstract class AbstractBrooklynObject implements BrooklynObjectInternal {
return managementContext;
}
+ protected boolean isRebinding() {
+ return RebindManagerImpl.RebindTracker.isRebinding();
+ }
+
protected void requestPersist() {
// TODO Could add PolicyChangeListener, similar to EntityChangeListener; should we do that?
if (getManagementContext() != null) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/79b49a9c/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 729a2ff..ad2043c 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@ -355,10 +355,6 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
(o instanceof Entity && Objects.equal(getId(), ((Entity)o).getId()));
}
- protected boolean isRebinding() {
- return RebindManagerImpl.RebindTracker.isRebinding();
- }
-
public void setProxy(Entity proxy) {
if (selfProxy != null) throw new IllegalStateException("Proxy is already set; cannot reset proxy for "+toString());
selfProxy = checkNotNull(proxy, "proxy");
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/79b49a9c/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 734b1c8..c4b4ee0 100644
--- a/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
@@ -37,7 +37,6 @@ import brooklyn.config.ConfigKey;
import brooklyn.config.ConfigKey.HasConfigKey;
import brooklyn.entity.basic.EntityDynamicType;
import brooklyn.entity.rebind.BasicLocationRebindSupport;
-import brooklyn.entity.rebind.RebindManagerImpl;
import brooklyn.entity.rebind.RebindSupport;
import brooklyn.entity.trait.Configurable;
import brooklyn.event.basic.BasicConfigKey;
@@ -263,10 +262,6 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
}
- protected boolean isRebinding() {
- return RebindManagerImpl.RebindTracker.isRebinding();
- }
-
public boolean isManaged() {
return getManagementContext() != null && managed;
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/79b49a9c/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 a8cf150..7f0e08f 100644
--- a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
@@ -162,10 +162,6 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
return _legacyNoConstructionInit;
}
- protected boolean isRebinding() {
- return RebindManagerImpl.RebindTracker.isRebinding();
- }
-
public <T> T getConfig(ConfigKey<T> key) {
return configsInternal.getConfig(key);
}
[6/9] git commit: Adds AbstractBrooklynObjectRebindSupport
Posted by he...@apache.org.
Adds AbstractBrooklynObjectRebindSupport
- removes duplication from Basic*RebindSupport, for them all
extending AbstractBrooklynObjectRebindSupport
- adds MementosGenerator.newMemento(BrooklynObject)
- moves init+rebind method declarations into AbstractBrooklynObject
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/0ab0c392
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/0ab0c392
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/0ab0c392
Branch: refs/heads/master
Commit: 0ab0c3926fe356106d0519aae822a2e0bd7a16e3
Parents: 2a0d03a
Author: Aled Sage <al...@gmail.com>
Authored: Thu Aug 7 11:41:37 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Aug 7 11:41:37 2014 +0100
----------------------------------------------------------------------
.../brooklyn/basic/AbstractBrooklynObject.java | 31 +++++++
.../brooklyn/entity/basic/AbstractEntity.java | 28 -------
.../AbstractBrooklynObjectRebindSupport.java | 88 ++++++++++++++++++++
.../rebind/BasicEnricherRebindSupport.java | 48 ++---------
.../entity/rebind/BasicEntityRebindSupport.java | 64 ++++++--------
.../rebind/BasicLocationRebindSupport.java | 47 +++--------
.../entity/rebind/BasicPolicyRebindSupport.java | 49 ++---------
.../entity/rebind/dto/MementosGenerators.java | 22 ++++-
.../location/basic/AbstractLocation.java | 33 ++------
.../policy/basic/AbstractEntityAdjunct.java | 9 --
10 files changed, 189 insertions(+), 230 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0ab0c392/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 8764bf0..5ddefd0 100644
--- a/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
+++ b/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
@@ -37,6 +37,37 @@ public abstract class AbstractBrooklynObject implements BrooklynObjectInternal {
private volatile ManagementContext managementContext;
+ public abstract void setDisplayName(String newName);
+
+ /**
+ * Called by framework (in new-style instances where spec was used) after configuring etc,
+ * but before a reference to this instance is shared.
+ *
+ * To preserve backwards compatibility for if the instance is constructed directly, one
+ * can call the code below, but that means it will be called after references to this
+ * policy have been shared with other entities.
+ * <pre>
+ * {@code
+ * if (isLegacyConstruction()) {
+ * init();
+ * }
+ * }
+ * </pre>
+ */
+ public void init() {
+ // no-op
+ }
+
+ /**
+ * Called by framework on rebind (in new-style instances),
+ * after configuring but before the instance is managed (or is attached to an entity, depending on its type),
+ * and before a reference to this policy is shared.
+ * Note that {@link #init()} will not be called on rebind.
+ */
+ public void rebind() {
+ // no-op
+ }
+
public void setManagementContext(ManagementContextInternal managementContext) {
this.managementContext = managementContext;
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0ab0c392/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 8cf279c..0f1a184 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@ -518,34 +518,6 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
}
/**
- * Called by framework (in new-style entities) after configuring, setting parent, etc,
- * but before a reference to this entity is shared with other entities.
- *
- * To preserve backwards compatibility for if the entity is constructed directly, one
- * can add to the start method the code below, but that means it will be called after
- * references to this entity have been shared with other entities.
- * <pre>
- * {@code
- * if (isLegacyConstruction()) {
- * init();
- * }
- * }
- * </pre>
- */
- public void init() {
- // no-op
- }
-
- /**
- * Called by framework (in new-style entities where EntitySpec was used) on rebind,
- * after configuring but before the entity is managed.
- * Note that {@link #init()} will not be called on rebind.
- */
- public void rebind() {
- // no-op
- }
-
- /**
* Adds this as a child of the given entity; registers with application if necessary.
*/
@Override
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0ab0c392/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
new file mode 100644
index 0000000..4549dd2
--- /dev/null
+++ b/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
@@ -0,0 +1,88 @@
+/*
+ * 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.entity.rebind;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.basic.AbstractBrooklynObject;
+import brooklyn.entity.rebind.dto.MementosGenerators;
+import brooklyn.mementos.Memento;
+
+public abstract class AbstractBrooklynObjectRebindSupport<T extends Memento> implements RebindSupport<T> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractBrooklynObjectRebindSupport.class);
+
+ private final AbstractBrooklynObject instance;
+
+ public AbstractBrooklynObjectRebindSupport(AbstractBrooklynObject instance) {
+ this.instance = instance;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public T getMemento() {
+ T memento = (T) MementosGenerators.newMemento(instance);
+ if (LOG.isTraceEnabled()) LOG.trace("Created memento: {}", memento.toVerboseString());
+ return memento;
+ }
+
+ @Override
+ public void reconstruct(RebindContext rebindContext, T memento) {
+ if (LOG.isTraceEnabled()) LOG.trace("Reconstructing: {}", memento.toVerboseString());
+
+ instance.setDisplayName(memento.getDisplayName());
+ addConfig(rebindContext, memento);
+ addTags(rebindContext, memento);
+ addCustoms(rebindContext, memento);
+
+ doReconstruct(rebindContext, memento);
+ instance.rebind();
+ }
+
+ protected abstract void addConfig(RebindContext rebindContext, T memento);
+
+ protected abstract void addCustoms(RebindContext rebindContext, T memento);
+
+ protected void addTags(RebindContext rebindContext, T memento) {
+ for (Object tag : memento.getTags()) {
+ instance.getTagSupport().addTag(tag);
+ }
+ }
+
+ @Override
+ public void addPolicies(RebindContext rebindContext, T Memento) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addEnrichers(RebindContext rebindContext, T Memento) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * For overriding, to give custom reconstruct behaviour.
+ *
+ * @deprecated since 0.7.0; should never need to override the RebindSupport types
+ */
+ @Deprecated
+ protected void doReconstruct(RebindContext rebindContext, T memento) {
+ // default is no-op
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0ab0c392/core/src/main/java/brooklyn/entity/rebind/BasicEnricherRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicEnricherRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicEnricherRebindSupport.java
index 167d684..65f093d 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicEnricherRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicEnricherRebindSupport.java
@@ -18,39 +18,22 @@
*/
package brooklyn.entity.rebind;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import brooklyn.enricher.basic.AbstractEnricher;
-import brooklyn.entity.rebind.dto.MementosGenerators;
import brooklyn.mementos.EnricherMemento;
-import brooklyn.mementos.Memento;
import brooklyn.util.config.ConfigBag;
import brooklyn.util.flags.FlagUtils;
-public class BasicEnricherRebindSupport implements RebindSupport<EnricherMemento> {
+public class BasicEnricherRebindSupport extends AbstractBrooklynObjectRebindSupport<EnricherMemento> {
- private static final Logger LOG = LoggerFactory.getLogger(BasicEnricherRebindSupport.class);
-
private final AbstractEnricher enricher;
public BasicEnricherRebindSupport(AbstractEnricher enricher) {
+ super(enricher);
this.enricher = enricher;
}
@Override
- public EnricherMemento getMemento() {
- EnricherMemento memento = MementosGenerators.newEnricherMemento(enricher);
- if (LOG.isTraceEnabled()) LOG.trace("Creating memento for enricher: {}", memento.toVerboseString());
- return memento;
- }
-
- @Override
- public void reconstruct(RebindContext rebindContext, EnricherMemento memento) {
- if (LOG.isTraceEnabled()) LOG.trace("Reconstructing enricher: {}", memento.toVerboseString());
-
- enricher.setDisplayName(memento.getDisplayName());
-
+ protected void addConfig(RebindContext rebindContext, EnricherMemento memento) {
// TODO entity does config-lookup differently; the memento contains the config keys.
// BasicEntityMemento.postDeserialize uses the injectTypeClass to call EntityTypes.getDefinedConfigKeys(clazz)
//
@@ -58,31 +41,10 @@ public class BasicEnricherRebindSupport implements RebindSupport<EnricherMemento
ConfigBag configBag = ConfigBag.newInstance(memento.getConfig());
FlagUtils.setFieldsFromFlags(enricher, configBag);
FlagUtils.setAllConfigKeys(enricher, configBag, false);
- addTags(rebindContext, memento);
- doReconstruct(rebindContext, memento);
- ((AbstractEnricher)enricher).rebind();
- }
-
- protected void addTags(RebindContext rebindContext, Memento memento) {
- for (Object tag : memento.getTags()) {
- enricher.getTagSupport().addTag(tag);
- }
}
@Override
- public void addPolicies(RebindContext rebindContext, EnricherMemento Memento) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void addEnrichers(RebindContext rebindContext, EnricherMemento Memento) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * For overriding, to give custom reconsruct behaviour.
- */
- protected void doReconstruct(RebindContext rebindContext, EnricherMemento memento) {
- // default is no-op
+ protected void addCustoms(RebindContext rebindContext, EnricherMemento memento) {
+ // no-op
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0ab0c392/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
index bdb87e2..a6e1341 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
@@ -43,16 +43,18 @@ import brooklyn.policy.basic.AbstractPolicy;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
-public class BasicEntityRebindSupport implements RebindSupport<EntityMemento> {
+public class BasicEntityRebindSupport extends AbstractBrooklynObjectRebindSupport<EntityMemento> {
private static final Logger LOG = LoggerFactory.getLogger(BasicEntityRebindSupport.class);
private final EntityLocal entity;
- public BasicEntityRebindSupport(EntityLocal entity) {
+ public BasicEntityRebindSupport(AbstractEntity entity) {
+ super(entity);
this.entity = checkNotNull(entity, "entity");
}
+ // Can rely on super-type once the deprecated getMementoWithProperties is deleted
@Override
public EntityMemento getMemento() {
return getMementoWithProperties(Collections.<String,Object>emptyMap());
@@ -68,31 +70,13 @@ public class BasicEntityRebindSupport implements RebindSupport<EntityMemento> {
return memento;
}
- @SuppressWarnings("unchecked")
@Override
- public void reconstruct(RebindContext rebindContext, EntityMemento memento) {
- if (LOG.isTraceEnabled()) LOG.trace("Reconstructing entity: {}", memento.toVerboseString());
-
- // Note that the id should have been set in the constructor; it is immutable
- entity.setDisplayName(memento.getDisplayName());
-
- for (Effector<?> eff: memento.getEffectors())
+ @SuppressWarnings("unchecked")
+ protected void addCustoms(RebindContext rebindContext, EntityMemento memento) {
+ for (Effector<?> eff: memento.getEffectors()) {
((EntityInternal)entity).getMutableEntityType().addEffector(eff);
-
- for (Map.Entry<ConfigKey<?>, Object> entry : memento.getConfig().entrySet()) {
- try {
- ConfigKey<?> key = entry.getKey();
- Object value = entry.getValue();
- Class<?> type = (key.getType() != null) ? key.getType() : rebindContext.loadClass(key.getTypeName());
- entity.setConfig((ConfigKey<Object>)key, value);
- } catch (ClassNotFoundException e) {
- throw Throwables.propagate(e);
- }
}
-
- ((EntityInternal)entity).getConfigMap().addToLocalBag(memento.getConfigUnmatched());
- ((EntityInternal)entity).refreshInheritedConfig();
-
+
for (Map.Entry<AttributeSensor<?>, Object> entry : memento.getAttributes().entrySet()) {
try {
AttributeSensor<?> key = entry.getKey();
@@ -107,11 +91,24 @@ public class BasicEntityRebindSupport implements RebindSupport<EntityMemento> {
setParent(rebindContext, memento);
addChildren(rebindContext, memento);
addMembers(rebindContext, memento);
- addTags(rebindContext, memento);
addLocations(rebindContext, memento);
+ }
- doReconstruct(rebindContext, memento);
- ((AbstractEntity)entity).rebind();
+ @Override
+ protected void addConfig(RebindContext rebindContext, EntityMemento memento) {
+ for (Map.Entry<ConfigKey<?>, Object> entry : memento.getConfig().entrySet()) {
+ try {
+ ConfigKey<?> key = entry.getKey();
+ Object value = entry.getValue();
+ Class<?> type = (key.getType() != null) ? key.getType() : rebindContext.loadClass(key.getTypeName());
+ entity.setConfig((ConfigKey<Object>)key, value);
+ } catch (ClassNotFoundException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+
+ ((EntityInternal)entity).getConfigMap().addToLocalBag(memento.getConfigUnmatched());
+ ((EntityInternal)entity).refreshInheritedConfig();
}
@Override
@@ -148,13 +145,6 @@ public class BasicEntityRebindSupport implements RebindSupport<EntityMemento> {
}
}
- /**
- * For overriding, to reconstruct other fields.
- */
- protected void doReconstruct(RebindContext rebindContext, EntityMemento memento) {
- // default is no-op
- }
-
protected void addMembers(RebindContext rebindContext, EntityMemento memento) {
if (memento.getMembers().size() > 0) {
if (entity instanceof Group) {
@@ -173,12 +163,6 @@ public class BasicEntityRebindSupport implements RebindSupport<EntityMemento> {
}
}
- protected void addTags(RebindContext rebindContext, EntityMemento memento) {
- for (Object tag : memento.getTags()) {
- entity.getTagSupport().addTag(tag);
- }
- }
-
protected void addChildren(RebindContext rebindContext, EntityMemento memento) {
for (String childId : memento.getChildren()) {
Entity child = rebindContext.getEntity(childId);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0ab0c392/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 fd5610c..50b4147 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
@@ -36,16 +36,18 @@ import brooklyn.util.flags.TypeCoercions;
import com.google.common.collect.Sets;
-public class BasicLocationRebindSupport implements RebindSupport<LocationMemento> {
+public class BasicLocationRebindSupport extends AbstractBrooklynObjectRebindSupport<LocationMemento> {
private static final Logger LOG = LoggerFactory.getLogger(BasicLocationRebindSupport.class);
private final AbstractLocation location;
public BasicLocationRebindSupport(AbstractLocation location) {
+ super(location);
this.location = location;
}
+ // Can rely on super-type once the deprecated getMementoWithProperties is deleted
@Override
public LocationMemento getMemento() {
return getMementoWithProperties(Collections.<String,Object>emptyMap());
@@ -62,14 +64,11 @@ public class BasicLocationRebindSupport implements RebindSupport<LocationMemento
}
@Override
- public void reconstruct(RebindContext rebindContext, LocationMemento memento) {
- if (LOG.isTraceEnabled()) LOG.trace("Reconstructing location: {}", memento.toVerboseString());
-
- // FIXME Treat config like we do for entities; this code will disappear when locations become entities.
-
- // Note that the flags have been set in the constructor
+ protected void addConfig(RebindContext rebindContext, LocationMemento memento) {
+ // FIXME Treat config like we do for entities; this code will disappear when locations become entities.
+
+ // 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.getLocalConfigBag().putAll(memento.getLocationConfig()).markAll(
Sets.difference(memento.getLocationConfig().keySet(), memento.getLocationConfigUnused())).
@@ -101,30 +100,13 @@ public class BasicLocationRebindSupport implements RebindSupport<LocationMemento
// FIXME How to do findFieldForFlag without throwing exception if it's not there?
}
}
-
+ }
+
+ @Override
+ protected void addCustoms(RebindContext rebindContext, LocationMemento memento) {
setParent(rebindContext, memento);
addChildren(rebindContext, memento);
- addTags(rebindContext, memento);
location.init(); // TODO deprecated calling init; will be deleted
- location.rebind();
-
- doReconstruct(rebindContext, memento);
- }
-
- protected void addTags(RebindContext rebindContext, LocationMemento memento) {
- for (Object tag : memento.getTags()) {
- location.getTagSupport().addTag(tag);
- }
- }
-
- @Override
- public void addPolicies(RebindContext rebindContext, LocationMemento Memento) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void addEnrichers(RebindContext rebindContext, LocationMemento Memento) {
- throw new UnsupportedOperationException();
}
protected void addChildren(RebindContext rebindContext, LocationMemento memento) {
@@ -146,11 +128,4 @@ public class BasicLocationRebindSupport implements RebindSupport<LocationMemento
LOG.warn("Ignoring parent {} of location {}({}), as cannot be found", new Object[] {memento.getParent(), memento.getType(), memento.getId()});
}
}
-
- /**
- * For overriding, to give custom reconsruct behaviour.
- */
- protected void doReconstruct(RebindContext rebindContext, LocationMemento memento) {
- // default is no-op
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0ab0c392/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java
index 228b5ba..838023e 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicPolicyRebindSupport.java
@@ -18,39 +18,22 @@
*/
package brooklyn.entity.rebind;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.rebind.dto.MementosGenerators;
-import brooklyn.mementos.Memento;
import brooklyn.mementos.PolicyMemento;
import brooklyn.policy.basic.AbstractPolicy;
import brooklyn.util.config.ConfigBag;
import brooklyn.util.flags.FlagUtils;
-public class BasicPolicyRebindSupport implements RebindSupport<PolicyMemento> {
+public class BasicPolicyRebindSupport extends AbstractBrooklynObjectRebindSupport<PolicyMemento> {
- private static final Logger LOG = LoggerFactory.getLogger(BasicPolicyRebindSupport.class);
-
private final AbstractPolicy policy;
public BasicPolicyRebindSupport(AbstractPolicy policy) {
+ super(policy);
this.policy = policy;
}
@Override
- public PolicyMemento getMemento() {
- PolicyMemento memento = MementosGenerators.newPolicyMemento(policy);
- if (LOG.isTraceEnabled()) LOG.trace("Creating memento for policy: {}", memento.toVerboseString());
- return memento;
- }
-
- @Override
- public void reconstruct(RebindContext rebindContext, PolicyMemento memento) {
- if (LOG.isTraceEnabled()) LOG.trace("Reconstructing policy: {}", memento.toVerboseString());
-
- policy.setDisplayName(memento.getDisplayName());
-
+ protected void addConfig(RebindContext rebindContext, PolicyMemento memento) {
// TODO entity does config-lookup differently; the memento contains the config keys.
// BasicEntityMemento.postDeserialize uses the injectTypeClass to call EntityTypes.getDefinedConfigKeys(clazz)
//
@@ -58,32 +41,10 @@ public class BasicPolicyRebindSupport implements RebindSupport<PolicyMemento> {
ConfigBag configBag = ConfigBag.newInstance(memento.getConfig());
FlagUtils.setFieldsFromFlags(policy, configBag);
FlagUtils.setAllConfigKeys(policy, configBag, false);
- addTags(rebindContext, memento);
-
- doReconstruct(rebindContext, memento);
- ((AbstractPolicy)policy).rebind();
}
- protected void addTags(RebindContext rebindContext, Memento memento) {
- for (Object tag : memento.getTags()) {
- policy.getTagSupport().addTag(tag);
- }
- }
-
@Override
- public void addPolicies(RebindContext rebindContext, PolicyMemento Memento) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void addEnrichers(RebindContext rebindContext, PolicyMemento Memento) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * For overriding, to give custom reconsruct behaviour.
- */
- protected void doReconstruct(RebindContext rebindContext, PolicyMemento memento) {
- // default is no-op
+ protected void addCustoms(RebindContext rebindContext, PolicyMemento memento) {
+ // no-op
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0ab0c392/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
index 79600da..3289665 100644
--- a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
+++ b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
@@ -44,6 +44,7 @@ import brooklyn.mementos.BrooklynMemento;
import brooklyn.mementos.EnricherMemento;
import brooklyn.mementos.EntityMemento;
import brooklyn.mementos.LocationMemento;
+import brooklyn.mementos.Memento;
import brooklyn.mementos.PolicyMemento;
import brooklyn.policy.Enricher;
import brooklyn.policy.Policy;
@@ -60,6 +61,23 @@ public class MementosGenerators {
private MementosGenerators() {}
/**
+ * Inspects a brooklyn object to create a corresponding memento.
+ */
+ public static Memento newMemento(BrooklynObject instance) {
+ if (instance instanceof Entity) {
+ return newEntityMemento((Entity)instance);
+ } else if (instance instanceof Location) {
+ return newLocationMemento((Location)instance);
+ } else if (instance instanceof Policy) {
+ return newPolicyMemento((Policy)instance);
+ } else if (instance instanceof Enricher) {
+ return newEnricherMemento((Enricher)instance);
+ } else {
+ throw new IllegalArgumentException("Unexpected brooklyn type: "+(instance == null ? "null" : instance.getClass())+" ("+instance+")");
+ }
+ }
+
+ /**
* Walks the contents of a ManagementContext, to create a corresponding memento.
*
* @deprecated since 0.7.0; will be moved to test code; generate each entity/location memento separately
@@ -103,7 +121,7 @@ public class MementosGenerators {
}
/**
- * @deprecated since 0.7.0; use {@link #newEntityMemento(Enricher)} instead
+ * @deprecated since 0.7.0; use {@link #newMemento(BrooklynObject)} instead
*/
@Deprecated
public static BasicEntityMemento.Builder newEntityMementoBuilder(Entity entity) {
@@ -197,7 +215,7 @@ public class MementosGenerators {
}
/**
- * @deprecated since 0.7.0; use {@link #newLocationMemento(Enricher)} instead
+ * @deprecated since 0.7.0; use {@link #newMemento(BrooklynObject)} instead
*/
@Deprecated
public static BasicLocationMemento.Builder newLocationMementoBuilder(Location location) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0ab0c392/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 9937e47..8aea917 100644
--- a/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
@@ -281,33 +281,6 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
}
- /**
- * Called by framework (in new-style locations) after configuring, setting parent, etc,
- * but before a reference to this location is shared with other locations.
- *
- * To preserve backwards compatibility for if the location is constructed directly, one
- * can call the code below, but that means it will be called after references to this
- * location have been shared with other entities.
- * <pre>
- * {@code
- * if (isLegacyConstruction()) {
- * init();
- * }
- * }
- * </pre>
- */
- public void init() {
- // no-op
- }
-
- /**
- * Called by framework (in new-style locations) on rebind, after configuring, setting parent, etc.
- * Note that a future change to Brooklyn is that {@link #init()} will not be called when rebinding.
- */
- public void rebind() {
- // no-op
- }
-
protected boolean isRebinding() {
return RebindManagerImpl.RebindTracker.isRebinding();
}
@@ -438,7 +411,11 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
return configBag.put(key, value);
}
- /** @since 0.6.0 (?) - use getDisplayName */
+ /**
+ * @since 0.6.0 (?) - use getDisplayName
+ * @deprecated since 0.7.0; use {@link #getDisplayName()}
+ */
+ @Deprecated
public void setName(String newName) {
setDisplayName(newName);
displayNameAutoGenerated = false;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0ab0c392/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 fed1fd2..a1e2449 100644
--- a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
@@ -206,15 +206,6 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
// no-op
}
- /**
- * Called by framework (in new-style policies/enrichers where PolicySpec/EnricherSpec was used) on rebind,
- * after configuring but before {@link #setEntity(EntityLocal)} and before a reference to this policy is shared.
- * Note that {@link #init()} will not be called on rebind.
- */
- public void rebind() {
- // no-op
- }
-
protected boolean isRebinding() {
return RebindManagerImpl.RebindTracker.isRebinding();
}
[2/9] git commit: ChangeListener: use BrooklynObject
Posted by he...@apache.org.
ChangeListener: use BrooklynObject
- instead of having separate methods for Entity, Location, etc,
just have one for BrooklynObject.
- move requestPersist() impl up to AbstractBrooklynObject
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/bf0b3e7d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/bf0b3e7d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/bf0b3e7d
Branch: refs/heads/master
Commit: bf0b3e7db3457cc5cc5e407c718555740d5719f3
Parents: 5c5ed96
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 6 22:00:47 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 6 23:17:46 2014 +0100
----------------------------------------------------------------------
.../brooklyn/entity/rebind/ChangeListener.java | 44 +----
.../brooklyn/basic/AbstractBrooklynObject.java | 9 +-
.../enricher/basic/AbstractEnricher.java | 8 -
.../rebind/ImmediateDeltaChangeListener.java | 179 +++++++------------
.../rebind/PeriodicDeltaChangeListener.java | 153 ++++++----------
.../entity/rebind/RebindManagerImpl.java | 100 ++---------
.../location/basic/AbstractLocation.java | 8 -
.../brooklyn/policy/basic/AbstractPolicy.java | 8 -
8 files changed, 147 insertions(+), 362 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bf0b3e7d/api/src/main/java/brooklyn/entity/rebind/ChangeListener.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/entity/rebind/ChangeListener.java b/api/src/main/java/brooklyn/entity/rebind/ChangeListener.java
index 582c7e0..02d4ad2 100644
--- a/api/src/main/java/brooklyn/entity/rebind/ChangeListener.java
+++ b/api/src/main/java/brooklyn/entity/rebind/ChangeListener.java
@@ -18,10 +18,7 @@
*/
package brooklyn.entity.rebind;
-import brooklyn.entity.Entity;
-import brooklyn.location.Location;
-import brooklyn.policy.Enricher;
-import brooklyn.policy.Policy;
+import brooklyn.basic.BrooklynObject;
/**
* Listener to be notified of changes within brooklyn, so that the new state
@@ -34,41 +31,14 @@ import brooklyn.policy.Policy;
public interface ChangeListener {
public static final ChangeListener NOOP = new ChangeListener() {
- @Override public void onManaged(Entity entity) {}
- @Override public void onUnmanaged(Entity entity) {}
- @Override public void onChanged(Entity entity) {}
- @Override public void onManaged(Location location) {}
- @Override public void onUnmanaged(Location location) {}
- @Override public void onChanged(Location location) {}
- @Override public void onManaged(Policy policy) {}
- @Override public void onUnmanaged(Policy policy) {}
- @Override public void onChanged(Policy policy) {}
- @Override public void onManaged(Enricher enricher) {}
- @Override public void onUnmanaged(Enricher enricher) {}
- @Override public void onChanged(Enricher enricher) {}
+ @Override public void onChanged(BrooklynObject instance) {}
+ @Override public void onManaged(BrooklynObject instance) {}
+ @Override public void onUnmanaged(BrooklynObject instance) {}
};
-
- void onManaged(Entity entity);
-
- void onUnmanaged(Entity entity);
-
- void onChanged(Entity entity);
-
- void onManaged(Location location);
-
- void onUnmanaged(Location location);
- void onChanged(Location location);
+ void onManaged(BrooklynObject instance);
- void onManaged(Policy policy);
-
- void onUnmanaged(Policy policy);
-
- void onChanged(Policy policy);
+ void onUnmanaged(BrooklynObject instance);
- void onManaged(Enricher enricher);
-
- void onUnmanaged(Enricher enricher);
-
- void onChanged(Enricher enricher);
+ void onChanged(BrooklynObject instance);
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bf0b3e7d/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 e11e4b9..8764bf0 100644
--- a/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
+++ b/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
@@ -37,8 +37,6 @@ public abstract class AbstractBrooklynObject implements BrooklynObjectInternal {
private volatile ManagementContext managementContext;
- protected abstract void requestPersist();
-
public void setManagementContext(ManagementContextInternal managementContext) {
this.managementContext = managementContext;
}
@@ -47,6 +45,13 @@ public abstract class AbstractBrooklynObject implements BrooklynObjectInternal {
return managementContext;
}
+ protected void requestPersist() {
+ // TODO Could add PolicyChangeListener, similar to EntityChangeListener; should we do that?
+ if (getManagementContext() != null) {
+ getManagementContext().getRebindManager().getChangeListener().onChanged(this);
+ }
+ }
+
@Override
public String getId() {
return id;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bf0b3e7d/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 e029ab2..8503663 100644
--- a/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
+++ b/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
@@ -64,12 +64,4 @@ public abstract class AbstractEnricher extends AbstractEntityAdjunct implements
protected void onChanged() {
requestPersist();
}
-
- @Override
- protected void requestPersist() {
- // TODO Could add PolicyChangeListener, similar to EntityChangeListener; should we do that?
- if (getManagementContext() != null) {
- getManagementContext().getRebindManager().getChangeListener().onChanged(this);
- }
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bf0b3e7d/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java b/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
index 06c8519..67a8c96 100644
--- a/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
+++ b/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
@@ -21,12 +21,17 @@ package brooklyn.entity.rebind;
import java.util.Collection;
import java.util.Map;
+import brooklyn.basic.BrooklynObject;
+import brooklyn.basic.BrooklynObjectInternal;
import brooklyn.entity.Entity;
-import brooklyn.entity.basic.EntityInternal;
import brooklyn.location.Location;
import brooklyn.location.basic.LocationInternal;
import brooklyn.mementos.BrooklynMementoPersister;
+import brooklyn.mementos.EnricherMemento;
+import brooklyn.mementos.EntityMemento;
import brooklyn.mementos.LocationMemento;
+import brooklyn.mementos.Memento;
+import brooklyn.mementos.PolicyMemento;
import brooklyn.policy.Enricher;
import brooklyn.policy.Policy;
@@ -55,133 +60,87 @@ public class ImmediateDeltaChangeListener implements ChangeListener {
}
@Override
- public void onManaged(Entity entity) {
- onChanged(entity);
+ public void onManaged(BrooklynObject instance) {
+ onChanged(instance);
}
@Override
- public void onManaged(Location location) {
- onChanged(location);
- }
-
- @Override
- public void onManaged(Policy policy) {
- onChanged(policy);
- }
-
- @Override
- public void onManaged(Enricher enricher) {
- onChanged(enricher);
- }
-
- @Override
- public void onChanged(Entity entity) {
+ public void onUnmanaged(BrooklynObject instance) {
if (running && persister != null) {
PersisterDeltaImpl delta = new PersisterDeltaImpl();
- delta.entities.add(((EntityInternal)entity).getRebindSupport().getMemento());
-
- // FIXME How to let the policy/location tell us about changes?
- // Don't do this every time!
- Map<String, LocationMemento> locations = Maps.newLinkedHashMap();
- for (Location location : entity.getLocations()) {
- if (!locations.containsKey(location.getId())) {
- Collection<Location> locsInHierachy = TreeUtils.findLocationsInHierarchy(location);
-
- /*
- * Need to guarantee "happens before", with any thread that has written
- * fields of these locations. In particular, saw failures where SshMachineLocation
- * had null address field. Our hypothesis is that the location had its fields set,
- * and then set its parent (which goes through a synchronized in AbstractLocation.addChild),
- * but that this memento-generating code did not go through any synchronization or volatiles.
- */
- synchronized (new Object()) {}
-
- for (Location locInHierarchy : locsInHierachy) {
- locations.put(locInHierarchy.getId(), ((LocationInternal)locInHierarchy).getRebindSupport().getMemento());
- }
- }
+ if (instance instanceof Entity) {
+ delta.removedEntityIds.add(instance.getId());
+ } else if (instance instanceof Location) {
+ delta.removedLocationIds.add(instance.getId());
+ } else if (instance instanceof Policy) {
+ delta.removedPolicyIds.add(instance.getId());
+ } else if (instance instanceof Enricher) {
+ delta.removedEnricherIds.add(instance.getId());
+ } else {
+ throw new IllegalStateException("Unexpected brooklyn type: "+instance);
}
- delta.locations = locations.values();
-
- // FIXME Not including policies, because lots of places regiser anonymous inner class policies
- // (e.g. AbstractController registering a AbstractMembershipTrackingPolicy)
- // Also, the entity constructor often re-creates the policy.
- // Also see MementosGenerator.newEntityMementoBuilder()
-// List<PolicyMemento> policies = Lists.newArrayList();
-// for (Policy policy : entity.getPolicies()) {
-// policies.add(policy.getRebindSupport().getMemento());
-// }
-// delta.policies = policies;
-
- /*
- * Make the writes to the mementos visible to other threads.
- */
- synchronized (new Object()) {}
-
- persister.delta(delta, exceptionHandler);
- }
- }
-
- @Override
- public void onUnmanaged(Entity entity) {
- if (running && persister != null) {
- PersisterDeltaImpl delta = new PersisterDeltaImpl();
- delta.removedEntityIds.add(entity.getId());
persister.delta(delta, exceptionHandler);
}
}
@Override
- public void onUnmanaged(Location location) {
+ public void onChanged(BrooklynObject instance) {
if (running && persister != null) {
PersisterDeltaImpl delta = new PersisterDeltaImpl();
- delta.removedLocationIds.add(location.getId());
+ Memento memento = ((BrooklynObjectInternal)instance).getRebindSupport().getMemento();
+ if (instance instanceof Entity) {
+ delta.entities.add((EntityMemento) memento);
+ addEntityAdjuncts((Entity)instance, delta);
+ } else if (instance instanceof Location) {
+ delta.locations.add((LocationMemento) memento);
+ } else if (instance instanceof Policy) {
+ delta.policies.add((PolicyMemento) memento);
+ } else if (instance instanceof Enricher) {
+ delta.enrichers.add((EnricherMemento) memento);
+ } else {
+ throw new IllegalStateException("Unexpected brooklyn type: "+instance);
+ }
persister.delta(delta, exceptionHandler);
}
}
-
- @Override
- public void onUnmanaged(Policy policy) {
- if (running && persister != null) {
- PersisterDeltaImpl delta = new PersisterDeltaImpl();
- delta.removedPolicyIds.add(policy.getId());
- persister.delta(delta, exceptionHandler);
+
+ private void addEntityAdjuncts(Entity entity, PersisterDeltaImpl delta) {
+ // FIXME How to let the policy/location tell us about changes?
+ // Don't do this every time!
+ Map<String, LocationMemento> locations = Maps.newLinkedHashMap();
+ for (Location location : entity.getLocations()) {
+ if (!locations.containsKey(location.getId())) {
+ Collection<Location> locsInHierachy = TreeUtils.findLocationsInHierarchy(location);
+
+ /*
+ * Need to guarantee "happens before", with any thread that has written
+ * fields of these locations. In particular, saw failures where SshMachineLocation
+ * had null address field. Our hypothesis is that the location had its fields set,
+ * and then set its parent (which goes through a synchronized in AbstractLocation.addChild),
+ * but that this memento-generating code did not go through any synchronization or volatiles.
+ */
+ synchronized (new Object()) {}
+
+ for (Location locInHierarchy : locsInHierachy) {
+ locations.put(locInHierarchy.getId(), ((LocationInternal)locInHierarchy).getRebindSupport().getMemento());
+ }
+ }
}
- }
+ delta.locations = locations.values();
- @Override
- public void onUnmanaged(Enricher enricher) {
- if (running && persister != null) {
- PersisterDeltaImpl delta = new PersisterDeltaImpl();
- delta.removedEnricherIds.add(enricher.getId());
- persister.delta(delta, exceptionHandler);
- }
- }
+ // FIXME Not including policies, because lots of places regiser anonymous inner class policies
+ // (e.g. AbstractController registering a AbstractMembershipTrackingPolicy)
+ // Also, the entity constructor often re-creates the policy.
+ // Also see MementosGenerator.newEntityMementoBuilder()
+// List<PolicyMemento> policies = Lists.newArrayList();
+// for (Policy policy : entity.getPolicies()) {
+// policies.add(policy.getRebindSupport().getMemento());
+// }
+// delta.policies = policies;
- @Override
- public void onChanged(Location location) {
- if (running && persister != null) {
- PersisterDeltaImpl delta = new PersisterDeltaImpl();
- delta.locations.add(((LocationInternal)location).getRebindSupport().getMemento());
- persister.delta(delta, exceptionHandler);
- }
- }
-
- @Override
- public void onChanged(Policy policy) {
- if (running && persister != null) {
- PersisterDeltaImpl delta = new PersisterDeltaImpl();
- delta.policies.add(policy.getRebindSupport().getMemento());
- persister.delta(delta, exceptionHandler);
- }
- }
-
- @Override
- public void onChanged(Enricher enricher) {
- if (running && persister != null) {
- PersisterDeltaImpl delta = new PersisterDeltaImpl();
- delta.enrichers.add(enricher.getRebindSupport().getMemento());
- persister.delta(delta, exceptionHandler);
- }
+ /*
+ * Make the writes to the mementos visible to other threads.
+ */
+ synchronized (new Object()) {}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bf0b3e7d/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java b/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
index 955ba2e..7613c2a 100644
--- a/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
+++ b/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
@@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicLong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import brooklyn.basic.BrooklynObject;
import brooklyn.entity.Entity;
import brooklyn.entity.basic.EntityInternal;
import brooklyn.internal.BrooklynFeatureEnablement;
@@ -280,120 +281,74 @@ public class PeriodicDeltaChangeListener implements ChangeListener {
}
@Override
- public synchronized void onManaged(Entity entity) {
- if (LOG.isTraceEnabled()) LOG.trace("onManaged: {}", entity);
- onChanged(entity);
+ public synchronized void onManaged(BrooklynObject instance) {
+ if (LOG.isTraceEnabled()) LOG.trace("onManaged: {}", instance);
+ onChanged(instance);
}
@Override
- public synchronized void onManaged(Location location) {
- if (LOG.isTraceEnabled()) LOG.trace("onManaged: {}", location);
- onChanged(location);
- }
-
- @Override
- public synchronized void onManaged(Policy policy) {
- if (LOG.isTraceEnabled()) LOG.trace("onManaged: {}", policy);
- onChanged(policy);
- }
-
- @Override
- public synchronized void onManaged(Enricher enricher) {
- if (LOG.isTraceEnabled()) LOG.trace("onManaged: {}", enricher);
- onChanged(enricher);
- }
-
- @Override
- public synchronized void onChanged(Entity entity) {
- if (LOG.isTraceEnabled()) LOG.trace("onChanged: {}", entity);
+ public synchronized void onUnmanaged(BrooklynObject instance) {
+ if (LOG.isTraceEnabled()) LOG.trace("onUnmanaged: {}", instance);
if (!isStopped()) {
- deltaCollector.entities.add(entity);
-
- // FIXME How to let the policy/location tell us about changes? Don't do this every time!
- for (Location location : entity.getLocations()) {
- deltaCollector.locations.addAll(TreeUtils.findLocationsInHierarchy(location));
- }
-
- if (persistPoliciesEnabled) {
+ if (instance instanceof Entity) {
+ Entity entity = (Entity) instance;
+ deltaCollector.removedEntityIds.add(entity.getId());
+ deltaCollector.entities.remove(entity);
+
for (Policy policy : entity.getPolicies()) {
- deltaCollector.policies.add(policy);
+ deltaCollector.removedPolicyIds.add(policy.getId());
+ deltaCollector.policies.remove(policy);
}
- }
-
- if (persistEnrichersEnabled) {
for (Enricher enricher : entity.getEnrichers()) {
- deltaCollector.enrichers.add(enricher);
+ deltaCollector.removedEnricherIds.add(enricher.getId());
+ deltaCollector.enrichers.remove(enricher);
}
+ } else if (instance instanceof Location) {
+ deltaCollector.removedLocationIds.add(instance.getId());
+ deltaCollector.locations.remove(instance);
+ } else if (instance instanceof Policy) {
+ deltaCollector.removedPolicyIds.add(instance.getId());
+ deltaCollector.policies.remove(instance);
+ } else if (instance instanceof Enricher) {
+ deltaCollector.removedEnricherIds.add(instance.getId());
+ deltaCollector.enrichers.remove(instance);
+ } else {
+ throw new IllegalStateException("Unexpected brooklyn type: "+instance);
}
}
}
-
- @Override
- public synchronized void onUnmanaged(Entity entity) {
- if (LOG.isTraceEnabled()) LOG.trace("onUnmanaged: {}", entity);
- if (!isStopped()) {
- deltaCollector.removedEntityIds.add(entity.getId());
- deltaCollector.entities.remove(entity);
-
- for (Policy policy : entity.getPolicies()) {
- deltaCollector.removedPolicyIds.add(policy.getId());
- deltaCollector.policies.remove(policy);
- }
- for (Enricher enricher : entity.getEnrichers()) {
- deltaCollector.removedEnricherIds.add(enricher.getId());
- deltaCollector.enrichers.remove(enricher);
- }
- }
- }
-
- @Override
- public synchronized void onUnmanaged(Location location) {
- if (LOG.isTraceEnabled()) LOG.trace("onUnmanaged: {}", location);
- if (!isStopped()) {
- deltaCollector.removedLocationIds.add(location.getId());
- deltaCollector.locations.remove(location);
- }
- }
@Override
- public synchronized void onUnmanaged(Policy policy) {
- if (LOG.isTraceEnabled()) LOG.trace("onUnmanaged: {}", policy);
+ public synchronized void onChanged(BrooklynObject instance) {
+ if (LOG.isTraceEnabled()) LOG.trace("onChanged: {}", instance);
if (!isStopped()) {
- deltaCollector.removedPolicyIds.add(policy.getId());
- deltaCollector.policies.remove(policy);
- }
- }
-
- @Override
- public synchronized void onUnmanaged(Enricher enricher) {
- if (LOG.isTraceEnabled()) LOG.trace("onUnmanaged: {}", enricher);
- if (!isStopped()) {
- deltaCollector.removedEnricherIds.add(enricher.getId());
- deltaCollector.enrichers.remove(enricher);
- }
- }
+ if (instance instanceof Entity) {
+ Entity entity = (Entity) instance;
+ deltaCollector.entities.add(entity);
- @Override
- public synchronized void onChanged(Location location) {
- if (LOG.isTraceEnabled()) LOG.trace("onChanged: {}", location);
- if (!isStopped()) {
- deltaCollector.locations.add(location);
- }
- }
-
- @Override
- public synchronized void onChanged(Policy policy) {
- if (LOG.isTraceEnabled()) LOG.trace("onChanged: {}", policy);
- if (!isStopped()) {
- deltaCollector.policies.add(policy);
- }
- }
-
- @Override
- public synchronized void onChanged(Enricher enricher) {
- if (LOG.isTraceEnabled()) LOG.trace("onChanged: {}", enricher);
- if (!isStopped()) {
- deltaCollector.enrichers.add(enricher);
+ // FIXME How to let the policy/location tell us about changes? Don't do this every time!
+ for (Location location : entity.getLocations()) {
+ deltaCollector.locations.addAll(TreeUtils.findLocationsInHierarchy(location));
+ }
+ if (persistPoliciesEnabled) {
+ for (Policy policy : entity.getPolicies()) {
+ deltaCollector.policies.add(policy);
+ }
+ }
+ if (persistEnrichersEnabled) {
+ for (Enricher enricher : entity.getEnrichers()) {
+ deltaCollector.enrichers.add(enricher);
+ }
+ }
+ } else if (instance instanceof Location) {
+ deltaCollector.locations.add((Location) instance);
+ } else if (instance instanceof Policy) {
+ deltaCollector.policies.add((Policy) instance);
+ } else if (instance instanceof Enricher) {
+ deltaCollector.enrichers.add((Enricher) instance);
+ } else {
+ throw new IllegalStateException("Unexpected brooklyn type: "+instance);
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bf0b3e7d/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java b/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
index 2bd121c..4e8ffc8 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
@@ -30,6 +30,7 @@ import java.util.concurrent.TimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import brooklyn.basic.BrooklynObject;
import brooklyn.config.ConfigKey;
import brooklyn.enricher.basic.AbstractEnricher;
import brooklyn.entity.Application;
@@ -747,110 +748,29 @@ public class RebindManagerImpl implements RebindManager {
}
@Override
- public void onManaged(Entity entity) {
+ public void onManaged(BrooklynObject instance) {
try {
- delegate.onManaged(entity);
+ delegate.onManaged(instance);
} catch (Throwable t) {
- LOG.error("Error persisting mememento onManaged("+entity+"); continuing.", t);
+ LOG.error("Error persisting mememento onManaged("+instance+"); continuing.", t);
}
}
@Override
- public void onManaged(Location location) {
+ public void onChanged(BrooklynObject instance) {
try {
- delegate.onManaged(location);
+ delegate.onChanged(instance);
} catch (Throwable t) {
- LOG.error("Error persisting mememento onManaged("+location+"); continuing.", t);
+ LOG.error("Error persisting mememento onChanged("+instance+"); continuing.", t);
}
}
@Override
- public void onManaged(Policy policy) {
+ public void onUnmanaged(BrooklynObject instance) {
try {
- delegate.onManaged(policy);
+ delegate.onUnmanaged(instance);
} catch (Throwable t) {
- LOG.error("Error persisting mememento onManaged("+policy+"); continuing.", t);
- }
- }
-
- @Override
- public void onManaged(Enricher enricher) {
- try {
- delegate.onManaged(enricher);
- } catch (Throwable t) {
- LOG.error("Error persisting mememento onManaged("+enricher+"); continuing.", t);
- }
- }
-
- @Override
- public void onChanged(Entity entity) {
- try {
- delegate.onChanged(entity);
- } catch (Throwable t) {
- LOG.error("Error persisting mememento onChanged("+entity+"); continuing.", t);
- }
- }
-
- @Override
- public void onUnmanaged(Entity entity) {
- try {
- delegate.onUnmanaged(entity);
- } catch (Throwable t) {
- LOG.error("Error persisting mememento onUnmanaged("+entity+"); continuing.", t);
- }
- }
-
- @Override
- public void onUnmanaged(Location location) {
- try {
- delegate.onUnmanaged(location);
- } catch (Throwable t) {
- LOG.error("Error persisting mememento onUnmanaged("+location+"); continuing.", t);
- }
- }
-
- @Override
- public void onUnmanaged(Policy policy) {
- try {
- delegate.onUnmanaged(policy);
- } catch (Throwable t) {
- LOG.error("Error persisting mememento onUnmanaged("+policy+"); continuing.", t);
- }
- }
-
- @Override
- public void onUnmanaged(Enricher enricher) {
- try {
- delegate.onUnmanaged(enricher);
- } catch (Throwable t) {
- LOG.error("Error persisting mememento onUnmanaged("+enricher+"); continuing.", t);
- }
- }
-
- @Override
- public void onChanged(Location location) {
- try {
- delegate.onChanged(location);
- } catch (Throwable t) {
- LOG.error("Error persisting mememento onChanged("+location+"); continuing.", t);
- }
- }
-
- @Override
- public void onChanged(Policy policy) {
- try {
- delegate.onChanged(policy);
- } catch (Throwable t) {
- LOG.error("Error persisting mememento onChanged("+policy+"); continuing.", t);
- }
- }
-
- @Override
- public void onChanged(Enricher enricher) {
- try {
- delegate.onChanged(enricher);
- } catch (Throwable t) {
- LOG.error("Error persisting mememento onChanged("+enricher+"); continuing.", t);
+ LOG.error("Error persisting mememento onUnmanaged("+instance+"); continuing.", t);
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bf0b3e7d/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 f6657c8..9937e47 100644
--- a/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
@@ -558,14 +558,6 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
@Override
- public void requestPersist() {
- // TODO Could add LocationChangeListener, similar to EntityChangeListener; should we do that?
- if (getManagementContext() != null) {
- getManagementContext().getRebindManager().getChangeListener().onChanged(this);
- }
- }
-
- @Override
public RebindSupport<LocationMemento> getRebindSupport() {
return new BasicLocationRebindSupport(this);
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bf0b3e7d/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 52fa5b9..1da196e 100644
--- a/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java
@@ -101,14 +101,6 @@ public abstract class AbstractPolicy extends AbstractEntityAdjunct implements Po
}
@Override
- protected void requestPersist() {
- // TODO Could add PolicyChangeListener, similar to EntityChangeListener; should we do that?
- if (getManagementContext() != null) {
- getManagementContext().getRebindManager().getChangeListener().onChanged(this);
- }
- }
-
- @Override
public RebindSupport<PolicyMemento> getRebindSupport() {
return new BasicPolicyRebindSupport(this);
}
[7/9] git commit: Move construction mess into AbstractBrooklynObject
Posted by he...@apache.org.
Move construction mess into AbstractBrooklynObject
- delete duplication from AbstractEntity, AbstractLocation, etc
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/6cb55b50
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/6cb55b50
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/6cb55b50
Branch: refs/heads/master
Commit: 6cb55b500449c6d6dee033509d50e9a20cc16d1e
Parents: 0ab0c39
Author: Aled Sage <al...@gmail.com>
Authored: Thu Aug 7 13:24:16 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Aug 7 13:43:33 2014 +0100
----------------------------------------------------------------------
.../brooklyn/basic/AbstractBrooklynObject.java | 62 ++++++++++
.../brooklyn/entity/basic/AbstractEntity.java | 124 +++++++++----------
.../location/basic/AbstractLocation.java | 48 ++-----
.../AggregatingMachineProvisioningLocation.java | 4 +-
.../FixedListMachineProvisioningLocation.java | 4 +-
.../LocalhostMachineProvisioningLocation.java | 10 +-
.../location/basic/SshMachineLocation.java | 3 +-
.../policy/basic/AbstractEntityAdjunct.java | 80 +++---------
.../location/jclouds/JcloudsLocation.java | 4 +-
9 files changed, 167 insertions(+), 172 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6cb55b50/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 5ddefd0..8396ec7 100644
--- a/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
+++ b/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
@@ -18,18 +18,30 @@
*/
package brooklyn.basic;
+import java.util.Collections;
+import java.util.Map;
import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.proxying.InternalFactory;
import brooklyn.management.ManagementContext;
import brooklyn.management.internal.ManagementContextInternal;
+import brooklyn.util.config.ConfigBag;
import brooklyn.util.flags.SetFromFlag;
import brooklyn.util.text.Identifiers;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
public abstract class AbstractBrooklynObject implements BrooklynObjectInternal {
+ private static final Logger log = LoggerFactory.getLogger(AbstractBrooklynObject.class);
+
+ private boolean _legacyConstruction;
+
@SetFromFlag(value="id")
private String id = Identifiers.makeRandomId(8);
@@ -39,6 +51,56 @@ public abstract class AbstractBrooklynObject implements BrooklynObjectInternal {
public abstract void setDisplayName(String newName);
+ public AbstractBrooklynObject() {
+ this(Maps.newLinkedHashMap());
+ }
+
+ public AbstractBrooklynObject(Map<?,?> properties) {
+ _legacyConstruction = !InternalFactory.FactoryConstructionTracker.isConstructing();
+
+ if (!_legacyConstruction && properties!=null && !properties.isEmpty()) {
+ log.warn("Forcing use of deprecated old-style location construction for "+getClass().getName()+" because properties were specified ("+properties+"); instead use specs (e.g. LocationSpec, EntitySpec, etc)");
+ if (log.isDebugEnabled())
+ log.debug("Source of use of old-style construction", new Throwable("Source of use of old-style construction"));
+ _legacyConstruction = true;
+ }
+
+ // rely on sub-class to call configure(properties), because otherwise its fields will not have been initialised
+ }
+
+ /**
+ * See {@link #configure(Map)}
+ *
+ * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly
+ */
+ @Deprecated
+ protected AbstractBrooklynObject configure() {
+ return configure(Collections.emptyMap());
+ }
+
+ /**
+ * Will set fields from flags, and put the remaining ones into the 'leftovers' map.
+ * For some types, you can find unused config via {@link ConfigBag#getUnusedConfig()}.
+ * <p>
+ * To be overridden by AbstractEntity, AbstractLoation, AbstractPolicy, AbstractEnricher, etc.
+ * <p>
+ * But should not be overridden by specific entity types. If you do, the entity may break in
+ * subsequent releases. Also note that if you require fields to be initialized you must do that
+ * in this method. You must *not* rely on field initializers because they may not run until *after*
+ * this method (this method is invoked by the constructor in this class, so initializers
+ * in subclasses will not have run when this overridden method is invoked.)
+ *
+ * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly
+ */
+ @Deprecated
+ protected AbstractBrooklynObject configure(Map flags) {
+ return this;
+ }
+
+ protected boolean isLegacyConstruction() {
+ return _legacyConstruction;
+ }
+
/**
* Called by framework (in new-style instances where spec was used) after configuring etc,
* but before a reference to this instance is shared.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6cb55b50/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 0f1a184..729a2ff 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@ -40,7 +40,6 @@ import brooklyn.entity.Entity;
import brooklyn.entity.EntityType;
import brooklyn.entity.Group;
import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.proxying.InternalFactory;
import brooklyn.entity.rebind.BasicEntityRebindSupport;
import brooklyn.entity.rebind.RebindManagerImpl;
import brooklyn.entity.rebind.RebindSupport;
@@ -80,6 +79,7 @@ import brooklyn.util.collections.MutableMap;
import brooklyn.util.collections.SetFromLiveMap;
import brooklyn.util.config.ConfigBag;
import brooklyn.util.flags.FlagUtils;
+import brooklyn.util.flags.TypeCoercions;
import brooklyn.util.guava.Maybe;
import brooklyn.util.task.DeferredSupplier;
import brooklyn.util.text.Strings;
@@ -212,8 +212,6 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
protected transient SubscriptionTracker _subscriptionTracker;
- private final boolean _legacyConstruction;
-
public AbstractEntity() {
this(Maps.newLinkedHashMap(), null);
}
@@ -240,8 +238,25 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
*/
@Deprecated
public AbstractEntity(@SuppressWarnings("rawtypes") Map flags, Entity parent) {
+ super(checkConstructorFlags(flags, parent));
+
+ // TODO Don't let `this` reference escape during construction
+ entityType = new EntityDynamicType(this);
+
+ if (isLegacyConstruction()) {
+ AbstractBrooklynObject checkWeGetThis = configure(flags);
+ assert this.equals(checkWeGetThis) : this+" configure method does not return itself; returns "+checkWeGetThis+" instead of "+this;
+
+ boolean deferConstructionChecks = (flags.containsKey("deferConstructionChecks") && TypeCoercions.coerce(flags.get("deferConstructionChecks"), Boolean.class));
+ if (!deferConstructionChecks) {
+ FlagUtils.checkRequiredFields(this);
+ }
+ }
+ }
+
+ private static Map<?,?> checkConstructorFlags(Map flags, Entity parent) {
if (flags==null) {
- throw new IllegalArgumentException("Flags passed to entity "+this+" must not be null (try no-arguments or empty map)");
+ throw new IllegalArgumentException("Flags passed to entity must not be null (try no-arguments or empty map)");
}
if (flags.get("parent") != null && parent != null && flags.get("parent") != parent) {
throw new IllegalArgumentException("Multiple parents supplied, "+flags.get("parent")+" and "+parent);
@@ -256,77 +271,18 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
flags.put("parent", parent);
}
if (flags.get("owner") != null) {
- LOG.warn("Use of deprecated \"flags.owner\" instead of \"flags.parent\" for entity {}", this);
+ LOG.warn("Use of deprecated \"flags.owner\" instead of \"flags.parent\" for entity");
flags.put("parent", flags.get("owner"));
flags.remove("owner");
}
-
- // TODO Don't let `this` reference escape during construction
- entityType = new EntityDynamicType(this);
-
- _legacyConstruction = !InternalFactory.FactoryConstructionTracker.isConstructing();
-
- if (_legacyConstruction) {
- LOG.warn("Deprecated use of old-style entity construction for "+getClass().getName()+"; instead use EntityManager().createEntity(spec)");
- AbstractEntity checkWeGetThis = configure(flags);
- assert this.equals(checkWeGetThis) : this+" configure method does not return itself; returns "+checkWeGetThis+" instead";
- }
-
- inConstruction = false;
+ return flags;
}
- @Override
- public int hashCode() {
- return getId().hashCode();
- }
-
- @Override
- public boolean equals(Object o) {
- return (o == this || o == selfProxy) ||
- (o instanceof Entity && Objects.equal(getId(), ((Entity)o).getId()));
- }
-
- protected boolean isLegacyConstruction() {
- return _legacyConstruction;
- }
-
- protected boolean isRebinding() {
- return RebindManagerImpl.RebindTracker.isRebinding();
- }
-
- public void setProxy(Entity proxy) {
- if (selfProxy != null) throw new IllegalStateException("Proxy is already set; cannot reset proxy for "+toString());
- selfProxy = checkNotNull(proxy, "proxy");
- }
-
- public Entity getProxy() {
- return selfProxy;
- }
-
/**
- * Returns the proxy, or if not available (because using legacy code) then returns the real entity.
- * This method will be deleted in a future release; it will be kept while deprecated legacy code
- * still exists that creates entities without setting the proxy.
- */
- @Beta
- public Entity getProxyIfAvailable() {
- return getProxy()!=null ? getProxy() : this;
- }
-
- /** sets fields from flags; can be overridden if needed, subclasses should
- * set custom fields before _invoking_ this super
- * (and they nearly always should invoke the super)
- * <p>
- * note that it is usually preferred to use the SetFromFlag annotation on relevant fields
- * so they get set automatically by this method and overriding it is unnecessary
- *
- * @return this entity, for fluent style initialization
+ * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly
*/
- public AbstractEntity configure() {
- return configure(Maps.newLinkedHashMap());
- }
-
@Override
+ @Deprecated
public AbstractEntity configure(Map flags) {
if (!inConstruction && getManagementSupport().isDeployed()) {
LOG.warn("bulk/flag configuration being made to {} after deployment: may not be supported in future versions ({})",
@@ -387,6 +343,40 @@ public abstract class AbstractEntity extends AbstractBrooklynObject implements E
return this;
}
+
+ @Override
+ public int hashCode() {
+ return getId().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return (o == this || o == selfProxy) ||
+ (o instanceof Entity && Objects.equal(getId(), ((Entity)o).getId()));
+ }
+
+ protected boolean isRebinding() {
+ return RebindManagerImpl.RebindTracker.isRebinding();
+ }
+
+ public void setProxy(Entity proxy) {
+ if (selfProxy != null) throw new IllegalStateException("Proxy is already set; cannot reset proxy for "+toString());
+ selfProxy = checkNotNull(proxy, "proxy");
+ }
+
+ public Entity getProxy() {
+ return selfProxy;
+ }
+
+ /**
+ * Returns the proxy, or if not available (because using legacy code) then returns the real entity.
+ * This method will be deleted in a future release; it will be kept while deprecated legacy code
+ * still exists that creates entities without setting the proxy.
+ */
+ @Beta
+ public Entity getProxyIfAvailable() {
+ return getProxy()!=null ? getProxy() : this;
+ }
/**
* Sets a config key value, and returns this Entity instance for use in fluent-API style coding.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6cb55b50/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 8aea917..734b1c8 100644
--- a/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
@@ -36,7 +36,6 @@ import brooklyn.basic.AbstractBrooklynObject;
import brooklyn.config.ConfigKey;
import brooklyn.config.ConfigKey.HasConfigKey;
import brooklyn.entity.basic.EntityDynamicType;
-import brooklyn.entity.proxying.InternalFactory;
import brooklyn.entity.rebind.BasicLocationRebindSupport;
import brooklyn.entity.rebind.RebindManagerImpl;
import brooklyn.entity.rebind.RebindSupport;
@@ -83,7 +82,7 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
public static final ConfigKey<Location> PARENT_LOCATION = new BasicConfigKey<Location>(Location.class, "parentLocation");
- private final AtomicBoolean configured = new AtomicBoolean(false);
+ private final AtomicBoolean configured = new AtomicBoolean();
private Reference<Long> creationTimeUtc = new BasicReference<Long>(System.currentTimeMillis());
@@ -102,8 +101,6 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
private volatile boolean managed;
- private boolean _legacyConstruction;
-
private boolean inConstruction;
private final Map<Class<?>, Object> extensions = Maps.newConcurrentMap();
@@ -137,12 +134,8 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
* </ul>
*/
public AbstractLocation(Map properties) {
+ super(properties);
inConstruction = true;
- _legacyConstruction = !InternalFactory.FactoryConstructionTracker.isConstructing();
- if (!_legacyConstruction && properties!=null && !properties.isEmpty()) {
- LOG.warn("Forcing use of deprecated old-style location construction for "+getClass().getName()+" because properties were specified ("+properties+")");
- _legacyConstruction = true;
- }
// When one calls getConfig(key), we want to use the default value specified on *this* location
// if it overrides the default config. The easiest way to look up all our config keys is to
@@ -150,13 +143,10 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
// entities). See {@link #getConfig(ConfigKey)}
entityType = new EntityDynamicType((Class)getClass());
- if (_legacyConstruction) {
- LOG.warn("Deprecated use of old-style location construction for "+getClass().getName()+"; instead use LocationManager().createLocation(spec)");
- if (LOG.isDebugEnabled())
- LOG.debug("Source of use of old-style location construction", new Throwable("Source of use of old-style location construction"));
-
- configure(properties);
-
+ if (isLegacyConstruction()) {
+ AbstractBrooklynObject checkWeGetThis = configure(properties);
+ assert this.equals(checkWeGetThis) : this+" configure method does not return itself; returns "+checkWeGetThis+" instead of "+this;
+
boolean deferConstructionChecks = (properties.containsKey("deferConstructionChecks") && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class));
if (!deferConstructionChecks) {
FlagUtils.checkRequiredFields(this);
@@ -213,21 +203,11 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
/**
- * Will set fields from flags. The unused configuration can be found via the
- * {@linkplain ConfigBag#getUnusedConfig()}.
- * This can be overridden for custom initialization but note the following.
- * <p>
- * For new-style locations (i.e. not calling constructor directly, this will
- * be invoked automatically by brooklyn-core post-construction).
- * <p>
- * For legacy location use, this will be invoked by the constructor in this class.
- * Therefore if over-riding you must *not* rely on field initializers because they
- * may not run until *after* this method (this method is invoked by the constructor
- * 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) {
+ * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly
+ */
+ @Override
+ @Deprecated
+ public AbstractLocation configure(Map properties) {
assertNotYetManaged();
boolean firstTime = !configured.getAndSet(true);
@@ -269,6 +249,8 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
configBag.put(LocationConfigKeys.ISO_3166, codes);
}
+
+ return this;
}
// TODO ensure no callers rely on 'remove' semantics, and don't remove;
@@ -307,10 +289,6 @@ public abstract class AbstractLocation extends AbstractBrooklynObject implements
}
}
- protected boolean isLegacyConstruction() {
- return _legacyConstruction;
- }
-
@Override
public String getDisplayName() {
return name.get();
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6cb55b50/core/src/main/java/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java b/core/src/main/java/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
index d50aa7b..dbb52c5 100644
--- a/core/src/main/java/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
@@ -78,13 +78,13 @@ public class AggregatingMachineProvisioningLocation<T extends MachineLocation> e
}
@Override
- public void configure(Map properties) {
+ public AbstractLocation configure(Map properties) {
if (lock == null) {
lock = new Object();
provisioners = Lists.<MachineProvisioningLocation<T>>newArrayList();
inUse = Maps.<T, MachineProvisioningLocation<T>>newLinkedHashMap();
}
- super.configure(properties);
+ return super.configure(properties);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6cb55b50/core/src/main/java/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/FixedListMachineProvisioningLocation.java b/core/src/main/java/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
index 595ab8a..263e307 100644
--- a/core/src/main/java/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
@@ -121,11 +121,11 @@ implements MachineProvisioningLocation<T>, Closeable {
}
@Override
- public void configure(Map properties) {
+ public AbstractLocation configure(Map properties) {
if (machines == null) machines = Sets.newLinkedHashSet();
if (inUse == null) inUse = Sets.newLinkedHashSet();
if (pendingRemoval == null) pendingRemoval = Sets.newLinkedHashSet();
- super.configure(properties);
+ return super.configure(properties);
}
public FixedListMachineProvisioningLocation<T> newSubLocation(Map<?,?> newFlags) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6cb55b50/core/src/main/java/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java b/core/src/main/java/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
index 1562f9f..64a9345 100644
--- a/core/src/main/java/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
@@ -118,7 +118,7 @@ public class LocalhostMachineProvisioningLocation extends FixedListMachineProvis
return LocationSpec.create(LocalhostMachineProvisioningLocation.class);
}
- public void configure(Map flags) {
+ public LocalhostMachineProvisioningLocation configure(Map flags) {
super.configure(flags);
if (!truth(getDisplayName())) { setDisplayName("localhost"); }
@@ -142,6 +142,8 @@ public class LocalhostMachineProvisioningLocation extends FixedListMachineProvis
if (getConfig(BrooklynConfigKeys.ONBOX_BASE_DIR)==null && (getManagementContext()==null || getManagementContext().getConfig().getConfig(BrooklynConfigKeys.ONBOX_BASE_DIR)==null)) {
setConfig(BrooklynConfigKeys.ONBOX_BASE_DIR, "/tmp/brooklyn-"+Os.user());
}
+
+ return this;
}
public static InetAddress getLocalhostInetAddress() {
@@ -253,11 +255,13 @@ public class LocalhostMachineProvisioningLocation extends FixedListMachineProvis
public LocalhostMachine(Map properties) {
super(MutableMap.builder().putAll(properties).put("mutexSupport", mutexSupport).build());
}
+
public boolean obtainSpecificPort(int portNumber) {
if (!isSudoAllowed() && portNumber <= 1024)
return false;
return LocalhostMachineProvisioningLocation.obtainSpecificPort(getAddress(), portNumber);
}
+
public int obtainPort(PortRange range) {
int r = LocalhostMachineProvisioningLocation.obtainPort(getAddress(), range);
synchronized (portsObtained) {
@@ -266,6 +270,7 @@ public class LocalhostMachineProvisioningLocation extends FixedListMachineProvis
LOG.debug("localhost.obtainPort("+range+"), returning "+r);
return r;
}
+
@Override
public void releasePort(int portNumber) {
synchronized (portsObtained) {
@@ -280,10 +285,11 @@ public class LocalhostMachineProvisioningLocation extends FixedListMachineProvis
}
@Override
- public void configure(Map properties) {
+ public LocalhostMachine configure(Map properties) {
if (address==null || !properties.containsKey("address"))
address = Networking.getLocalHost();
super.configure(properties);
+ return this;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6cb55b50/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java b/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java
index 47376d5..a88218e 100644
--- a/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java
@@ -309,7 +309,7 @@ public class SshMachineLocation extends AbstractLocation implements MachineLocat
}
@Override
- public void configure(Map properties) {
+ public SshMachineLocation configure(Map properties) {
super.configure(properties);
// TODO Note that check for addresss!=null is done automatically in super-constructor, in FlagUtils.checkRequiredFields
@@ -325,6 +325,7 @@ public class SshMachineLocation extends AbstractLocation implements MachineLocat
setDisplayName((truth(user) ? user+"@" : "") + address.getHostName());
}
}
+ return this;
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6cb55b50/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 a1e2449..a8cf150 100644
--- a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
@@ -39,14 +39,12 @@ import brooklyn.entity.Entity;
import brooklyn.entity.Group;
import brooklyn.entity.basic.EntityInternal;
import brooklyn.entity.basic.EntityLocal;
-import brooklyn.entity.proxying.InternalFactory;
import brooklyn.entity.rebind.RebindManagerImpl;
import brooklyn.entity.trait.Configurable;
import brooklyn.event.AttributeSensor;
import brooklyn.event.Sensor;
import brooklyn.event.SensorEventListener;
import brooklyn.management.ExecutionContext;
-import brooklyn.management.ManagementContext;
import brooklyn.management.SubscriptionContext;
import brooklyn.management.SubscriptionHandle;
import brooklyn.management.internal.SubscriptionTracker;
@@ -68,14 +66,9 @@ import com.google.common.collect.Maps;
public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject implements BrooklynObjectInternal, EntityAdjunct, Configurable {
private static final Logger log = LoggerFactory.getLogger(AbstractEntityAdjunct.class);
- protected Map<String,Object> leftoverProperties = Maps.newLinkedHashMap();
-
- private boolean _legacyConstruction;
private boolean _legacyNoConstructionInit;
-
- // TODO not sure if we need this -- never read
- @SuppressWarnings("unused")
- private boolean inConstruction;
+
+ protected Map<String,Object> leftoverProperties = Maps.newLinkedHashMap();
protected transient ExecutionContext execution;
@@ -101,43 +94,28 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
this(Collections.emptyMap());
}
- public AbstractEntityAdjunct(@SuppressWarnings("rawtypes") Map flags) {
- inConstruction = true;
- _legacyConstruction = !InternalFactory.FactoryConstructionTracker.isConstructing();
- _legacyNoConstructionInit = (flags != null) && Boolean.TRUE.equals(flags.get("noConstructionInit"));
-
- if (!_legacyConstruction && flags!=null && !flags.isEmpty()) {
- log.debug("Using direct construction for "+getClass().getName()+" because properties were specified ("+flags+")");
- _legacyConstruction = true;
- }
+ public AbstractEntityAdjunct(@SuppressWarnings("rawtypes") Map properties) {
+ super(properties);
+ _legacyNoConstructionInit = (properties != null) && Boolean.TRUE.equals(properties.get("noConstructionInit"));
- if (_legacyConstruction) {
- log.debug("Using direct construction for "+getClass().getName()+"; calling configure(Map) immediately");
-
- configure(flags);
-
- boolean deferConstructionChecks = (flags.containsKey("deferConstructionChecks") && TypeCoercions.coerce(flags.get("deferConstructionChecks"), Boolean.class));
+ if (isLegacyConstruction()) {
+ AbstractBrooklynObject checkWeGetThis = configure(properties);
+ assert this.equals(checkWeGetThis) : this+" configure method does not return itself; returns "+checkWeGetThis+" instead of "+this;
+
+ boolean deferConstructionChecks = (properties.containsKey("deferConstructionChecks") && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class));
if (!deferConstructionChecks) {
FlagUtils.checkRequiredFields(this);
}
}
-
- inConstruction = false;
}
- /** will set fields from flags, and put the remaining ones into the 'leftovers' map.
- * can be subclassed for custom initialization but note the following.
- * <p>
- * if you require fields to be initialized you must do that in this method. You must
- * *not* rely on field initializers because they may not run until *after* this method
- * (this method is invoked by the constructor in this class, so initializers
- * in subclasses will not have run when this overridden method is invoked.) */
- protected void configure() {
- configure(Collections.emptyMap());
- }
-
+ /**
+ * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly
+ */
+ @Override
+ @Deprecated
@SuppressWarnings({ "unchecked", "rawtypes" })
- public void configure(Map flags) {
+ public AbstractEntityAdjunct configure(Map flags) {
// TODO only set on first time through
boolean isFirstTime = true;
@@ -172,12 +150,9 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
Preconditions.checkArgument(flags.get("displayName") instanceof CharSequence, "'displayName' property should be a string");
setDisplayName(flags.remove("displayName").toString());
}
+ return this;
}
- protected boolean isLegacyConstruction() {
- return _legacyConstruction;
- }
-
/**
* Used for legacy-style policies/enrichers on rebind, to indicate that init() should not be called.
* Will likely be deleted in a future release; should not be called apart from by framework code.
@@ -186,26 +161,7 @@ public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject imple
protected boolean isLegacyNoConstructionInit() {
return _legacyNoConstructionInit;
}
-
- /**
- * Called by framework (in new-style policies where PolicySpec was used) after configuring etc,
- * but before a reference to this policy is shared.
- *
- * To preserve backwards compatibility for if the policy is constructed directly, one
- * can call the code below, but that means it will be called after references to this
- * policy have been shared with other entities.
- * <pre>
- * {@code
- * if (isLegacyConstruction()) {
- * init();
- * }
- * }
- * </pre>
- */
- public void init() {
- // no-op
- }
-
+
protected boolean isRebinding() {
return RebindManagerImpl.RebindTracker.isRebinding();
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6cb55b50/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
index 0290dc5..380e351 100644
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
+++ b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
@@ -93,6 +93,7 @@ import brooklyn.location.MachineManagementMixins.MachineMetadata;
import brooklyn.location.MachineManagementMixins.RichMachineProvisioningLocation;
import brooklyn.location.NoMachinesAvailableException;
import brooklyn.location.access.PortForwardManager;
+import brooklyn.location.basic.AbstractLocation;
import brooklyn.location.basic.BasicMachineMetadata;
import brooklyn.location.basic.LocationConfigKeys;
import brooklyn.location.basic.LocationConfigUtils;
@@ -206,7 +207,7 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
}
@Override
- public void configure(Map properties) {
+ public JcloudsLocation configure(Map properties) {
super.configure(properties);
if (getLocalConfigBag().containsKey("providerLocationId")) {
@@ -231,6 +232,7 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
}
setConfig(MACHINE_CREATION_SEMAPHORE, new Semaphore(maxConcurrent, true));
}
+ return this;
}
@Override
[9/9] git commit: This closes #110
Posted by he...@apache.org.
This closes #110
Merge remote-tracking branch 'apache-gh/pr/110'
Conflicts:
api/src/main/java/brooklyn/basic/BrooklynObject.java
core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java
core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
core/src/main/java/brooklyn/location/basic/AbstractLocation.java
core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
Conflicts mainly new tags methods from #109, resolved and confirmed tests pass.
Also added LocationType and related classes.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/d4a6328e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/d4a6328e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/d4a6328e
Branch: refs/heads/master
Commit: d4a6328ebf2fdab2306d84261bfd412ec1dc04e7
Parents: 4891355 79b49a9
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Aug 7 17:54:08 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Aug 7 17:55:14 2014 -0400
----------------------------------------------------------------------
.../java/brooklyn/basic/BrooklynObject.java | 30 +-
.../main/java/brooklyn/basic/BrooklynType.java | 54 ++++
api/src/main/java/brooklyn/entity/Entity.java | 29 +-
.../main/java/brooklyn/entity/EntityType.java | 24 +-
.../brooklyn/entity/rebind/ChangeListener.java | 44 +--
.../java/brooklyn/location/LocationType.java | 32 +++
.../java/brooklyn/mementos/EntityMemento.java | 3 -
.../main/java/brooklyn/mementos/Memento.java | 3 +
.../main/java/brooklyn/policy/EnricherType.java | 24 +-
.../java/brooklyn/policy/EntityAdjunct.java | 11 -
.../main/java/brooklyn/policy/PolicyType.java | 22 +-
.../brooklyn/basic/AbstractBrooklynObject.java | 198 ++++++++++---
.../brooklyn/basic/BrooklynDynamicType.java | 283 +++++++++++++++++++
.../brooklyn/basic/BrooklynTypeSnapshot.java | 100 +++++++
.../main/java/brooklyn/basic/BrooklynTypes.java | 119 ++++++++
.../enricher/basic/AbstractEnricher.java | 15 +-
.../enricher/basic/EnricherDynamicType.java | 39 +++
.../enricher/basic/EnricherTypeSnapshot.java | 39 +++
.../brooklyn/entity/basic/AbstractEntity.java | 169 +++++------
.../entity/basic/EntityDynamicType.java | 252 ++---------------
.../entity/basic/EntityInitializers.java | 2 +-
.../entity/basic/EntityTypeSnapshot.java | 58 +---
.../java/brooklyn/entity/basic/EntityTypes.java | 86 +-----
.../proxying/BasicEntityTypeRegistry.java | 2 -
.../entity/proxying/InternalEntityFactory.java | 2 +-
.../proxying/InternalLocationFactory.java | 11 +-
.../entity/proxying/InternalPolicyFactory.java | 19 +-
.../AbstractBrooklynObjectRebindSupport.java | 88 ++++++
.../rebind/BasicEnricherRebindSupport.java | 43 +--
.../entity/rebind/BasicEntityRebindSupport.java | 64 ++---
.../rebind/BasicLocationRebindSupport.java | 40 +--
.../entity/rebind/BasicPolicyRebindSupport.java | 41 +--
.../rebind/ImmediateDeltaChangeListener.java | 179 +++++-------
.../rebind/PeriodicDeltaChangeListener.java | 153 ++++------
.../entity/rebind/RebindManagerImpl.java | 104 +------
.../entity/rebind/dto/AbstractMemento.java | 11 +-
.../entity/rebind/dto/BasicEntityMemento.java | 13 +-
.../entity/rebind/dto/MementosGenerators.java | 87 +++---
.../location/basic/AbstractLocation.java | 137 +++------
.../AggregatingMachineProvisioningLocation.java | 4 +-
.../FixedListMachineProvisioningLocation.java | 4 +-
.../LocalhostMachineProvisioningLocation.java | 10 +-
.../location/basic/LocationDynamicType.java | 39 +++
.../location/basic/LocationTypeSnapshot.java | 40 +++
.../location/basic/SshMachineLocation.java | 3 +-
.../policy/basic/AbstractEntityAdjunct.java | 111 ++------
.../brooklyn/policy/basic/AbstractPolicy.java | 12 +-
.../brooklyn/policy/basic/EnricherTypeImpl.java | 75 -----
.../policy/basic/PolicyDynamicType.java | 39 +++
.../brooklyn/policy/basic/PolicyTypeImpl.java | 75 -----
.../policy/basic/PolicyTypeSnapshot.java | 39 +++
.../enricher/basic/BasicEnricherTest.java | 2 +-
.../brooklyn/entity/basic/EntitiesTest.java | 22 +-
.../entity/rebind/RebindEnricherTest.java | 16 +-
.../entity/rebind/RebindEntityTest.java | 14 +-
.../entity/rebind/RebindLocationTest.java | 17 +-
.../entity/rebind/RebindPolicyTest.java | 27 +-
.../location/basic/AbstractLocationTest.java | 3 +-
.../brooklyn/policy/basic/BasicPolicyTest.java | 2 +-
.../location/jclouds/JcloudsLocation.java | 4 +-
.../brooklyn/rest/resources/EntityResource.java | 14 +-
.../rest/transform/CatalogTransformer.java | 4 +-
.../rest/util/BrooklynRestResourceUtils.java | 4 +-
.../rest/resources/EntityResourceTest.java | 11 +-
64 files changed, 1687 insertions(+), 1534 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/api/src/main/java/brooklyn/basic/BrooklynObject.java
----------------------------------------------------------------------
diff --cc api/src/main/java/brooklyn/basic/BrooklynObject.java
index dd26528,44cd489..88b50c2
--- a/api/src/main/java/brooklyn/basic/BrooklynObject.java
+++ b/api/src/main/java/brooklyn/basic/BrooklynObject.java
@@@ -34,12 -35,25 +36,28 @@@ public interface BrooklynObject extend
*/
String getDisplayName();
- /**
- * A set of tags associated to this adjunct.
+ /**
+ * Tags are arbitrary objects which can be attached to an entity for subsequent reference.
+ * They must not be null (as {@link ImmutableMap} may be used under the covers; also there is little point!);
+ * and they should be amenable to our persistence (on-disk serialization) and our JSON serialization in the REST API.
*/
- @Nonnull Set<Object> getTags();
-
- /** whether the given object is contained as a tag */
- boolean containsTag(Object tag);
+ TagSupport getTagSupport();
+ public static interface TagSupport {
+ /**
+ * @return An immutable copy of the set of tags on this entity.
+ * Note {@link #containsTag(Object)} will be more efficient,
+ * and {@link #addTag(Object)} and {@link #removeTag(Object)} will not work on the returned set.
+ */
- Set<Object> getTags();
++ @Nonnull Set<Object> getTags();
+
+ boolean containsTag(@Nonnull Object tag);
+
+ boolean addTag(@Nonnull Object tag);
+
++ boolean addTags(@Nonnull Iterable<?> tags);
++
+ boolean removeTag(@Nonnull Object tag);
+ }
++
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/api/src/main/java/brooklyn/entity/Entity.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/api/src/main/java/brooklyn/location/LocationType.java
----------------------------------------------------------------------
diff --cc api/src/main/java/brooklyn/location/LocationType.java
index 0000000,0000000..7bdb179
new file mode 100644
--- /dev/null
+++ b/api/src/main/java/brooklyn/location/LocationType.java
@@@ -1,0 -1,0 +1,32 @@@
++/*
++ * 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.location;
++
++import brooklyn.basic.BrooklynType;
++
++import com.google.common.annotations.Beta;
++
++/**
++ * Gives type information for a {@link Location}. It is immutable.
++
++ * @since 0.7.0
++ */
++@Beta
++public interface LocationType extends BrooklynType {
++}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/api/src/main/java/brooklyn/policy/EntityAdjunct.java
----------------------------------------------------------------------
diff --cc api/src/main/java/brooklyn/policy/EntityAdjunct.java
index 97acc08,fa05a2a..ed42605
--- a/api/src/main/java/brooklyn/policy/EntityAdjunct.java
+++ b/api/src/main/java/brooklyn/policy/EntityAdjunct.java
@@@ -18,11 -18,6 +18,8 @@@
*/
package brooklyn.policy;
- import java.util.Set;
-
- import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
import brooklyn.basic.BrooklynObject;
/**
@@@ -48,25 -43,7 +45,17 @@@ public interface EntityAdjunct extends
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/d4a6328e/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
index e977fec,b15e73d..d06eb2f
--- a/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
+++ b/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
@@@ -24,7 -34,7 +34,8 @@@ 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.Maps;
import com.google.common.collect.Sets;
public abstract class AbstractBrooklynObject implements BrooklynObjectInternal {
@@@ -32,55 -46,150 +47,166 @@@
@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();
+ private final Set<Object> tags = Sets.newLinkedHashSet();
+
+ private volatile ManagementContext managementContext;
+
+ public abstract void setDisplayName(String newName);
+
+ public AbstractBrooklynObject() {
+ this(Maps.newLinkedHashMap());
+ }
+
+ public AbstractBrooklynObject(Map<?,?> properties) {
+ _legacyConstruction = !InternalFactory.FactoryConstructionTracker.isConstructing();
+
+ if (!_legacyConstruction && properties!=null && !properties.isEmpty()) {
+ log.warn("Forcing use of deprecated old-style location construction for "+getClass().getName()+" because properties were specified ("+properties+"); instead use specs (e.g. LocationSpec, EntitySpec, etc)");
+ if (log.isDebugEnabled())
+ log.debug("Source of use of old-style construction", new Throwable("Source of use of old-style construction"));
+ _legacyConstruction = true;
+ }
+
+ // rely on sub-class to call configure(properties), because otherwise its fields will not have been initialised
+ }
+
+ /**
+ * See {@link #configure(Map)}
+ *
+ * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly
+ */
+ @Deprecated
+ protected AbstractBrooklynObject configure() {
+ return configure(Collections.emptyMap());
+ }
+
+ /**
+ * Will set fields from flags, and put the remaining ones into the 'leftovers' map.
+ * For some types, you can find unused config via {@link ConfigBag#getUnusedConfig()}.
+ * <p>
+ * To be overridden by AbstractEntity, AbstractLoation, AbstractPolicy, AbstractEnricher, etc.
+ * <p>
+ * But should not be overridden by specific entity types. If you do, the entity may break in
+ * subsequent releases. Also note that if you require fields to be initialized you must do that
+ * in this method. You must *not* rely on field initializers because they may not run until *after*
+ * this method (this method is invoked by the constructor in this class, so initializers
+ * in subclasses will not have run when this overridden method is invoked.)
+ *
+ * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly
+ */
+ @Deprecated
- protected AbstractBrooklynObject configure(Map flags) {
- return this;
- }
++ protected abstract AbstractBrooklynObject configure(Map<?,?> flags);
+
+ protected boolean isLegacyConstruction() {
+ return _legacyConstruction;
+ }
+
+ /**
+ * Called by framework (in new-style instances where spec was used) after configuring etc,
+ * but before a reference to this instance is shared.
+ *
+ * To preserve backwards compatibility for if the instance is constructed directly, one
+ * can call the code below, but that means it will be called after references to this
+ * policy have been shared with other entities.
+ * <pre>
+ * {@code
+ * if (isLegacyConstruction()) {
+ * init();
+ * }
+ * }
+ * </pre>
+ */
+ public void init() {
+ // no-op
+ }
+
+ /**
+ * Called by framework on rebind (in new-style instances),
+ * after configuring but before the instance is managed (or is attached to an entity, depending on its type),
+ * and before a reference to this policy is shared.
+ * Note that {@link #init()} will not be called on rebind.
+ */
+ public void rebind() {
+ // no-op
+ }
+
+ public void setManagementContext(ManagementContextInternal managementContext) {
+ this.managementContext = managementContext;
+ }
+
+ public ManagementContext getManagementContext() {
+ return managementContext;
+ }
+
+ protected boolean isRebinding() {
+ return RebindManagerImpl.RebindTracker.isRebinding();
+ }
+
+ protected void requestPersist() {
- // TODO Could add PolicyChangeListener, similar to EntityChangeListener; should we do that?
+ if (getManagementContext() != null) {
+ getManagementContext().getRebindManager().getChangeListener().onChanged(this);
+ }
+ }
@Override
public String getId() {
return id;
}
- @Override
- public Set<Object> getTags() {
- synchronized (tags) {
- return ImmutableSet.copyOf(tags);
- }
++ protected void onTagsChanged() {
++ requestPersist();
++ }
++
+ public TagSupport getTagSupport() {
- return new TagSupport() {
- @Override
- public Set<Object> getTags() {
- synchronized (tags) {
- return ImmutableSet.copyOf(tags);
- }
++ return new BasicTagSupport();
+ }
+
- public boolean addTag(Object tag) {
- boolean result;
- synchronized (tags) {
- result = tags.add(tag);
++ protected class BasicTagSupport implements TagSupport {
++ @Override
++ public Set<Object> getTags() {
++ synchronized (tags) {
++ return ImmutableSet.copyOf(tags);
+ }
-
- @Override
- public boolean containsTag(Object tag) {
- synchronized (tags) {
- return tags.contains(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);
++ @Override
++ public boolean containsTag(Object tag) {
++ synchronized (tags) {
++ return tags.contains(tag);
+ }
-
- @Override
- public boolean addTag(Object tag) {
- boolean result;
- synchronized (tags) {
- result = tags.add(tag);
- }
- requestPersist();
- return result;
- }
-
- @Override
- public boolean removeTag(Object tag) {
- boolean result;
- synchronized (tags) {
- result = tags.remove(tag);
- }
- requestPersist();
- return result;
- }
- };
+ }
- }
++
++ @Override
++ public boolean addTag(Object tag) {
++ boolean result;
++ synchronized (tags) {
++ result = tags.add(tag);
++ }
++ onTagsChanged();
++ return result;
++ }
+
- protected abstract void onTagsChanged();
++ @Override
++ public boolean addTags(Iterable<?> newTags) {
++ boolean result;
++ synchronized (tags) {
++ result = Iterables.addAll(tags, newTags);
++ }
++ onTagsChanged();
++ return result;
++ }
++
++ @Override
++ public boolean removeTag(Object tag) {
++ boolean result;
++ synchronized (tags) {
++ result = tags.remove(tag);
++ }
++ onTagsChanged();
++ return result;
++ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
index 0000000,0ae7400..011c499
mode 000000,100644..100644
--- a/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
+++ b/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
@@@ -1,0 -1,283 +1,283 @@@
+ /*
+ * 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.basic;
+
+ import static com.google.common.base.Preconditions.checkNotNull;
+
+ import java.lang.reflect.Field;
+ import java.lang.reflect.Modifier;
+ import java.util.ArrayList;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.LinkedHashMap;
+ import java.util.LinkedHashSet;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.atomic.AtomicBoolean;
+
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+
+ import brooklyn.config.ConfigKey;
+ import brooklyn.config.ConfigKey.HasConfigKey;
+ import brooklyn.event.basic.BasicConfigKey.BasicConfigKeyOverwriting;
+ import brooklyn.util.flags.FlagUtils;
+ import brooklyn.util.javalang.Reflections;
+ import brooklyn.util.text.Strings;
+
+ import com.google.common.base.Joiner;
+ import com.google.common.base.Objects;
+ import com.google.common.collect.ArrayListMultimap;
+ import com.google.common.collect.ListMultimap;
+ import com.google.common.collect.Lists;
+
+ /**
+ * This is the actual type of a brooklyn object instance at runtime,
+ * which can change from the static {@link BrooklynType}, and can change over time;
+ * for this reason it does *not* implement BrooklynType, but
+ * callers can call {@link #getSnapshot()} to get a snapshot such instance.
+ */
+ public abstract class BrooklynDynamicType<T extends BrooklynObject, AbstractT extends AbstractBrooklynObject> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BrooklynDynamicType.class);
+
+ protected final Class<? extends T> brooklynClass;
+ protected final AbstractT instance;
+ protected volatile String name;
+
+ /**
+ * Map of config keys (and their fields) on this instance, by name.
+ */
+ protected final Map<String,FieldAndValue<ConfigKey<?>>> configKeys = new ConcurrentHashMap<String, FieldAndValue<ConfigKey<?>>>();
+
+ private volatile BrooklynTypeSnapshot snapshot;
+ private final AtomicBoolean snapshotValid = new AtomicBoolean(false);
+
++ @SuppressWarnings("unchecked")
+ public BrooklynDynamicType(AbstractT instance) {
+ this((Class<? extends T>) instance.getClass(), instance);
+ }
+ public BrooklynDynamicType(Class<? extends T> clazz) {
+ this(clazz, null);
+ }
+ protected BrooklynDynamicType(Class<? extends T> clazz, AbstractT instance) {
+ this.brooklynClass = checkNotNull(clazz, "brooklyn class");
+ this.instance = instance;
+ // NB: official name is usually injected later, e.g. from AbstractEntity.setManagementContext
+ this.name = (clazz.getCanonicalName() == null) ? clazz.getName() : clazz.getCanonicalName();
+
+ buildConfigKeys(clazz, null, configKeys);
+ if (LOG.isTraceEnabled())
+ LOG.trace("Entity {} config keys: {}", (instance==null ? clazz.getName() : instance.getId()), Joiner.on(", ").join(configKeys.keySet()));
+ }
+
+ protected abstract BrooklynTypeSnapshot newSnapshot();
+
+ protected void invalidateSnapshot() {
+ snapshotValid.set(false);
+ }
+
+ public void setName(String name) {
+ if (Strings.isBlank(name)) {
+ throw new IllegalArgumentException("Invalid name "+(name == null ? "null" : "'"+name+"'")+"; name must be non-empty and not just white space");
+ }
+ this.name = name;
+ invalidateSnapshot();
+ }
+
+ public synchronized BrooklynType getSnapshot() {
+ return refreshSnapshot();
+ }
+
+ public Class<? extends T> getBrooklynClass() {
+ return brooklynClass;
+ }
+
+ // --------------------------------------------------
+
+ /**
+ * ConfigKeys available on this entity.
+ */
+ public Map<String,ConfigKey<?>> getConfigKeys() {
+ return Collections.unmodifiableMap(value(configKeys));
+ }
+
+ /**
+ * ConfigKeys available on this entity.
+ */
+ public ConfigKey<?> getConfigKey(String keyName) {
+ return value(configKeys.get(keyName));
+ }
+
+ /** field where a config key is defined, for use getting annotations. note annotations are not inherited. */
+ public Field getConfigKeyField(String keyName) {
+ return field(configKeys.get(keyName));
+ }
+
+ protected BrooklynTypeSnapshot refreshSnapshot() {
+ if (snapshotValid.compareAndSet(false, true)) {
+ snapshot = newSnapshot();
+ }
+ return snapshot;
+ }
+
+ /**
+ * Finds the config keys defined on the entity's class, statics and optionally any non-static (discouraged).
+ * Prefers keys which overwrite other keys, and prefers keys which are lower in the hierarchy;
+ * logs warnings if there are two conflicting keys which don't have an overwriting relationship.
+ */
+ protected static void buildConfigKeys(Class<? extends BrooklynObject> clazz, AbstractBrooklynObject optionalInstance,
+ Map<String, FieldAndValue<ConfigKey<?>>> configKeys) {
+ ListMultimap<String,FieldAndValue<ConfigKey<?>>> configKeysAll =
+ ArrayListMultimap.<String, FieldAndValue<ConfigKey<?>>>create();
+
+ for (Field f : FlagUtils.getAllFields(clazz)) {
+ boolean isConfigKey = ConfigKey.class.isAssignableFrom(f.getType());
+ if (!isConfigKey) {
+ if (!HasConfigKey.class.isAssignableFrom(f.getType())) {
+ // neither ConfigKey nor HasConfigKey
+ continue;
+ }
+ }
+ if (!Modifier.isStatic(f.getModifiers())) {
+ // require it to be static or we have an instance
+ LOG.warn("Discouraged use of non-static config key "+f+" defined in " + (optionalInstance!=null ? optionalInstance : clazz));
+ if (optionalInstance==null) continue;
+ }
+ try {
+ ConfigKey<?> k = isConfigKey ? (ConfigKey<?>) f.get(optionalInstance) :
+ ((HasConfigKey<?>)f.get(optionalInstance)).getConfigKey();
+
+ if (k==null) {
+ LOG.warn("no value defined for config key field (skipping): "+f);
+ } else {
+ configKeysAll.put(k.getName(), new FieldAndValue<ConfigKey<?>>(f, k));
+ }
+
+ } catch (IllegalAccessException e) {
+ LOG.warn("cannot access config key (skipping): "+f);
+ }
+ }
+ LinkedHashSet<String> keys = new LinkedHashSet<String>(configKeysAll.keys());
+ for (String kn: keys) {
+ List<FieldAndValue<ConfigKey<?>>> kk = Lists.newArrayList(configKeysAll.get(kn));
+ if (kk.size()>1) {
+ // remove anything which extends another value in the list
+ for (FieldAndValue<ConfigKey<?>> k: kk) {
+ ConfigKey<?> key = value(k);
+ if (key instanceof BasicConfigKeyOverwriting) {
+ ConfigKey<?> parent = ((BasicConfigKeyOverwriting<?>)key).getParentKey();
+ // find and remove the parent from consideration
+ for (FieldAndValue<ConfigKey<?>> k2: kk) {
+ if (value(k2) == parent)
+ configKeysAll.remove(kn, k2);
+ }
+ }
+ }
+ kk = Lists.newArrayList(configKeysAll.get(kn));
+ }
+ // multiple keys, not overwriting; if their values are the same then we don't mind
+ FieldAndValue<ConfigKey<?>> best = null;
+ for (FieldAndValue<ConfigKey<?>> k: kk) {
+ if (best==null) {
+ best=k;
+ } else {
+ Field lower = Reflections.inferSubbestField(k.field, best.field);
+ ConfigKey<? extends Object> lowerV = lower==null ? null : lower.equals(k.field) ? k.value : best.value;
+ if (best.value == k.value) {
+ // same value doesn't matter which we take (but take lower if there is one)
+ if (LOG.isTraceEnabled())
+ LOG.trace("multiple definitions for config key {} on {}; same value {}; " +
+ "from {} and {}, preferring {}",
+ new Object[] {
+ best.value.getName(), optionalInstance!=null ? optionalInstance : clazz,
+ best.value.getDefaultValue(),
+ k.field, best.field, lower});
+ best = new FieldAndValue<ConfigKey<?>>(lower!=null ? lower : best.field, best.value);
+ } else if (lower!=null) {
+ // different value, but one clearly lower (in type hierarchy)
+ if (LOG.isTraceEnabled())
+ LOG.trace("multiple definitions for config key {} on {}; " +
+ "from {} and {}, preferring lower {}, value {}",
+ new Object[] {
+ best.value.getName(), optionalInstance!=null ? optionalInstance : clazz,
+ k.field, best.field, lower,
+ lowerV.getDefaultValue() });
+ best = new FieldAndValue<ConfigKey<?>>(lower, lowerV);
+ } else {
+ // different value, neither one lower than another in hierarchy
+ LOG.warn("multiple ambiguous definitions for config key {} on {}; " +
+ "from {} and {}, values {} and {}; " +
+ "keeping latter (arbitrarily)",
+ new Object[] {
+ best.value.getName(), optionalInstance!=null ? optionalInstance : clazz,
+ k.field, best.field,
+ k.value.getDefaultValue(), best.value.getDefaultValue() });
+ // (no change)
+ }
+ }
+ }
+ if (best==null) {
+ // shouldn't happen
+ LOG.error("Error - no matching config key from "+kk+" in class "+clazz+", even though had config key name "+kn);
+ continue;
+ } else {
+ configKeys.put(best.value.getName(), best);
+ }
+ }
+ }
+
+ protected static class FieldAndValue<V> {
+ public final Field field;
+ public final V value;
+ public FieldAndValue(Field field, V value) {
+ this.field = field;
+ this.value = value;
+ }
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this).add("field", field).add("value", value).toString();
+ }
+ }
+
+ protected static <V> V value(FieldAndValue<V> fv) {
+ if (fv==null) return null;
+ return fv.value;
+ }
+
+ protected static Field field(FieldAndValue<?> fv) {
+ if (fv==null) return null;
+ return fv.field;
+ }
+
- @SuppressWarnings("unused")
+ protected static <V> Collection<V> value(Collection<FieldAndValue<V>> fvs) {
+ List<V> result = new ArrayList<V>();
+ for (FieldAndValue<V> fv: fvs) result.add(value(fv));
+ return result;
+ }
+
+ protected static <K,V> Map<K,V> value(Map<K,FieldAndValue<V>> fvs) {
+ Map<K,V> result = new LinkedHashMap<K,V>();
+ for (K key: fvs.keySet())
+ result.put(key, value(fvs.get(key)));
+ return result;
+ }
+
+ }
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
index df6a370,8503663..9cba5b9
--- a/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
+++ b/core/src/main/java/brooklyn/enricher/basic/AbstractEnricher.java
@@@ -62,10 -62,6 +62,7 @@@ public abstract class AbstractEnricher
@Override
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);
- }
+ requestPersist();
}
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
index 68846aa,ad2043c..97d7b4e
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@@ -1349,9 -1285,24 +1308,29 @@@ public abstract class AbstractEntity ex
}
@Override
+ protected void onTagsChanged() {
++ super.onTagsChanged();
+ getManagementSupport().getEntityChangeListener().onTagsChanged();
+ }
++
+ public Set<Object> getTags() {
+ return getTagSupport().getTags();
+ }
+
+ @Override
+ public boolean addTag(Object tag) {
+ return getTagSupport().addTag(tag);
+ }
+
+ @Override
+ public boolean removeTag(Object tag) {
+ return getTagSupport().removeTag(tag);
+ }
+
+ @Override
+ public boolean containsTag(Object tag) {
+ return getTagSupport().containsTag(tag);
+ }
@Override
protected void finalize() throws Throwable {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
index 9cc05c3,b5d7c0a..78fa574
--- a/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
+++ b/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
@@@ -231,7 -230,6 +231,7 @@@ public class InternalEntityFactory exte
if (spec.getDisplayName()!=null)
((AbstractEntity)entity).setDisplayName(spec.getDisplayName());
- ((AbstractEntity)entity).addTags(spec.getTags());
++ entity.getTagSupport().addTags(spec.getTags());
((AbstractEntity)entity).configure(MutableMap.copyOf(spec.getFlags()));
for (Map.Entry<ConfigKey<?>, Object> entry : spec.getConfig().entrySet()) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
index 6a7b599,b989392..934acce
--- a/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
+++ b/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
@@@ -95,11 -102,9 +102,11 @@@ public class InternalLocationFactory ex
managementContext.prePreManage(loc);
if (spec.getDisplayName()!=null)
- ((AbstractLocation)loc).setName(spec.getDisplayName());
+ ((AbstractLocation)loc).setDisplayName(spec.getDisplayName());
+
- ((AbstractLocation)loc).addTags(spec.getTags());
++ loc.getTagSupport().addTags(spec.getTags());
- if (isNewStyleLocation(clazz)) {
+ if (isNewStyle(clazz)) {
((AbstractLocation)loc).setManagementContext(managementContext);
((AbstractLocation)loc).configure(ConfigBag.newInstance().putAll(spec.getFlags()).putAll(spec.getConfig()).getAllConfig());
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java
index 76dd312,d52d368..9a84c3b
--- a/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java
+++ b/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java
@@@ -94,9 -105,7 +105,9 @@@ public class InternalPolicyFactory exte
if (spec.getDisplayName()!=null)
((AbstractPolicy)pol).setDisplayName(spec.getDisplayName());
- ((AbstractPolicy)pol).addTags(spec.getTags());
++ pol.getTagSupport().addTags(spec.getTags());
+
- if (isNewStylePolicy(clazz)) {
+ if (isNewStyle(clazz)) {
((AbstractPolicy)pol).setManagementContext(managementContext);
Map<String, Object> config = ConfigBag.newInstance().putAll(spec.getFlags()).putAll(spec.getConfig()).getAllConfig();
((AbstractPolicy)pol).configure(MutableMap.copyOf(config)); // TODO AbstractPolicy.configure modifies the map
@@@ -131,9 -140,7 +142,9 @@@
if (spec.getDisplayName()!=null)
((AbstractEnricher)enricher).setDisplayName(spec.getDisplayName());
- ((AbstractEnricher)enricher).addTags(spec.getTags());
++ enricher.getTagSupport().addTags(spec.getTags());
+
- if (isNewStyleEnricher(clazz)) {
+ if (isNewStyle(clazz)) {
((AbstractEnricher)enricher).setManagementContext(managementContext);
Map<String, Object> config = ConfigBag.newInstance().putAll(spec.getFlags()).putAll(spec.getConfig()).getAllConfig();
((AbstractEnricher)enricher).configure(MutableMap.copyOf(config)); // TODO AbstractEnricher.configure modifies the map
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/location/basic/AbstractLocation.java
index 84259ff,c4b4ee0..4d76849
--- a/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
+++ b/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
@@@ -35,10 -35,8 +35,7 @@@ import org.slf4j.LoggerFactory
import brooklyn.basic.AbstractBrooklynObject;
import brooklyn.config.ConfigKey;
import brooklyn.config.ConfigKey.HasConfigKey;
--import brooklyn.entity.basic.EntityDynamicType;
- import brooklyn.entity.proxying.InternalFactory;
import brooklyn.entity.rebind.BasicLocationRebindSupport;
- import brooklyn.entity.rebind.RebindManagerImpl;
import brooklyn.entity.rebind.RebindSupport;
import brooklyn.entity.trait.Configurable;
import brooklyn.event.basic.BasicConfigKey;
@@@ -113,7 -104,7 +106,7 @@@ public abstract class AbstractLocation
private final Map<Class<?>, Object> extensions = Maps.newConcurrentMap();
-- private final EntityDynamicType entityType;
++ private final LocationDynamicType locationType;
/**
* Construct a new instance of an AbstractLocation.
@@@ -141,28 -132,20 +134,18 @@@
* <li>abbreviatedName
* </ul>
*/
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public AbstractLocation(Map properties) {
+ public AbstractLocation(Map<?,?> properties) {
+ super(properties);
inConstruction = true;
- _legacyConstruction = !InternalFactory.FactoryConstructionTracker.isConstructing();
- if (!_legacyConstruction && properties!=null && !properties.isEmpty()) {
- LOG.warn("Forcing use of deprecated old-style location construction for "+getClass().getName()+" because properties were specified ("+properties+")");
- _legacyConstruction = true;
- }
// When one calls getConfig(key), we want to use the default value specified on *this* location
-- // if it overrides the default config. The easiest way to look up all our config keys is to
-- // reuse the code for Entity (and this will become identical when locations become first-class
-- // entities). See {@link #getConfig(ConfigKey)}
-- entityType = new EntityDynamicType((Class)getClass());
++ // if it overrides the default config, by using the type object
++ locationType = new LocationDynamicType(this);
- if (_legacyConstruction) {
- LOG.warn("Deprecated use of old-style location construction for "+getClass().getName()+"; instead use LocationManager().createLocation(spec)");
- if (LOG.isDebugEnabled())
- LOG.debug("Source of use of old-style location construction", new Throwable("Source of use of old-style location construction"));
-
- configure(properties);
-
+ if (isLegacyConstruction()) {
+ AbstractBrooklynObject checkWeGetThis = configure(properties);
+ assert this.equals(checkWeGetThis) : this+" configure method does not return itself; returns "+checkWeGetThis+" instead of "+this;
+
boolean deferConstructionChecks = (properties.containsKey("deferConstructionChecks") && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class));
if (!deferConstructionChecks) {
FlagUtils.checkRequiredFields(this);
@@@ -218,28 -201,12 +201,14 @@@
}
}
- @Override
- public ManagementContext getManagementContext() {
- return managementContext;
- }
-
/**
- * Will set fields from flags. The unused configuration can be found via the
- * {@linkplain ConfigBag#getUnusedConfig()}.
- * This can be overridden for custom initialization but note the following.
- * <p>
- * For new-style locations (i.e. not calling constructor directly, this will
- * be invoked automatically by brooklyn-core post-construction).
- * <p>
- * For legacy location use, this will be invoked by the constructor in this class.
- * Therefore if over-riding you must *not* rely on field initializers because they
- * may not run until *after* this method (this method is invoked by the constructor
- * 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).
- * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly
++ * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly;
++ * see overridden method for more info
*/
+ @SuppressWarnings("serial")
- public void configure(Map<?,?> properties) {
+ @Override
+ @Deprecated
- public AbstractLocation configure(Map properties) {
++ public AbstractLocation configure(Map<?,?> properties) {
assertNotYetManaged();
boolean firstTime = !configured.getAndSet(true);
@@@ -406,8 -338,7 +342,8 @@@
// 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.
- ConfigKey<T> ownKey = (ConfigKey<T>) elvis(entityType.getConfigKey(key.getName()), key);
+ @SuppressWarnings("unchecked")
- ConfigKey<T> ownKey = (ConfigKey<T>) elvis(entityType.getConfigKey(key.getName()), key);
++ ConfigKey<T> ownKey = (ConfigKey<T>) elvis(locationType.getConfigKey(key.getName()), key);
return ownKey.getDefaultValue();
}
@@@ -450,11 -381,19 +386,20 @@@
@Override
public <T> T setConfig(ConfigKey<T> key, T value) {
- return configBag.put(key, value);
+ T result = configBag.put(key, value);
+ onChanged();
+ return result;
}
+ /**
+ * @since 0.6.0 (?) - use getDisplayName
+ * @deprecated since 0.7.0; use {@link #getDisplayName()}
+ */
+ @Deprecated
+ public void setName(String newName) {
+ setDisplayName(newName);
- displayNameAutoGenerated = false;
+ }
+
public void setDisplayName(String newName) {
name.set(newName);
displayNameAutoGenerated = false;
@@@ -514,13 -451,10 +459,12 @@@
}
if (isManaged()) {
- if (!managementContext.getLocationManager().isManaged(child)) {
- // this deprecated call should be replaced with an internal interface call?
- managementContext.getLocationManager().manage(child);
- Locations.manage(child, getManagementContext());
++ if (!getManagementContext().getLocationManager().isManaged(child)) {
++ Locations.manage(child, getManagementContext());
+ }
- } else if (managementContext != null) {
- if (((LocalLocationManager)managementContext.getLocationManager()).getLocationEvenIfPreManaged(child.getId()) == null) {
- ((ManagementContextInternal)managementContext).prePreManage(child);
+ } else if (getManagementContext() != null) {
+ if (((LocalLocationManager)getManagementContext().getLocationManager()).getLocationEvenIfPreManaged(child.getId()) == null) {
+ ((ManagementContextInternal)getManagementContext()).prePreManage(child);
}
}
@@@ -542,25 -474,12 +486,20 @@@
child.setParent(null);
if (isManaged()) {
- managementContext.getLocationManager().unmanage(child);
+ getManagementContext().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/d4a6328e/core/src/main/java/brooklyn/location/basic/LocationDynamicType.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/location/basic/LocationDynamicType.java
index 0000000,0000000..cc0b304
new file mode 100644
--- /dev/null
+++ b/core/src/main/java/brooklyn/location/basic/LocationDynamicType.java
@@@ -1,0 -1,0 +1,39 @@@
++/*
++ * 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.location.basic;
++
++import brooklyn.basic.BrooklynDynamicType;
++import brooklyn.location.Location;
++import brooklyn.location.LocationType;
++
++public class LocationDynamicType extends BrooklynDynamicType<Location, AbstractLocation> {
++
++ public LocationDynamicType(AbstractLocation location) {
++ super(location);
++ }
++
++ public LocationType getSnapshot() {
++ return (LocationType) super.getSnapshot();
++ }
++
++ @Override
++ protected LocationTypeSnapshot newSnapshot() {
++ return new LocationTypeSnapshot(name, value(configKeys));
++ }
++}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/main/java/brooklyn/location/basic/LocationTypeSnapshot.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/location/basic/LocationTypeSnapshot.java
index 0000000,0000000..9a96e98
new file mode 100644
--- /dev/null
+++ b/core/src/main/java/brooklyn/location/basic/LocationTypeSnapshot.java
@@@ -1,0 -1,0 +1,40 @@@
++/*
++ * 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.location.basic;
++
++import java.util.Map;
++
++import brooklyn.basic.BrooklynTypeSnapshot;
++import brooklyn.config.ConfigKey;
++import brooklyn.policy.EnricherType;
++
++public class LocationTypeSnapshot extends BrooklynTypeSnapshot implements EnricherType {
++
++ private static final long serialVersionUID = 9150132836104748237L;
++
++ LocationTypeSnapshot(String name, Map<String, ConfigKey<?>> configKeys) {
++ super(name, configKeys);
++ }
++
++ @Override
++ public boolean equals(Object obj) {
++ if (this == obj) return true;
++ return (obj instanceof LocationTypeSnapshot) && super.equals(obj);
++ }
++}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
index a53d9a5,7f0e08f..36d8505
--- a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
@@@ -40,8 -39,7 +39,6 @@@ import brooklyn.entity.Entity
import brooklyn.entity.Group;
import brooklyn.entity.basic.EntityInternal;
import brooklyn.entity.basic.EntityLocal;
- import brooklyn.entity.proxying.InternalFactory;
--import brooklyn.entity.rebind.RebindManagerImpl;
import brooklyn.entity.trait.Configurable;
import brooklyn.event.AttributeSensor;
import brooklyn.event.Sensor;
@@@ -407,25 -331,11 +338,17 @@@ public abstract class AbstractEntityAdj
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/d4a6328e/core/src/main/java/brooklyn/policy/basic/AbstractPolicy.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/test/java/brooklyn/enricher/basic/BasicEnricherTest.java
----------------------------------------------------------------------
diff --cc core/src/test/java/brooklyn/enricher/basic/BasicEnricherTest.java
index b62b9c9,0000000..1252e36
mode 100644,000000..100644
--- a/core/src/test/java/brooklyn/enricher/basic/BasicEnricherTest.java
+++ b/core/src/test/java/brooklyn/enricher/basic/BasicEnricherTest.java
@@@ -1,100 -1,0 +1,100 @@@
+/*
+ * 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.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.getTagSupport().getTags(), MutableSet.of("x", 99));
+ assertEquals(enricher.getUniqueTag(), "x");
+ }
+
+ @Test
+ public void testSameUniqueTagEnricherNotAddedTwice() throws Exception {
+ MyEnricher enricher1 = app.addEnricher(EnricherSpec.create(MyEnricher.class).tag(99).uniqueTag("x"));
+ MyEnricher enricher2 = app.addEnricher(EnricherSpec.create(MyEnricher.class).tag(94).uniqueTag("x"));
+ assertEquals(enricher2, enricher1);
+ assertEquals(app.getEnrichers().size(), 1);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
----------------------------------------------------------------------
diff --cc core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
index e9b3399,999c168..415efa5
--- a/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
@@@ -107,26 -107,22 +107,26 @@@ public class EntitiesTest extends Brook
@Test
public void testCreateGetContainsAndRemoveTags() throws Exception {
entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)
+ .tag(2)
.addInitializer(EntityInitializers.addingTags("foo")));
- entity.addTag(app);
+ entity.getTagSupport().addTag(app);
- Assert.assertTrue(entity.containsTag(app));
- Assert.assertTrue(entity.containsTag("foo"));
- Assert.assertTrue(entity.containsTag(2));
- Assert.assertFalse(entity.containsTag("bar"));
++ Assert.assertTrue(entity.getTagSupport().containsTag(app));
+ Assert.assertTrue(entity.getTagSupport().containsTag("foo"));
++ Assert.assertTrue(entity.getTagSupport().containsTag(2));
+ Assert.assertFalse(entity.getTagSupport().containsTag("bar"));
- Assert.assertEquals(entity.getTags(), MutableSet.of(app, "foo", 2));
- Assert.assertEquals(entity.getTagSupport().getTags(), MutableSet.of(app, "foo"));
++ Assert.assertEquals(entity.getTagSupport().getTags(), MutableSet.of(app, "foo", 2));
- entity.removeTag("foo");
- Assert.assertFalse(entity.containsTag("foo"));
+ entity.getTagSupport().removeTag("foo");
+ Assert.assertFalse(entity.getTagSupport().containsTag("foo"));
- Assert.assertTrue(entity.containsTag(entity.getParent()));
- Assert.assertFalse(entity.containsTag(entity));
+ Assert.assertTrue(entity.getTagSupport().containsTag(entity.getParent()));
+ Assert.assertFalse(entity.getTagSupport().containsTag(entity));
+ entity.removeTag(2);
- Assert.assertEquals(entity.getTags(), MutableSet.of(app));
+ Assert.assertEquals(entity.getTagSupport().getTags(), MutableSet.of(app));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
----------------------------------------------------------------------
diff --cc core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
index d23e2d2,d8273ca..27e5edc
--- a/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
@@@ -177,11 -174,7 +179,11 @@@ public class RebindEnricherTest extend
newApp = (TestApplication) rebind();
MyEnricher newEnricher = (MyEnricher) Iterables.getOnlyElement(newApp.getEnrichers());
- assertEquals(newEnricher.getName(), "My Enricher");
+ assertEquals(newEnricher.getDisplayName(), "My Enricher");
+
+ assertEquals(newEnricher.getUniqueTag(), "tagU");
- assertEquals(newEnricher.getTags(), MutableSet.of("tagU", "tag1", "tag2"));
++ assertEquals(newEnricher.getTagSupport().getTags(), MutableSet.of("tagU", "tag1", "tag2"));
+
assertEquals(newEnricher.getConfig(MyEnricher.MY_CONFIG_WITH_SETFROMFLAG_NO_SHORT_NAME), "myVal for with setFromFlag noShortName");
assertEquals(newEnricher.getConfig(MyEnricher.MY_CONFIG_WITH_SETFROMFLAG_WITH_SHORT_NAME), "myVal for setFromFlag withShortName");
assertEquals(newEnricher.getConfig(MyEnricher.MY_CONFIG_WITHOUT_SETFROMFLAG), "myVal for witout setFromFlag");
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
----------------------------------------------------------------------
diff --cc core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
index bc4e845,90d700b..e0314c3
--- a/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
@@@ -111,14 -110,9 +114,14 @@@ public class RebindPolicyTest extends R
.configure(MyPolicy.MY_CONFIG_WITH_SETFROMFLAG_WITH_SHORT_NAME, "myVal for setFromFlag withShortName")
.configure(MyPolicy.MY_CONFIG_WITHOUT_SETFROMFLAG, "myVal for witout setFromFlag"));
- newApp = (TestApplication) rebind();
+ newApp = rebind();
MyPolicy newPolicy = (MyPolicy) Iterables.getOnlyElement(newApp.getPolicies());
+ assertEquals(newPolicy.getDisplayName(), "My Policy");
+
+ assertEquals(newPolicy.getUniqueTag(), "tagU");
- assertEquals(newPolicy.getTags(), MutableSet.of("tagU", "tag1", "tag2"));
++ assertEquals(newPolicy.getTagSupport().getTags(), MutableSet.of("tagU", "tag1", "tag2"));
+
assertEquals(newPolicy.getConfig(MyPolicy.MY_CONFIG_WITH_SETFROMFLAG_NO_SHORT_NAME), "myVal for with setFromFlag noShortName");
assertEquals(newPolicy.getConfig(MyPolicy.MY_CONFIG_WITH_SETFROMFLAG_WITH_SHORT_NAME), "myVal for setFromFlag withShortName");
assertEquals(newPolicy.getConfig(MyPolicy.MY_CONFIG_WITHOUT_SETFROMFLAG), "myVal for witout setFromFlag");
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java
----------------------------------------------------------------------
diff --cc core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java
index 97fb633,4993486..d005098
--- a/core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java
+++ b/core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java
@@@ -76,6 -75,6 +76,7 @@@ public class AbstractLocationTest
private ConcreteLocation createConcrete(Map<String,?> flags) {
return createConcrete(null, flags);
}
++ @SuppressWarnings("deprecation")
private ConcreteLocation createConcrete(String id, Map<String,?> flags) {
return mgmt.getLocationManager().createLocation( LocationSpec.create(ConcreteLocation.class).id(id).configure(flags) );
}
@@@ -173,11 -172,5 +174,11 @@@
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"));
++ assertEquals(loc.getTagSupport().getTags(), MutableSet.of("x"));
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d4a6328e/core/src/test/java/brooklyn/policy/basic/BasicPolicyTest.java
----------------------------------------------------------------------
diff --cc core/src/test/java/brooklyn/policy/basic/BasicPolicyTest.java
index 1072bc8,0000000..2488aee
mode 100644,000000..100644
--- a/core/src/test/java/brooklyn/policy/basic/BasicPolicyTest.java
+++ b/core/src/test/java/brooklyn/policy/basic/BasicPolicyTest.java
@@@ -1,89 -1,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.getTagSupport().getTags(), MutableSet.of("x", 99));
+ assertEquals(policy.getUniqueTag(), "x");
+ }
+
+}
[4/9] git commit: Tidy Internal*Factory
Posted by he...@apache.org.
Tidy Internal*Factory
- deprecates isNewStyleEnricher etc, in preference for general
InternalFactory.isNewStyle
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/2a0d03a9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/2a0d03a9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/2a0d03a9
Branch: refs/heads/master
Commit: 2a0d03a9fe05fdaf384f67b4323916a31b30408a
Parents: bf0b3e7
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 6 22:39:42 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 6 23:17:46 2014 +0100
----------------------------------------------------------------------
.../entity/proxying/BasicEntityTypeRegistry.java | 2 --
.../entity/proxying/InternalLocationFactory.java | 9 ++++++++-
.../entity/proxying/InternalPolicyFactory.java | 15 +++++++++++++--
.../brooklyn/entity/rebind/RebindManagerImpl.java | 4 ++--
4 files changed, 23 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a0d03a9/core/src/main/java/brooklyn/entity/proxying/BasicEntityTypeRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/proxying/BasicEntityTypeRegistry.java b/core/src/main/java/brooklyn/entity/proxying/BasicEntityTypeRegistry.java
index aeb4365..09f0cfb 100644
--- a/core/src/main/java/brooklyn/entity/proxying/BasicEntityTypeRegistry.java
+++ b/core/src/main/java/brooklyn/entity/proxying/BasicEntityTypeRegistry.java
@@ -30,9 +30,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import brooklyn.entity.Entity;
-import brooklyn.entity.basic.AbstractEntity;
import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.javalang.Reflections;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a0d03a9/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..b989392 100644
--- a/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
+++ b/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
@@ -51,7 +51,10 @@ public class InternalLocationFactory extends InternalFactory {
*
* @param managementContext
* @param clazz
+ *
+ * @deprecated since 0.7.0; use {@link InternalFactory#isNewStyle(Class)}
*/
+ @Deprecated
public static boolean isNewStyleLocation(ManagementContext managementContext, Class<?> clazz) {
try {
return isNewStyleLocation(clazz);
@@ -60,6 +63,10 @@ public class InternalLocationFactory extends InternalFactory {
}
}
+ /**
+ * @deprecated since 0.7.0; use {@link InternalFactory#isNewStyle(Class)}
+ */
+ @Deprecated
public static boolean isNewStyleLocation(Class<?> clazz) {
if (!Location.class.isAssignableFrom(clazz)) {
throw new IllegalArgumentException("Class "+clazz+" is not an location");
@@ -97,7 +104,7 @@ public class InternalLocationFactory extends InternalFactory {
if (spec.getDisplayName()!=null)
((AbstractLocation)loc).setName(spec.getDisplayName());
- if (isNewStyleLocation(clazz)) {
+ if (isNewStyle(clazz)) {
((AbstractLocation)loc).setManagementContext(managementContext);
((AbstractLocation)loc).configure(ConfigBag.newInstance().putAll(spec.getFlags()).putAll(spec.getConfig()).getAllConfig());
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a0d03a9/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..d52d368 100644
--- a/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java
+++ b/core/src/main/java/brooklyn/entity/proxying/InternalPolicyFactory.java
@@ -51,7 +51,10 @@ public class InternalPolicyFactory extends InternalFactory {
*
* @param managementContext
* @param clazz
+ *
+ * @deprecated since 0.7.0; use {@link InternalFactory#isNewStyle(Class)}
*/
+ @Deprecated
public static boolean isNewStylePolicy(ManagementContext managementContext, Class<?> clazz) {
try {
return isNewStylePolicy(clazz);
@@ -60,6 +63,10 @@ public class InternalPolicyFactory extends InternalFactory {
}
}
+ /**
+ * @deprecated since 0.7.0; use {@link InternalFactory#isNewStyle(Class)}
+ */
+ @Deprecated
public static boolean isNewStylePolicy(Class<?> clazz) {
if (!Policy.class.isAssignableFrom(clazz)) {
throw new IllegalArgumentException("Class "+clazz+" is not a policy");
@@ -68,6 +75,10 @@ public class InternalPolicyFactory extends InternalFactory {
return InternalFactory.isNewStyle(clazz);
}
+ /**
+ * @deprecated since 0.7.0; use {@link InternalFactory#isNewStyle(Class)}
+ */
+ @Deprecated
public static boolean isNewStyleEnricher(Class<?> clazz) {
if (!Enricher.class.isAssignableFrom(clazz)) {
throw new IllegalArgumentException("Class "+clazz+" is not an enricher");
@@ -94,7 +105,7 @@ public class InternalPolicyFactory extends InternalFactory {
if (spec.getDisplayName()!=null)
((AbstractPolicy)pol).setDisplayName(spec.getDisplayName());
- if (isNewStylePolicy(clazz)) {
+ if (isNewStyle(clazz)) {
((AbstractPolicy)pol).setManagementContext(managementContext);
Map<String, Object> config = ConfigBag.newInstance().putAll(spec.getFlags()).putAll(spec.getConfig()).getAllConfig();
((AbstractPolicy)pol).configure(MutableMap.copyOf(config)); // TODO AbstractPolicy.configure modifies the map
@@ -129,7 +140,7 @@ public class InternalPolicyFactory extends InternalFactory {
if (spec.getDisplayName()!=null)
((AbstractEnricher)enricher).setDisplayName(spec.getDisplayName());
- if (isNewStyleEnricher(clazz)) {
+ if (isNewStyle(clazz)) {
((AbstractEnricher)enricher).setManagementContext(managementContext);
Map<String, Object> config = ConfigBag.newInstance().putAll(spec.getFlags()).putAll(spec.getConfig()).getAllConfig();
((AbstractEnricher)enricher).configure(MutableMap.copyOf(config)); // TODO AbstractEnricher.configure modifies the map
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a0d03a9/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java b/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
index 4e8ffc8..5094e78 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
@@ -645,7 +645,7 @@ public class RebindManagerImpl implements RebindManager {
String policyType = checkNotNull(memento.getType(), "policy type of %s must not be null in memento", id);
Class<? extends Policy> policyClazz = (Class<? extends Policy>) reflections.loadClass(policyType);
- if (InternalPolicyFactory.isNewStylePolicy(policyClazz)) {
+ if (InternalFactory.isNewStyle(policyClazz)) {
InternalPolicyFactory policyFactory = managementContext.getPolicyFactory();
Policy policy = policyFactory.constructPolicy(policyClazz);
FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", id), policy);
@@ -677,7 +677,7 @@ public class RebindManagerImpl implements RebindManager {
String enricherType = checkNotNull(memento.getType(), "enricher type of %s must not be null in memento", id);
Class<? extends Enricher> enricherClazz = (Class<? extends Enricher>) reflections.loadClass(enricherType);
- if (InternalPolicyFactory.isNewStyleEnricher(enricherClazz)) {
+ if (InternalFactory.isNewStyle(enricherClazz)) {
InternalPolicyFactory policyFactory = managementContext.getPolicyFactory();
Enricher enricher = policyFactory.constructEnricher(enricherClazz);
FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", id), enricher);