You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ha...@apache.org on 2015/08/18 08:39:26 UTC
[3/4] incubator-brooklyn git commit: This closes #833
This closes #833
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/f9b357d7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/f9b357d7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/f9b357d7
Branch: refs/heads/master
Commit: f9b357d716e28067eed4af3c691b22921a54d296
Parents: 4d0bbce e1a2d66
Author: Hadrian Zbarcea <ha...@apache.org>
Authored: Tue Aug 18 02:28:19 2015 -0400
Committer: Hadrian Zbarcea <ha...@apache.org>
Committed: Tue Aug 18 02:28:19 2015 -0400
----------------------------------------------------------------------
.../brooklyn/basic/AbstractBrooklynObject.java | 249 ----------------
.../brooklyn/basic/BasicConfigurableObject.java | 120 --------
.../brooklyn/basic/BrooklynDynamicType.java | 284 -------------------
.../brooklyn/basic/BrooklynObjectInternal.java | 104 -------
.../brooklyn/basic/BrooklynTypeSnapshot.java | 102 -------
.../main/java/brooklyn/basic/BrooklynTypes.java | 132 ---------
.../basic/internal/ApiObjectsFactoryImpl.java | 42 ---
.../enricher/basic/EnricherDynamicType.java | 2 +-
.../enricher/basic/EnricherTypeSnapshot.java | 2 +-
.../brooklyn/entity/basic/AbstractEntity.java | 2 +-
.../java/brooklyn/entity/basic/Entities.java | 2 +-
.../entity/basic/EntityDynamicType.java | 2 +-
.../brooklyn/entity/basic/EntityInternal.java | 2 +-
.../entity/basic/EntityTypeSnapshot.java | 2 +-
.../java/brooklyn/entity/basic/EntityTypes.java | 2 +-
.../AbstractBrooklynObjectRebindSupport.java | 2 +-
.../rebind/ActivePartialRebindIteration.java | 2 +-
.../rebind/ImmediateDeltaChangeListener.java | 2 +-
.../rebind/PeriodicDeltaChangeListener.java | 2 +-
.../brooklyn/entity/rebind/RebindIteration.java | 4 +-
.../entity/rebind/dto/BasicEntityMemento.java | 3 +-
.../entity/rebind/dto/MementosGenerators.java | 2 +-
.../persister/BrooklynPersistenceUtils.java | 2 +-
.../brooklyn/basic/AbstractBrooklynObject.java | 249 ++++++++++++++++
.../brooklyn/basic/BasicConfigurableObject.java | 120 ++++++++
.../brooklyn/basic/BrooklynDynamicType.java | 284 +++++++++++++++++++
.../brooklyn/basic/BrooklynObjectInternal.java | 104 +++++++
.../brooklyn/basic/BrooklynTypeSnapshot.java | 102 +++++++
.../apache/brooklyn/basic/BrooklynTypes.java | 132 +++++++++
.../basic/internal/ApiObjectsFactoryImpl.java | 42 +++
.../catalog/internal/BasicBrooklynCatalog.java | 2 +-
.../core/catalog/internal/CatalogItemDo.java | 2 +-
.../internal/CatalogItemDtoAbstract.java | 2 +-
.../core/catalog/internal/CatalogUtils.java | 2 +-
.../catalog/internal/CatalogXmlSerializer.java | 4 +-
.../policy/basic/AbstractEntityAdjunct.java | 4 +-
.../core/policy/basic/PolicyDynamicType.java | 2 +-
.../core/policy/basic/PolicyTypeSnapshot.java | 2 +-
.../location/basic/AbstractLocation.java | 2 +-
.../location/basic/LocationDynamicType.java | 2 +-
.../location/basic/LocationInternal.java | 2 +-
.../location/basic/LocationTypeSnapshot.java | 2 +-
...pi.basic.internal.ApiObjectsFactoryInterface | 2 +-
.../CatalogOsgiVersionMoreEntityTest.java | 2 +-
.../main/java/org/apache/brooklyn/cli/Main.java | 13 +-
.../brooklyn/cli/lister/ItemDescriptors.java | 4 +-
.../SoftlayerObtainPrivateLiveTest.java | 2 +-
.../rest/resources/PolicyConfigResource.java | 2 +-
.../rest/transform/CatalogTransformer.java | 2 +-
.../rest/util/BrooklynRestResourceUtils.java | 2 +-
50 files changed, 1074 insertions(+), 1084 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/basic/Entities.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/entity/basic/EntityInternal.java
index 36e6907,f7fa53f..d9967d1
--- a/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
@@@ -33,10 -33,10 +33,10 @@@ import org.apache.brooklyn.api.manageme
import org.apache.brooklyn.api.management.SubscriptionContext;
import org.apache.brooklyn.api.mementos.EntityMemento;
import org.apache.brooklyn.core.management.internal.EntityManagementSupport;
+import org.apache.brooklyn.core.util.config.ConfigBag;
- import brooklyn.basic.BrooklynObjectInternal;
+ import org.apache.brooklyn.basic.BrooklynObjectInternal;
import brooklyn.config.ConfigKey;
-import brooklyn.util.config.ConfigBag;
import com.google.common.annotations.Beta;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
index 000a651,f3eca47..aed26d4
--- a/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
@@@ -26,8 -25,9 +26,8 @@@ import org.apache.brooklyn.core.policy.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
- import brooklyn.basic.AbstractBrooklynObject;
+ import org.apache.brooklyn.basic.AbstractBrooklynObject;
import brooklyn.entity.rebind.dto.MementosGenerators;
-import brooklyn.policy.basic.AbstractEntityAdjunct.AdjunctTagSupport;
import brooklyn.util.text.Strings;
public abstract class AbstractBrooklynObjectRebindSupport<T extends Memento> implements RebindSupport<T> {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/basic/AbstractBrooklynObject.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/basic/AbstractBrooklynObject.java
index 0000000,260c91b..4515492
mode 000000,100644..100644
--- a/core/src/main/java/org/apache/brooklyn/basic/AbstractBrooklynObject.java
+++ b/core/src/main/java/org/apache/brooklyn/basic/AbstractBrooklynObject.java
@@@ -1,0 -1,249 +1,249 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ package org.apache.brooklyn.basic;
+
+ import java.util.Collections;
+ import java.util.Map;
+ import java.util.Set;
+
+ import org.apache.brooklyn.api.basic.internal.ApiObjectsFactory;
+ import org.apache.brooklyn.api.management.ManagementContext;
+ import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
++import org.apache.brooklyn.core.util.config.ConfigBag;
++import org.apache.brooklyn.core.util.flags.SetFromFlag;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+
+ import brooklyn.entity.basic.AbstractEntity;
+ import brooklyn.entity.proxying.InternalFactory;
+ import brooklyn.entity.rebind.RebindManagerImpl;
-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.Iterables;
+ 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;
+ private boolean hasWarnedOfNoManagementContextWhenPersistRequested;
+
+ @SetFromFlag(value = "id")
+ private String id = Identifiers.makeRandomId(8);
+
+ private String catalogItemId;
+
+ /** subclasses should synchronize on this for all access */
+ @SetFromFlag(value = "tags")
+ 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 construction for {} because properties were " +
+ "specified ({}); instead use specs (e.g. LocationSpec, EntitySpec, etc)",
+ getClass().getName(), properties);
+ if (log.isDebugEnabled())
+ log.debug("Source of use of old-style construction", new Throwable("Source of use of old-style construction"));
+ _legacyConstruction = true;
+ }
+
+ catalogItemId = ApiObjectsFactory.get().getCatalogItemIdFromContext();
+
+ // 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 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.
+ * <p>
+ * 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):
+ * <ul>
+ * <li> after configuring, but
+ * <li> before the instance is managed, and
+ * <li> before adjuncts are attached to entities, and
+ * <li> before a reference to an object is shared.
+ * </ul>
+ * Note that {@link #init()} will not be called on rebind.
+ * <p>
+ * If you need to intercept behaviour <i>after</i> adjuncts are attached,
+ * consider {@link AbstractEntity#onManagementStarting()}
+ * (but probably worth raising a discussion on the mailing list!)
+ */
+ 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() {
+ if (getManagementContext() != null) {
+ getManagementContext().getRebindManager().getChangeListener().onChanged(this);
+ } else {
+ // Might be nice to log this at debug but it gets hit a lot of times as locations
+ // are created and destroyed for the API. It also might not be an error - the
+ // management context might be null if the object is being recreated by persistence.
+ if (log.isTraceEnabled() && !hasWarnedOfNoManagementContextWhenPersistRequested) {
+ log.trace("Cannot fulfil request to persist {} because it has no management context. " +
+ "This warning will not be logged for this object again.", this);
+ hasWarnedOfNoManagementContextWhenPersistRequested = true;
+ }
+ }
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public void setCatalogItemId(String id) {
+ this.catalogItemId = id;
+ }
+
+ @Override
+ public String getCatalogItemId() {
+ return catalogItemId;
+ }
+
+ protected void onTagsChanged() {
+ requestPersist();
+ }
+
+ @Override
+ public TagSupport tags() {
+ return new BasicTagSupport();
+ }
+
+ 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);
+ }
+ }
+
+ @Override
+ public boolean addTag(Object tag) {
+ boolean result;
+ synchronized (tags) {
+ result = tags.add(tag);
+ }
+ onTagsChanged();
+ return result;
+ }
+
+ @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/f9b357d7/core/src/main/java/org/apache/brooklyn/basic/BasicConfigurableObject.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/basic/BasicConfigurableObject.java
index 0000000,f376d74..f79b1d7
mode 000000,100644..100644
--- a/core/src/main/java/org/apache/brooklyn/basic/BasicConfigurableObject.java
+++ b/core/src/main/java/org/apache/brooklyn/basic/BasicConfigurableObject.java
@@@ -1,0 -1,120 +1,120 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ package org.apache.brooklyn.basic;
+
+ import org.apache.brooklyn.api.entity.trait.Configurable;
+ import org.apache.brooklyn.api.entity.trait.Identifiable;
+ import org.apache.brooklyn.api.management.ManagementContext;
+ import org.apache.brooklyn.api.management.Task;
+ import org.apache.brooklyn.core.management.ManagementContextInjectable;
++import org.apache.brooklyn.core.util.config.ConfigBag;
++import org.apache.brooklyn.core.util.flags.SetFromFlag;
+
+ import brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
+ import brooklyn.config.ConfigKey;
+ import brooklyn.config.ConfigKey.HasConfigKey;
+ import brooklyn.config.ConfigMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.flags.SetFromFlag;
+ import brooklyn.util.text.Identifiers;
+
+ /**
+ * A parent class for ancilliary objects that do not require the full heavy lifting of {@link AbstractBrooklynObject}
+ * or similar, but wish to use {@link ConfigKey} and {@link Configurable} in their construction, via the
+ * {@code $brooklyn:object} method of the CAMP DSL.
+ * <p>
+ * Type coercion of values will occur when the {@link ConfigMap} is accessed, but resolving of {@link Task tasks} and other
+ * deferred operations are assumed to have occurred prior to calling {@link #setConfig(ConfigKey, Object)} i.e. at
+ * object construction.
+ */
+ public class BasicConfigurableObject implements Configurable, Identifiable, ManagementContextInjectable, HasBrooklynManagementContext {
+
+ @SetFromFlag("id")
+ private String id = Identifiers.makeRandomId(8);
+
+ private volatile ManagementContext managementContext;
+ private BasicConfigurationSupport config;
+
+ public BasicConfigurableObject() {
+ config = new BasicConfigurationSupport();
+ }
+
+ @Override
+ public void injectManagementContext(ManagementContext managementContext) {
+ this.managementContext = managementContext;
+ }
+
+ public ManagementContext getBrooklynManagementContext() {
+ return managementContext;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public ConfigurationSupport config() {
+ return config;
+ }
+
+ @Override
+ @Deprecated
+ public <T> T setConfig(ConfigKey<T> key, T value) {
+ return config().set(key, value);
+ }
+
+ public <T> T getConfig(ConfigKey<T> key) {
+ return config().get(key);
+ }
+
+ private static class BasicConfigurationSupport implements ConfigurationSupport {
+ private final ConfigBag config = ConfigBag.newInstance();
+
+ @Override
+ public <T> T get(ConfigKey<T> key) {
+ return config.get(key);
+ }
+
+ @Override
+ public <T> T get(HasConfigKey<T> key) {
+ return get(key.getConfigKey());
+ }
+
+ @Override
+ public <T> T set(ConfigKey<T> key, T val) {
+ T old = config.get(key);
+ config.configure(key, val);
+ return old;
+ }
+
+ @Override
+ public <T> T set(HasConfigKey<T> key, T val) {
+ return set(key.getConfigKey(), val);
+ }
+
+ @Override
+ public <T> T set(ConfigKey<T> key, Task<T> val) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> T set(HasConfigKey<T> key, Task<T> val) {
+ return set(key.getConfigKey(), val);
+ }
+ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/basic/BrooklynDynamicType.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/basic/BrooklynDynamicType.java
index 0000000,368b035..f6a8893
mode 000000,100644..100644
--- a/core/src/main/java/org/apache/brooklyn/basic/BrooklynDynamicType.java
+++ b/core/src/main/java/org/apache/brooklyn/basic/BrooklynDynamicType.java
@@@ -1,0 -1,284 +1,284 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ package org.apache.brooklyn.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.apache.brooklyn.api.basic.BrooklynObject;
+ import org.apache.brooklyn.api.basic.BrooklynType;
++import org.apache.brooklyn.core.util.flags.FlagUtils;
+ 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 {
+ Object v = f.get(optionalInstance);
+
+ if (v == null) {
+ LOG.warn("no value defined for config key field (skipping): "+f);
+ } else {
+ ConfigKey<?> k = isConfigKey ? (ConfigKey<?>) v : ((HasConfigKey<?>) v).getConfigKey();
+ 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;
+ }
+
+ 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/f9b357d7/core/src/main/java/org/apache/brooklyn/basic/BrooklynObjectInternal.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/basic/BrooklynObjectInternal.java
index 0000000,8109b78..eacb1e1
mode 000000,100644..100644
--- a/core/src/main/java/org/apache/brooklyn/basic/BrooklynObjectInternal.java
+++ b/core/src/main/java/org/apache/brooklyn/basic/BrooklynObjectInternal.java
@@@ -1,0 -1,104 +1,104 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ package org.apache.brooklyn.basic;
+
+ import java.util.Map;
+
+ import org.apache.brooklyn.api.basic.BrooklynObject;
+ import org.apache.brooklyn.api.entity.rebind.RebindSupport;
+ import org.apache.brooklyn.api.entity.rebind.Rebindable;
+ import org.apache.brooklyn.api.entity.trait.Configurable;
++import org.apache.brooklyn.core.util.config.ConfigBag;
+
+ import brooklyn.config.ConfigKey;
+ import brooklyn.config.ConfigKey.HasConfigKey;
-import brooklyn.util.config.ConfigBag;
+ import brooklyn.util.guava.Maybe;
+
+ import com.google.common.annotations.Beta;
+
+ public interface BrooklynObjectInternal extends BrooklynObject, Rebindable {
+
+ void setCatalogItemId(String id);
+
+ @SuppressWarnings("rawtypes") // subclasses typically apply stronger typing
+ RebindSupport getRebindSupport();
+
+ ConfigurationSupportInternal config();
+
+ @Beta
+ public interface ConfigurationSupportInternal extends Configurable.ConfigurationSupport {
+
+ /**
+ * Returns a read-only view of all the config key/value pairs on this entity, backed by a string-based map,
+ * including config names that did not match anything on this entity.
+ *
+ * TODO This method gives no information about which config is inherited versus local;
+ * this means {@link ConfigKey#getInheritance()} cannot be respected. This is an unsolvable problem
+ * for "config names that did not match anything on this entity". Therefore consider using
+ * alternative getters.
+ */
+ @Beta
+ ConfigBag getBag();
+
+ /**
+ * Returns a read-only view of the local (i.e. not inherited) config key/value pairs on this entity,
+ * backed by a string-based map, including config names that did not match anything on this entity.
+ */
+ @Beta
+ ConfigBag getLocalBag();
+
+ /**
+ * Returns the uncoerced value for this config key, if available, not taking any default.
+ * If there is no local value and there is an explicit inherited value, will return the inherited.
+ */
+ @Beta
+ Maybe<Object> getRaw(ConfigKey<?> key);
+
+ /**
+ * @see {@link #getConfigRaw(ConfigKey)}
+ */
+ @Beta
+ Maybe<Object> getRaw(HasConfigKey<?> key);
+
+ /**
+ * Returns the uncoerced value for this config key, if available,
+ * not following any inheritance chains and not taking any default.
+ */
+ @Beta
+ Maybe<Object> getLocalRaw(ConfigKey<?> key);
+
+ /**
+ * @see {@link #getLocalConfigRaw(ConfigKey)}
+ */
+ @Beta
+ Maybe<Object> getLocalRaw(HasConfigKey<?> key);
+
+ @Beta
+ void addToLocalBag(Map<String, ?> vals);
+
+ @Beta
+ void removeFromLocalBag(String key);
+
+ @Beta
+ void refreshInheritedConfig();
+
+ @Beta
+ void refreshInheritedConfigOfChildren();
+ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/basic/BrooklynTypes.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/basic/BrooklynTypes.java
index 0000000,f64c8f9..d199686
mode 000000,100644..100644
--- a/core/src/main/java/org/apache/brooklyn/basic/BrooklynTypes.java
+++ b/core/src/main/java/org/apache/brooklyn/basic/BrooklynTypes.java
@@@ -1,0 -1,132 +1,132 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ package org.apache.brooklyn.basic;
+
+ import java.util.Map;
+
+ import org.apache.brooklyn.api.basic.BrooklynObject;
+ import org.apache.brooklyn.api.entity.Entity;
+ import org.apache.brooklyn.api.event.Sensor;
+ import org.apache.brooklyn.api.location.Location;
+ import org.apache.brooklyn.api.policy.Enricher;
+ import org.apache.brooklyn.api.policy.Policy;
++import org.apache.brooklyn.core.policy.basic.PolicyDynamicType;
+
+ import brooklyn.config.ConfigKey;
+ import brooklyn.enricher.basic.EnricherDynamicType;
+ import brooklyn.entity.basic.EntityDynamicType;
-import brooklyn.policy.basic.PolicyDynamicType;
+ 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);
+ }
+
+ public 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 if (Location.class.isAssignableFrom(brooklynClass)) {
+ type = new ImmutableEntityType((Class<? extends Entity>)brooklynClass);
+ } else if (Policy.class.isAssignableFrom(brooklynClass)) {
+ type = new PolicyDynamicType((Class<? extends Policy>)brooklynClass); // TODO immutable?
+ } else if (Enricher.class.isAssignableFrom(brooklynClass)) {
+ type = new EnricherDynamicType((Class<? extends Enricher>)brooklynClass); // TODO immutable?
+ } 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/f9b357d7/core/src/main/java/org/apache/brooklyn/basic/internal/ApiObjectsFactoryImpl.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/basic/internal/ApiObjectsFactoryImpl.java
index 0000000,d200a3c..a51ee39
mode 000000,100644..100644
--- a/core/src/main/java/org/apache/brooklyn/basic/internal/ApiObjectsFactoryImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/basic/internal/ApiObjectsFactoryImpl.java
@@@ -1,0 -1,42 +1,42 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ package org.apache.brooklyn.basic.internal;
+
+ import org.apache.brooklyn.api.basic.internal.ApiObjectsFactoryInterface;
+ import org.apache.brooklyn.api.entity.Entity;
+ import org.apache.brooklyn.api.management.Task;
++import org.apache.brooklyn.core.util.task.Tasks;
+
+ import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.util.task.Tasks;
+
+ public class ApiObjectsFactoryImpl implements ApiObjectsFactoryInterface {
+
+ @Override
+ public String getCatalogItemIdFromContext() {
+ Task<?> currentTask = Tasks.current();
+ if (currentTask != null) {
+ Entity contextEntity = BrooklynTaskTags.getContextEntity(currentTask);
+ if (contextEntity != null) {
+ return contextEntity.getCatalogItemId();
+ }
+ }
+ return null;
+ }
+
+ }
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
index 836cac3,ede8bde..49462e2
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
@@@ -24,10 -24,10 +24,12 @@@ import java.util.List
import java.util.Map;
import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
+import org.apache.brooklyn.core.util.xstream.EnumCaseForgivingSingleValueConverter;
+import org.apache.brooklyn.core.util.xstream.XmlSerializer;
- import brooklyn.basic.AbstractBrooklynObject;
+ import org.apache.brooklyn.basic.AbstractBrooklynObject;
+ import brooklyn.util.xstream.EnumCaseForgivingSingleValueConverter;
+ import brooklyn.util.xstream.XmlSerializer;
public class CatalogXmlSerializer extends XmlSerializer<Object> {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/core/policy/basic/AbstractEntityAdjunct.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/core/policy/basic/AbstractEntityAdjunct.java
index eda106f,0000000..f5c36aa
mode 100644,000000..100644
--- a/core/src/main/java/org/apache/brooklyn/core/policy/basic/AbstractEntityAdjunct.java
+++ b/core/src/main/java/org/apache/brooklyn/core/policy/basic/AbstractEntityAdjunct.java
@@@ -1,510 -1,0 +1,510 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.policy.basic;
+
+import static brooklyn.util.GroovyJavaMethods.truth;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.Group;
+import org.apache.brooklyn.api.entity.basic.EntityLocal;
+import org.apache.brooklyn.api.entity.trait.Configurable;
+import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.event.Sensor;
+import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.management.ExecutionContext;
+import org.apache.brooklyn.api.management.SubscriptionContext;
+import org.apache.brooklyn.api.management.SubscriptionHandle;
+import org.apache.brooklyn.api.management.Task;
+import org.apache.brooklyn.api.policy.EntityAdjunct;
+import org.apache.brooklyn.core.management.internal.SubscriptionTracker;
+import org.apache.brooklyn.core.util.config.ConfigBag;
+import org.apache.brooklyn.core.util.flags.FlagUtils;
+import org.apache.brooklyn.core.util.flags.SetFromFlag;
+import org.apache.brooklyn.core.util.flags.TypeCoercions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
- import brooklyn.basic.AbstractBrooklynObject;
- import brooklyn.basic.BrooklynObjectInternal;
++import org.apache.brooklyn.basic.AbstractBrooklynObject;
++import org.apache.brooklyn.basic.BrooklynObjectInternal;
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+import brooklyn.config.ConfigMap;
+import brooklyn.enricher.basic.AbstractEnricher;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.text.Strings;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+
+
+/**
+ * Common functionality for policies and enrichers
+ */
+public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject implements BrooklynObjectInternal, EntityAdjunct, Configurable {
+ private static final Logger log = LoggerFactory.getLogger(AbstractEntityAdjunct.class);
+
+ private boolean _legacyNoConstructionInit;
+
+ /**
+ * @deprecated since 0.7.0; leftover properties are put into config, since when coming from yaml this is normal.
+ */
+ @Deprecated
+ protected Map<String,Object> leftoverProperties = Maps.newLinkedHashMap();
+
+ protected transient ExecutionContext execution;
+
+ private final BasicConfigurationSupport config = new BasicConfigurationSupport();
+
+ /**
+ * The config values of this entity. Updating this map should be done
+ * via {@link #config()}.
+ *
+ * @deprecated since 0.7.0; use {@link #config()} instead; this field may be made private or deleted in a future release.
+ */
+ @Deprecated
+ protected final ConfigMapImpl configsInternal = new ConfigMapImpl(this);
+
+ /**
+ * @deprecated since 0.7.0; use {@link #getAdjunctType()} instead; this field may be made private or deleted in a future release.
+ */
+ @Deprecated
+ protected final AdjunctType adjunctType = new AdjunctType(this);
+
+ @SetFromFlag
+ protected String name;
+
+ protected transient EntityLocal entity;
+
+ /** not for direct access; refer to as 'subscriptionTracker' via getter so that it is initialized */
+ protected transient SubscriptionTracker _subscriptionTracker;
+
+ private AtomicBoolean destroyed = new AtomicBoolean(false);
+
+ @SetFromFlag(value="uniqueTag")
+ protected String uniqueTag;
+
+ public AbstractEntityAdjunct() {
+ this(Collections.emptyMap());
+ }
+
+ public AbstractEntityAdjunct(@SuppressWarnings("rawtypes") Map properties) {
+ super(properties);
+ _legacyNoConstructionInit = (properties != null) && Boolean.TRUE.equals(properties.get("noConstructionInit"));
+
+ 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);
+ }
+ }
+ }
+
+ /**
+ * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly
+ */
+ @Override
+ @Deprecated
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public AbstractEntityAdjunct configure(Map flags) {
+ // TODO only set on first time through
+ boolean isFirstTime = true;
+
+ // allow config keys, and fields, to be set from these flags if they have a SetFromFlag annotation
+ // or if the value is a config key
+ for (Iterator<Map.Entry> iter = flags.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry entry = iter.next();
+ if (entry.getKey() instanceof ConfigKey) {
+ ConfigKey key = (ConfigKey)entry.getKey();
+ if (adjunctType.getConfigKeys().contains(key)) {
+ setConfig(key, entry.getValue());
+ } else {
+ log.warn("Unknown configuration key {} for policy {}; ignoring", key, this);
+ iter.remove();
+ }
+ }
+ }
+
+ ConfigBag bag = new ConfigBag().putAll(flags);
+ FlagUtils.setFieldsFromFlags(this, bag, isFirstTime);
+ FlagUtils.setAllConfigKeys(this, bag, false);
+ leftoverProperties.putAll(bag.getUnusedConfig());
+
+ //replace properties _contents_ with leftovers so subclasses see leftovers only
+ flags.clear();
+ flags.putAll(leftoverProperties);
+ leftoverProperties = flags;
+
+ if (!truth(name) && flags.containsKey("displayName")) {
+ //TODO inconsistent with entity and location, where name is legacy and displayName is encouraged!
+ //'displayName' is a legacy way to refer to a policy's name
+ Preconditions.checkArgument(flags.get("displayName") instanceof CharSequence, "'displayName' property should be a string");
+ setDisplayName(flags.remove("displayName").toString());
+ }
+
+ // set leftover flags should as config items; particularly useful when these have come from a brooklyn.config map
+ for (Object flag: flags.keySet()) {
+ ConfigKey<Object> key = ConfigKeys.newConfigKey(Object.class, Strings.toString(flag));
+ if (config().getRaw(key).isPresent()) {
+ log.warn("Config '"+flag+"' on "+this+" conflicts with key already set; ignoring");
+ } else {
+ config().set(key, flags.get(flag));
+ }
+ }
+
+ return this;
+ }
+
+ /**
+ * 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.
+ */
+ @Beta
+ protected boolean isLegacyNoConstructionInit() {
+ return _legacyNoConstructionInit;
+ }
+
+ @Override
+ public ConfigurationSupportInternal config() {
+ return config;
+ }
+
+ private class BasicConfigurationSupport implements ConfigurationSupportInternal {
+
+ @Override
+ public <T> T get(ConfigKey<T> key) {
+ return configsInternal.getConfig(key);
+ }
+
+ @Override
+ public <T> T get(HasConfigKey<T> key) {
+ return get(key.getConfigKey());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T set(ConfigKey<T> key, T val) {
+ if (entity != null && isRunning()) {
+ doReconfigureConfig(key, val);
+ }
+ T result = (T) configsInternal.setConfig(key, val);
+ onChanged();
+ return result;
+ }
+
+ @Override
+ public <T> T set(HasConfigKey<T> key, T val) {
+ return setConfig(key.getConfigKey(), val);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T set(ConfigKey<T> key, Task<T> val) {
+ if (entity != null && isRunning()) {
+ // TODO Support for AbstractEntityAdjunct
+ throw new UnsupportedOperationException();
+ }
+ T result = (T) configsInternal.setConfig(key, val);
+ onChanged();
+ return result;
+ }
+
+ @Override
+ public <T> T set(HasConfigKey<T> key, Task<T> val) {
+ return set(key.getConfigKey(), val);
+ }
+
+ @Override
+ public ConfigBag getBag() {
+ return getLocalBag();
+ }
+
+ @Override
+ public ConfigBag getLocalBag() {
+ return ConfigBag.newInstance(configsInternal.getAllConfig());
+ }
+
+ @Override
+ public Maybe<Object> getRaw(ConfigKey<?> key) {
+ return configsInternal.getConfigRaw(key, true);
+ }
+
+ @Override
+ public Maybe<Object> getRaw(HasConfigKey<?> key) {
+ return getRaw(key.getConfigKey());
+ }
+
+ @Override
+ public Maybe<Object> getLocalRaw(ConfigKey<?> key) {
+ return configsInternal.getConfigRaw(key, false);
+ }
+
+ @Override
+ public Maybe<Object> getLocalRaw(HasConfigKey<?> key) {
+ return getLocalRaw(key.getConfigKey());
+ }
+
+ @Override
+ public void addToLocalBag(Map<String, ?> vals) {
+ configsInternal.addToLocalBag(vals);
+ }
+
+ @Override
+ public void removeFromLocalBag(String key) {
+ configsInternal.removeFromLocalBag(key);
+ }
+
+ @Override
+ public void refreshInheritedConfig() {
+ // no-op for location
+ }
+
+ @Override
+ public void refreshInheritedConfigOfChildren() {
+ // no-op for location
+ }
+ }
+
+ public <T> T getConfig(ConfigKey<T> key) {
+ return config().get(key);
+ }
+
+ protected <K> K getRequiredConfig(ConfigKey<K> key) {
+ K result = config().get(key);
+ if (result==null)
+ throw new NullPointerException("Value required for '"+key.getName()+"' in "+this);
+ return result;
+ }
+
+ @Override
+ @Deprecated
+ public <T> T setConfig(ConfigKey<T> key, T val) {
+ return config().set(key, val);
+ }
+
+ // TODO make immutable
+ /** for inspection only */
+ @Beta
+ @Deprecated
+ public ConfigMap getConfigMap() {
+ return configsInternal;
+ }
+
+ /**
+ * Invoked whenever a config change is applied after management is started.
+ * Default implementation throws an exception to disallow the change.
+ * Can be overridden to return (allowing the change) or to make other changes
+ * (if necessary), and of course it can do this selectively and call the super to disallow any others. */
+ protected <T> void doReconfigureConfig(ConfigKey<T> key, T val) {
+ throw new UnsupportedOperationException("reconfiguring "+key+" unsupported for "+this);
+ }
+
+ @Override
+ protected void onTagsChanged() {
+ onChanged();
+ }
+
+ protected abstract void onChanged();
+
+ protected AdjunctType getAdjunctType() {
+ return adjunctType;
+ }
+
+ @Override
+ public String getDisplayName() {
+ if (name!=null && name.length()>0) return name;
+ return getClass().getCanonicalName();
+ }
+
+ public void setDisplayName(String name) {
+ this.name = name;
+ }
+
+ public void setEntity(EntityLocal entity) {
+ if (destroyed.get()) throw new IllegalStateException("Cannot set entity on a destroyed entity adjunct");
+ this.entity = entity;
+ if (entity!=null && getCatalogItemId() == null) {
+ setCatalogItemId(entity.getCatalogItemId());
+ }
+ }
+
+ /** @deprecated since 0.7.0 only {@link AbstractEnricher} has emit convenience */
+ protected <T> void emit(Sensor<T> sensor, Object val) {
+ checkState(entity != null, "entity must first be set");
+ if (val == Entities.UNCHANGED) {
+ return;
+ }
+ if (val == Entities.REMOVE) {
+ ((EntityInternal)entity).removeAttribute((AttributeSensor<T>) sensor);
+ return;
+ }
+
+ T newVal = TypeCoercions.coerce(val, sensor.getTypeToken());
+ if (sensor instanceof AttributeSensor) {
+ entity.setAttribute((AttributeSensor<T>)sensor, newVal);
+ } else {
+ entity.emit(sensor, newVal);
+ }
+ }
+
+ protected synchronized SubscriptionTracker getSubscriptionTracker() {
+ if (_subscriptionTracker!=null) return _subscriptionTracker;
+ if (entity==null) return null;
+ _subscriptionTracker = new SubscriptionTracker(((EntityInternal)entity).getManagementSupport().getSubscriptionContext());
+ return _subscriptionTracker;
+ }
+
+ /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */
+ protected <T> SubscriptionHandle subscribe(Entity producer, Sensor<T> sensor, SensorEventListener<? super T> listener) {
+ if (!checkCanSubscribe()) return null;
+ return getSubscriptionTracker().subscribe(producer, sensor, listener);
+ }
+
+ /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */
+ protected <T> SubscriptionHandle subscribeToMembers(Group producerGroup, Sensor<T> sensor, SensorEventListener<? super T> listener) {
+ if (!checkCanSubscribe(producerGroup)) return null;
+ return getSubscriptionTracker().subscribeToMembers(producerGroup, sensor, listener);
+ }
+
+ /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */
+ protected <T> SubscriptionHandle subscribeToChildren(Entity producerParent, Sensor<T> sensor, SensorEventListener<? super T> listener) {
+ if (!checkCanSubscribe(producerParent)) return null;
+ return getSubscriptionTracker().subscribeToChildren(producerParent, sensor, listener);
+ }
+
+ /** @deprecated since 0.7.0 use {@link #checkCanSubscribe(Entity)} */
+ @Deprecated
+ protected boolean check(Entity requiredEntity) {
+ return checkCanSubscribe(requiredEntity);
+ }
+ /** returns false if deleted, throws exception if invalid state, otherwise true.
+ * okay if entity is not yet managed (but not if entity is no longer managed). */
+ protected boolean checkCanSubscribe(Entity producer) {
+ if (destroyed.get()) return false;
+ if (producer==null) throw new IllegalStateException(this+" given a null target for subscription");
+ if (entity==null) throw new IllegalStateException(this+" cannot subscribe to "+producer+" because it is not associated to an entity");
+ if (((EntityInternal)entity).getManagementSupport().isNoLongerManaged()) throw new IllegalStateException(this+" cannot subscribe to "+producer+" because the associated entity "+entity+" is no longer managed");
+ return true;
+ }
+ protected boolean checkCanSubscribe() {
+ if (destroyed.get()) return false;
+ if (entity==null) throw new IllegalStateException(this+" cannot subscribe because it is not associated to an entity");
+ if (((EntityInternal)entity).getManagementSupport().isNoLongerManaged()) throw new IllegalStateException(this+" cannot subscribe because the associated entity "+entity+" is no longer managed");
+ return true;
+ }
+
+ /**
+ * Unsubscribes the given producer.
+ *
+ * @see SubscriptionContext#unsubscribe(SubscriptionHandle)
+ */
+ protected boolean unsubscribe(Entity producer) {
+ if (destroyed.get()) return false;
+ return getSubscriptionTracker().unsubscribe(producer);
+ }
+
+ /**
+ * Unsubscribes the given producer.
+ *
+ * @see SubscriptionContext#unsubscribe(SubscriptionHandle)
+ */
+ protected boolean unsubscribe(Entity producer, SubscriptionHandle handle) {
+ if (destroyed.get()) return false;
+ return getSubscriptionTracker().unsubscribe(producer, handle);
+ }
+
+ /**
+ * @return a list of all subscription handles
+ */
+ protected Collection<SubscriptionHandle> getAllSubscriptions() {
+ SubscriptionTracker tracker = getSubscriptionTracker();
+ return (tracker != null) ? tracker.getAllSubscriptions() : Collections.<SubscriptionHandle>emptyList();
+ }
+
+ /**
+ * Unsubscribes and clears all managed subscriptions; is called by the owning entity when a policy is removed
+ * and should always be called by any subclasses overriding this method
+ */
+ public void destroy() {
+ destroyed.set(true);
+ SubscriptionTracker tracker = getSubscriptionTracker();
+ if (tracker != null) tracker.unsubscribeAll();
+ }
+
+ @Override
+ public boolean isDestroyed() {
+ return destroyed.get();
+ }
+
+ @Override
+ public boolean isRunning() {
+ return !isDestroyed();
+ }
+
+ @Override
+ public String getUniqueTag() {
+ return uniqueTag;
+ }
+
+ public TagSupport tags() {
+ return new AdjunctTagSupport();
+ }
+
+ public class AdjunctTagSupport extends BasicTagSupport {
+ @Override
+ public Set<Object> getTags() {
+ ImmutableSet.Builder<Object> rb = ImmutableSet.builder().addAll(super.getTags());
+ if (getUniqueTag()!=null) rb.add(getUniqueTag());
+ return rb.build();
+ }
+ public String getUniqueTag() {
+ return AbstractEntityAdjunct.this.getUniqueTag();
+ }
+ public void setUniqueTag(String uniqueTag) {
+ AbstractEntityAdjunct.this.uniqueTag = uniqueTag;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(getClass()).omitNullValues()
+ .add("name", name)
+ .add("uniqueTag", uniqueTag)
+ .add("running", isRunning())
+ .add("entity", entity)
+ .add("id", getId())
+ .toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyDynamicType.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyDynamicType.java
index 315d03d,0000000..a98aead
mode 100644,000000..100644
--- a/core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyDynamicType.java
+++ b/core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyDynamicType.java
@@@ -1,44 -1,0 +1,44 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.policy.basic;
+
+import org.apache.brooklyn.api.policy.Policy;
+import org.apache.brooklyn.api.policy.PolicyType;
+
- import brooklyn.basic.BrooklynDynamicType;
++import org.apache.brooklyn.basic.BrooklynDynamicType;
+
+public class PolicyDynamicType extends BrooklynDynamicType<Policy, AbstractPolicy> {
+
+ public PolicyDynamicType(Class<? extends Policy> type) {
+ super(type);
+ }
+
+ 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/f9b357d7/core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyTypeSnapshot.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyTypeSnapshot.java
index 0e655b6,0000000..6604350
mode 100644,000000..100644
--- a/core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyTypeSnapshot.java
+++ b/core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyTypeSnapshot.java
@@@ -1,40 -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 org.apache.brooklyn.core.policy.basic;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.policy.PolicyType;
+
- import brooklyn.basic.BrooklynTypeSnapshot;
++import org.apache.brooklyn.basic.BrooklynTypeSnapshot;
+import brooklyn.config.ConfigKey;
+
+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/f9b357d7/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
index 4a444c7,0082b9a..5d2e18e
--- a/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
@@@ -24,9 -24,8 +24,9 @@@ import org.apache.brooklyn.api.entity.r
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.management.ManagementContext;
import org.apache.brooklyn.api.mementos.LocationMemento;
+import org.apache.brooklyn.core.util.config.ConfigBag;
- import brooklyn.basic.BrooklynObjectInternal;
+ import org.apache.brooklyn.basic.BrooklynObjectInternal;
import brooklyn.config.ConfigInheritance;
import brooklyn.config.ConfigKey;
import brooklyn.entity.basic.ConfigKeys;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/usage/cli/src/main/java/org/apache/brooklyn/cli/Main.java
----------------------------------------------------------------------
diff --cc usage/cli/src/main/java/org/apache/brooklyn/cli/Main.java
index 95c10a1,8cce298..7293abf
--- a/usage/cli/src/main/java/org/apache/brooklyn/cli/Main.java
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/Main.java
@@@ -66,19 -65,8 +65,9 @@@ import org.apache.brooklyn.cli.CloudExp
import org.apache.brooklyn.cli.CloudExplorer.ComputeListInstancesCommand;
import org.apache.brooklyn.cli.CloudExplorer.ComputeTerminateInstancesCommand;
import org.apache.brooklyn.cli.ItemLister.ListAllCommand;
- import org.apache.brooklyn.cli.CloudExplorer.BlobstoreGetBlobCommand;
- import org.apache.brooklyn.cli.CloudExplorer.BlobstoreListContainerCommand;
- import org.apache.brooklyn.cli.CloudExplorer.BlobstoreListContainersCommand;
- import org.apache.brooklyn.cli.CloudExplorer.ComputeDefaultTemplateCommand;
- import org.apache.brooklyn.cli.CloudExplorer.ComputeGetImageCommand;
- import org.apache.brooklyn.cli.CloudExplorer.ComputeListHardwareProfilesCommand;
- import org.apache.brooklyn.cli.CloudExplorer.ComputeListImagesCommand;
- import org.apache.brooklyn.cli.CloudExplorer.ComputeListInstancesCommand;
- import org.apache.brooklyn.cli.CloudExplorer.ComputeTerminateInstancesCommand;
- import org.apache.brooklyn.cli.ItemLister.ListAllCommand;
import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
import org.apache.brooklyn.core.management.ha.OsgiManager;
+import org.apache.brooklyn.core.util.ResourceUtils;
import brooklyn.entity.basic.AbstractApplication;
import brooklyn.entity.basic.AbstractEntity;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/usage/qa/src/test/java/org/apache/brooklyn/qa/brooklynnode/SoftlayerObtainPrivateLiveTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/PolicyConfigResource.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
----------------------------------------------------------------------