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/15 15:33:12 UTC
[10/33] incubator-brooklyn git commit: [BROOKLYN-162] Refactor
package in ./core/management
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/main/java/org/apache/brooklyn/core/management/internal/NonDeploymentManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/NonDeploymentManagementContext.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/NonDeploymentManagementContext.java
new file mode 100644
index 0000000..9d98792
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/NonDeploymentManagementContext.java
@@ -0,0 +1,639 @@
+/*
+ * 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.management.internal;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.api.basic.BrooklynObject;
+import org.apache.brooklyn.api.catalog.BrooklynCatalog;
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.entity.Effector;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.drivers.EntityDriverManager;
+import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager;
+import org.apache.brooklyn.api.entity.rebind.ChangeListener;
+import org.apache.brooklyn.api.entity.rebind.PersistenceExceptionHandler;
+import org.apache.brooklyn.api.entity.rebind.RebindExceptionHandler;
+import org.apache.brooklyn.api.entity.rebind.RebindManager;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.management.AccessController;
+import org.apache.brooklyn.api.management.EntityManager;
+import org.apache.brooklyn.api.management.ExecutionContext;
+import org.apache.brooklyn.api.management.ExecutionManager;
+import org.apache.brooklyn.api.management.LocationManager;
+import org.apache.brooklyn.api.management.SubscriptionContext;
+import org.apache.brooklyn.api.management.Task;
+import org.apache.brooklyn.api.management.entitlement.EntitlementManager;
+import org.apache.brooklyn.api.management.ha.HighAvailabilityManager;
+import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
+import org.apache.brooklyn.api.management.ha.ManagementNodeState;
+import org.apache.brooklyn.api.management.ha.ManagementPlaneSyncRecord;
+import org.apache.brooklyn.api.management.ha.ManagementPlaneSyncRecordPersister;
+import org.apache.brooklyn.api.mementos.BrooklynMementoPersister;
+import org.apache.brooklyn.api.mementos.BrooklynMementoRawData;
+import org.apache.brooklyn.core.management.entitlement.Entitlements;
+import org.apache.brooklyn.core.management.ha.OsgiManager;
+
+import brooklyn.catalog.internal.CatalogInitialization;
+import brooklyn.config.BrooklynProperties;
+import brooklyn.config.StringConfigMap;
+import brooklyn.entity.basic.AbstractEntity;
+import brooklyn.entity.proxying.InternalEntityFactory;
+import brooklyn.entity.proxying.InternalLocationFactory;
+import brooklyn.entity.proxying.InternalPolicyFactory;
+import brooklyn.internal.storage.BrooklynStorage;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Objects;
+
+public class NonDeploymentManagementContext implements ManagementContextInternal {
+
+ private static final Logger log = LoggerFactory.getLogger(NonDeploymentManagementContext.class);
+
+ public enum NonDeploymentManagementContextMode {
+ PRE_MANAGEMENT,
+ MANAGEMENT_REBINDING,
+ MANAGEMENT_STARTING,
+ MANAGEMENT_STARTED,
+ MANAGEMENT_STOPPING,
+ MANAGEMENT_STOPPED;
+
+ public boolean isPreManaged() {
+ return this == PRE_MANAGEMENT || this == MANAGEMENT_REBINDING;
+ }
+ }
+
+ private final AbstractEntity entity;
+ private NonDeploymentManagementContextMode mode;
+ private ManagementContextInternal initialManagementContext;
+
+ private final QueueingSubscriptionManager qsm;
+ private final BasicSubscriptionContext subscriptionContext;
+ private NonDeploymentEntityManager entityManager;
+ private NonDeploymentLocationManager locationManager;
+ private NonDeploymentAccessManager accessManager;
+ private NonDeploymentUsageManager usageManager;
+ private EntitlementManager entitlementManager;;
+
+ public NonDeploymentManagementContext(AbstractEntity entity, NonDeploymentManagementContextMode mode) {
+ this.entity = checkNotNull(entity, "entity");
+ this.mode = checkNotNull(mode, "mode");
+ qsm = new QueueingSubscriptionManager();
+ subscriptionContext = new BasicSubscriptionContext(qsm, entity);
+ entityManager = new NonDeploymentEntityManager(null);
+ locationManager = new NonDeploymentLocationManager(null);
+ accessManager = new NonDeploymentAccessManager(null);
+ usageManager = new NonDeploymentUsageManager(null);
+
+ // TODO might need to be some kind of "system" which can see that the system is running at this point
+ // though quite possibly we are entirely behind the auth-wall at this point
+ entitlementManager = Entitlements.minimal();
+ }
+
+ @Override
+ public String getManagementPlaneId() {
+ return (initialManagementContext == null) ? null : initialManagementContext.getManagementPlaneId();
+ }
+
+ @Override
+ public String getManagementNodeId() {
+ return (initialManagementContext == null) ? null : initialManagementContext.getManagementNodeId();
+ }
+
+ @Override
+ public Maybe<URI> getManagementNodeUri() {
+ return (initialManagementContext == null) ? Maybe.<URI>absent() : initialManagementContext.getManagementNodeUri();
+ }
+
+ public void setManagementContext(ManagementContextInternal val) {
+ this.initialManagementContext = checkNotNull(val, "initialManagementContext");
+ this.entityManager = new NonDeploymentEntityManager(val);
+ this.locationManager = new NonDeploymentLocationManager(val);
+ this.accessManager = new NonDeploymentAccessManager(val);
+ this.usageManager = new NonDeploymentUsageManager(val);
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this).add("entity", entity.getId()).add("mode", mode).toString();
+ }
+
+ public void setMode(NonDeploymentManagementContextMode mode) {
+ this.mode = checkNotNull(mode, "mode");
+ }
+ public NonDeploymentManagementContextMode getMode() {
+ return mode;
+ }
+
+ @Override
+ public Collection<Application> getApplications() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean isRunning() {
+ // Assume that the real management context has not been terminated, so always true
+ return true;
+ }
+
+ @Override
+ public boolean isStartupComplete() {
+ // This mgmt context is only used by items who are not yet fully started.
+ // It's slightly misleading as this does not refer to the main mgmt context.
+ // OTOH it probably won't be used. TBC. -Alex, Apr 2015
+ return false;
+ }
+
+ @Override
+ public InternalEntityFactory getEntityFactory() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getEntityFactory();
+ }
+
+ @Override
+ public InternalLocationFactory getLocationFactory() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getLocationFactory();
+ }
+
+ @Override
+ public InternalPolicyFactory getPolicyFactory() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getPolicyFactory();
+ }
+
+ @Override
+ public EntityManager getEntityManager() {
+ return entityManager;
+ }
+
+ @Override
+ public LocationManager getLocationManager() {
+ return locationManager;
+ }
+
+ @Override
+ public AccessManager getAccessManager() {
+ return accessManager;
+ }
+
+ @Override
+ public UsageManager getUsageManager() {
+ return usageManager;
+ }
+
+ @Override
+ public Maybe<OsgiManager> getOsgiManager() {
+ return Maybe.absent();
+ }
+
+ @Override
+ public AccessController getAccessController() {
+ return getAccessManager().getAccessController();
+ }
+
+ @Override
+ public ExecutionManager getExecutionManager() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getExecutionManager();
+ }
+
+ @Override
+ public QueueingSubscriptionManager getSubscriptionManager() {
+ return qsm;
+ }
+
+ @Override
+ public synchronized SubscriptionContext getSubscriptionContext(Entity entity) {
+ if (!this.entity.equals(entity)) throw new IllegalStateException("Non-deployment context "+this+" can only use a single Entity: has "+this.entity+", but passed "+entity);
+ if (mode==NonDeploymentManagementContextMode.MANAGEMENT_STOPPED)
+ throw new IllegalStateException("Entity "+entity+" is no longer managed; subscription context not available");
+ return subscriptionContext;
+ }
+
+ @Override
+ public ExecutionContext getExecutionContext(Entity entity) {
+ if (!this.entity.equals(entity)) throw new IllegalStateException("Non-deployment context "+this+" can only use a single Entity: has "+this.entity+", but passed "+entity);
+ if (mode==NonDeploymentManagementContextMode.MANAGEMENT_STOPPED)
+ throw new IllegalStateException("Entity "+entity+" is no longer managed; execution context not available");
+ checkInitialManagementContextReal();
+ return initialManagementContext.getExecutionContext(entity);
+ }
+
+ @Override
+ public ExecutionContext getServerExecutionContext() {
+ return initialManagementContext.getServerExecutionContext();
+ }
+
+ // TODO the methods below should delegate to the application?
+ @Override
+ public EntityDriverManager getEntityDriverManager() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getEntityDriverManager();
+ }
+
+ @Override
+ public DownloadResolverManager getEntityDownloadsManager() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getEntityDownloadsManager();
+ }
+
+ @Override
+ public StringConfigMap getConfig() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getConfig();
+ }
+
+ @Override
+ public BrooklynProperties getBrooklynProperties() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getBrooklynProperties();
+ }
+
+ @Override
+ public BrooklynStorage getStorage() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getStorage();
+ }
+
+ @Override
+ public RebindManager getRebindManager() {
+ // There was a race where EffectorUtils on invoking an effector calls:
+ // mgmtSupport.getEntityChangeListener().onEffectorCompleted(eff);
+ // but where the entity/app may be being unmanaged concurrently (e.g. calling app.stop()).
+ // So now we allow the change-listener to be called.
+
+ if (isInitialManagementContextReal()) {
+ return initialManagementContext.getRebindManager();
+ } else {
+ return new NonDeploymentRebindManager();
+ }
+ }
+
+ @Override
+ public HighAvailabilityManager getHighAvailabilityManager() {
+ if (isInitialManagementContextReal()) {
+ return initialManagementContext.getHighAvailabilityManager();
+ } else {
+ return new NonDeploymentHighAvailabilityManager();
+ }
+ }
+
+ @Override
+ public LocationRegistry getLocationRegistry() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getLocationRegistry();
+ }
+
+ @Override
+ public BrooklynCatalog getCatalog() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getCatalog();
+ }
+
+ @Override
+ public ClassLoader getCatalogClassLoader() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getCatalogClassLoader();
+ }
+
+ @Override
+ public EntitlementManager getEntitlementManager() {
+ return entitlementManager;
+ }
+
+ @Override
+ public <T> T invokeEffectorMethodSync(final Entity entity, final Effector<T> eff, final Object args) throws ExecutionException {
+ throw new IllegalStateException("Non-deployment context "+this+" is not valid for this operation: cannot invoke effector "+eff+" on entity "+entity);
+ }
+
+ @Override
+ public <T> Task<T> invokeEffector(final Entity entity, final Effector<T> eff, @SuppressWarnings("rawtypes") final Map parameters) {
+ throw new IllegalStateException("Non-deployment context "+this+" is not valid for this operation: cannot invoke effector "+eff+" on entity "+entity);
+ }
+
+ @Override
+ public ClassLoader getBaseClassLoader() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getBaseClassLoader();
+ }
+
+ @Override
+ public Iterable<URL> getBaseClassPathForScanning() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getBaseClassPathForScanning();
+ }
+
+ @Override
+ public void addEntitySetListener(CollectionChangeListener<Entity> listener) {
+ checkInitialManagementContextReal();
+ initialManagementContext.addEntitySetListener(listener);
+ }
+
+ @Override
+ public void removeEntitySetListener(CollectionChangeListener<Entity> listener) {
+ checkInitialManagementContextReal();
+ initialManagementContext.removeEntitySetListener(listener);
+ }
+
+ @Override
+ public void terminate() {
+ if (isInitialManagementContextReal()) {
+ initialManagementContext.terminate();
+ } else {
+ // no-op; the non-deployment management context has nothing needing terminated
+ }
+ }
+
+ @Override
+ public long getTotalEffectorInvocations() {
+ if (isInitialManagementContextReal()) {
+ return initialManagementContext.getTotalEffectorInvocations();
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public void setBaseClassPathForScanning(Iterable<URL> urls) {
+ checkInitialManagementContextReal();
+ initialManagementContext.setBaseClassPathForScanning(urls);
+ }
+
+ @Override
+ public void setManagementNodeUri(URI uri) {
+ checkInitialManagementContextReal();
+ initialManagementContext.setManagementNodeUri(uri);
+ }
+
+ @Override
+ public void prePreManage(Entity entity) {
+ // should throw? but in 0.7.0-SNAPSHOT it was no-op
+ log.warn("Ignoring call to prePreManage("+entity+") on "+this);
+ }
+
+ @Override
+ public void prePreManage(Location location) {
+ // should throw? but in 0.7.0-SNAPSHOT it was no-op
+ log.warn("Ignoring call to prePreManage("+location+") on "+this);
+ }
+
+ private boolean isInitialManagementContextReal() {
+ return (initialManagementContext != null && !(initialManagementContext instanceof NonDeploymentManagementContext));
+ }
+
+ private void checkInitialManagementContextReal() {
+ if (!isInitialManagementContextReal()) {
+ throw new IllegalStateException("Non-deployment context "+this+" is not valid for this operation.");
+ }
+ }
+
+ @Override
+ public void reloadBrooklynProperties() {
+ checkInitialManagementContextReal();
+ initialManagementContext.reloadBrooklynProperties();
+ }
+
+ @Override
+ public void addPropertiesReloadListener(PropertiesReloadListener listener) {
+ checkInitialManagementContextReal();
+ initialManagementContext.addPropertiesReloadListener(listener);
+ }
+
+ @Override
+ public void removePropertiesReloadListener(PropertiesReloadListener listener) {
+ checkInitialManagementContextReal();
+ initialManagementContext.removePropertiesReloadListener(listener);
+ }
+
+ @Override
+ public BrooklynObject lookup(String id) {
+ checkInitialManagementContextReal();
+ return initialManagementContext.lookup(id);
+ }
+
+ @Override
+ public <T extends BrooklynObject> T lookup(String id, Class<T> type) {
+ checkInitialManagementContextReal();
+ return initialManagementContext.lookup(id, type);
+ }
+
+ @Override
+ public List<Throwable> errors() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.errors();
+ }
+
+ @Override
+ public CatalogInitialization getCatalogInitialization() {
+ checkInitialManagementContextReal();
+ return initialManagementContext.getCatalogInitialization();
+ }
+
+ @Override
+ public void setCatalogInitialization(CatalogInitialization catalogInitialization) {
+ checkInitialManagementContextReal();
+ initialManagementContext.setCatalogInitialization(catalogInitialization);
+ }
+
+ /**
+ * For when the initial management context is not "real"; the changeListener is a no-op, but everything else forbidden.
+ *
+ * @author aled
+ */
+ private class NonDeploymentRebindManager implements RebindManager {
+
+ @Override
+ public ChangeListener getChangeListener() {
+ return ChangeListener.NOOP;
+ }
+
+ @Override
+ public void setPersister(BrooklynMementoPersister persister) {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public void setPersister(BrooklynMementoPersister persister, PersistenceExceptionHandler exceptionHandler) {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public BrooklynMementoPersister getPersister() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public List<Application> rebind() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public List<Application> rebind(ClassLoader classLoader) {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public List<Application> rebind(ClassLoader classLoader, RebindExceptionHandler exceptionHandler) {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public List<Application> rebind(ClassLoader classLoader, RebindExceptionHandler exceptionHandler, ManagementNodeState mode) {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public void startPersistence() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public void stopPersistence() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public void startReadOnly(ManagementNodeState state) {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public void stopReadOnly() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public void start() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public void stop() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public void waitForPendingComplete(Duration timeout, boolean canTrigger) throws InterruptedException, TimeoutException {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public void forcePersistNow() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public void forcePersistNow(boolean full, PersistenceExceptionHandler exceptionHandler) {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public BrooklynMementoRawData retrieveMementoRawData() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public boolean isAwaitingInitialRebind() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+
+ @Override
+ public Map<String, Object> getMetrics() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ }
+
+ /**
+ * For when the initial management context is not "real".
+ *
+ * @author aled
+ */
+ private class NonDeploymentHighAvailabilityManager implements HighAvailabilityManager {
+ @Override
+ public ManagementNodeState getNodeState() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public boolean isRunning() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public HighAvailabilityManager setPersister(ManagementPlaneSyncRecordPersister persister) {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public void disabled() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public void start(HighAvailabilityMode startMode) {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public void stop() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public ManagementPlaneSyncRecordPersister getPersister() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public ManagementPlaneSyncRecord getLastManagementPlaneSyncRecord() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public ManagementPlaneSyncRecord loadManagementPlaneSyncRecord(boolean x) {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public void changeMode(HighAvailabilityMode startMode) {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public void setPriority(long priority) {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public long getPriority() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public Map<String, Object> getMetrics() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public void publishClearNonMaster() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ @Override
+ public long getLastStateChange() {
+ throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/main/java/org/apache/brooklyn/core/management/internal/NonDeploymentUsageManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/NonDeploymentUsageManager.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/NonDeploymentUsageManager.java
new file mode 100644
index 0000000..55a4a78
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/NonDeploymentUsageManager.java
@@ -0,0 +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.core.management.internal;
+
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.core.management.usage.ApplicationUsage;
+import org.apache.brooklyn.core.management.usage.LocationUsage;
+
+import brooklyn.entity.basic.Lifecycle;
+
+import com.google.common.base.Predicate;
+
+
+public class NonDeploymentUsageManager implements UsageManager {
+
+ // TODO All the `isInitialManagementContextReal()` code-checks is a code-smell.
+ // Expect we can delete a lot of this once we guarantee that all entities are
+ // instantiated via EntitySpec / EntityManager. Until then, we'll live with this.
+
+ private final ManagementContextInternal initialManagementContext;
+
+ public NonDeploymentUsageManager(ManagementContextInternal initialManagementContext) {
+ this.initialManagementContext = initialManagementContext;
+ }
+
+ private boolean isInitialManagementContextReal() {
+ return (initialManagementContext != null && !(initialManagementContext instanceof NonDeploymentManagementContext));
+ }
+
+ @Override
+ public void recordApplicationEvent(Application app, Lifecycle state) {
+ if (isInitialManagementContextReal()) {
+ initialManagementContext.getUsageManager().recordApplicationEvent(app, state);
+ } else {
+ throw new IllegalStateException("Non-deployment context "+this+" is not valid for this operation");
+ }
+ }
+
+ @Override
+ public void recordLocationEvent(Location loc, Lifecycle state) {
+ if (isInitialManagementContextReal()) {
+ initialManagementContext.getUsageManager().recordLocationEvent(loc, state);
+ } else {
+ throw new IllegalStateException("Non-deployment context "+this+" is not valid for this operation");
+ }
+ }
+
+ @Override
+ public LocationUsage getLocationUsage(String locationId) {
+ if (isInitialManagementContextReal()) {
+ return initialManagementContext.getUsageManager().getLocationUsage(locationId);
+ } else {
+ throw new IllegalStateException("Non-deployment context "+this+" is not valid for this operation");
+ }
+ }
+
+ @Override
+ public Set<LocationUsage> getLocationUsage(Predicate<? super LocationUsage> filter) {
+ if (isInitialManagementContextReal()) {
+ return initialManagementContext.getUsageManager().getLocationUsage(filter);
+ } else {
+ throw new IllegalStateException("Non-deployment context "+this+" is not valid for this operation");
+ }
+ }
+
+ @Override
+ public ApplicationUsage getApplicationUsage(String appId) {
+ if (isInitialManagementContextReal()) {
+ return initialManagementContext.getUsageManager().getApplicationUsage(appId);
+ } else {
+ throw new IllegalStateException("Non-deployment context "+this+" is not valid for this operation");
+ }
+ }
+
+ @Override
+ public Set<ApplicationUsage> getApplicationUsage(Predicate<? super ApplicationUsage> filter) {
+ if (isInitialManagementContextReal()) {
+ return initialManagementContext.getUsageManager().getApplicationUsage(filter);
+ } else {
+ throw new IllegalStateException("Non-deployment context "+this+" is not valid for this operation");
+ }
+ }
+
+ @Override
+ @Deprecated
+ public void addUsageListener(org.apache.brooklyn.core.management.internal.UsageManager.UsageListener listener) {
+ addUsageListener(new org.apache.brooklyn.core.management.internal.UsageManager.UsageListener.UsageListenerAdapter(listener));
+ }
+
+ @Override
+ @Deprecated
+ public void removeUsageListener(org.apache.brooklyn.core.management.internal.UsageManager.UsageListener listener) {
+ removeUsageListener(new org.apache.brooklyn.core.management.internal.UsageManager.UsageListener.UsageListenerAdapter(listener));
+ }
+
+ @Override
+ public void addUsageListener(org.apache.brooklyn.core.management.internal.UsageListener listener) {
+ if (isInitialManagementContextReal()) {
+ initialManagementContext.getUsageManager().addUsageListener(listener);
+ } else {
+ throw new IllegalStateException("Non-deployment context "+this+" is not valid for this operation");
+ }
+ }
+
+ @Override
+ public void removeUsageListener(org.apache.brooklyn.core.management.internal.UsageListener listener) {
+ if (isInitialManagementContextReal()) {
+ initialManagementContext.getUsageManager().removeUsageListener(listener);
+ } else {
+ throw new IllegalStateException("Non-deployment context "+this+" is not valid for this operation");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/main/java/org/apache/brooklyn/core/management/internal/QueueingSubscriptionManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/QueueingSubscriptionManager.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/QueueingSubscriptionManager.java
new file mode 100644
index 0000000..8f54d95
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/QueueingSubscriptionManager.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.management.internal;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.event.Sensor;
+import org.apache.brooklyn.api.event.SensorEvent;
+import org.apache.brooklyn.api.management.SubscriptionHandle;
+
+import com.google.common.base.Objects;
+
+@SuppressWarnings("rawtypes")
+public class QueueingSubscriptionManager extends AbstractSubscriptionManager {
+
+ static class QueuedSubscription<T> {
+ Map<String, Object> flags;
+ Subscription<T> s;
+ }
+
+ public AbstractSubscriptionManager delegate = null;
+ public boolean useDelegateForSubscribing = false;
+ public boolean useDelegateForPublishing = false;
+
+ List<QueuedSubscription> queuedSubscriptions = new ArrayList<QueuedSubscription>();
+ List<SensorEvent> queuedSensorEvents = new ArrayList<SensorEvent>();
+
+ @Override
+ protected synchronized <T> SubscriptionHandle subscribe(Map<String, Object> flags, Subscription<T> s) {
+ if (useDelegateForSubscribing)
+ return delegate.subscribe(flags, s);
+
+ QueuedSubscription<T> qs = new QueuedSubscription<T>();
+ qs.flags = flags;
+ s.subscriber = getSubscriber(flags, s);
+ qs.s = s;
+ queuedSubscriptions.add(qs);
+ return s;
+ }
+
+ @Override
+ public synchronized <T> void publish(SensorEvent<T> event) {
+ if (useDelegateForPublishing) {
+ delegate.publish(event);
+ return;
+ }
+
+ queuedSensorEvents.add(event);
+ }
+
+ public void setDelegate(AbstractSubscriptionManager delegate) {
+ this.delegate = delegate;
+ }
+
+ @SuppressWarnings("unchecked")
+ public synchronized void startDelegatingForSubscribing() {
+ assert delegate!=null;
+ for (QueuedSubscription s: queuedSubscriptions) {
+ delegate.subscribe(s.flags, s.s);
+ }
+ queuedSubscriptions.clear();
+ useDelegateForSubscribing = true;
+ }
+
+ @SuppressWarnings("unchecked")
+ public synchronized void startDelegatingForPublishing() {
+ assert delegate!=null;
+ for (SensorEvent evt: queuedSensorEvents) {
+ delegate.publish(evt);
+ }
+ queuedSensorEvents.clear();
+ useDelegateForPublishing = true;
+ }
+
+ public synchronized void stopDelegatingForSubscribing() {
+ useDelegateForSubscribing = false;
+ }
+
+ public synchronized void stopDelegatingForPublishing() {
+ useDelegateForPublishing = false;
+ }
+
+ @Override
+ public synchronized boolean unsubscribe(SubscriptionHandle subscriptionId) {
+ if (useDelegateForSubscribing)
+ return delegate.unsubscribe(subscriptionId);
+
+ Iterator<QueuedSubscription> qi = queuedSubscriptions.iterator();
+ while (qi.hasNext()) {
+ QueuedSubscription q = qi.next();
+ if (Objects.equal(subscriptionId, q.s)) {
+ qi.remove();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public synchronized Set<SubscriptionHandle> getSubscriptionsForSubscriber(Object subscriber) {
+ if (useDelegateForSubscribing)
+ return delegate.getSubscriptionsForSubscriber(subscriber);
+
+ Set<SubscriptionHandle> result = new LinkedHashSet<SubscriptionHandle>();
+ for (QueuedSubscription q: queuedSubscriptions) {
+ if (Objects.equal(subscriber, getSubscriber(q.flags, q.s))) result.add(q.s);
+ }
+ return result;
+ }
+
+ @Override
+ public synchronized Set<SubscriptionHandle> getSubscriptionsForEntitySensor(Entity source, Sensor<?> sensor) {
+ if (useDelegateForSubscribing)
+ return delegate.getSubscriptionsForEntitySensor(source, sensor);
+
+ Set<SubscriptionHandle> result = new LinkedHashSet<SubscriptionHandle>();
+ for (QueuedSubscription q: queuedSubscriptions) {
+ if ((q.s.sensor==null || Objects.equal(q.s.sensor, sensor)) &&
+ (q.s.producer==null || Objects.equal(q.s.producer, sensor)))
+ result.add(q.s);
+ }
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/main/java/org/apache/brooklyn/core/management/internal/Subscription.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/Subscription.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/Subscription.java
new file mode 100644
index 0000000..acd30c3
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/Subscription.java
@@ -0,0 +1,66 @@
+/*
+ * 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.management.internal;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.event.Sensor;
+import org.apache.brooklyn.api.event.SensorEvent;
+import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.management.SubscriptionHandle;
+
+import brooklyn.util.text.Identifiers;
+
+import com.google.common.base.Predicate;
+
+class Subscription<T> implements SubscriptionHandle {
+ public final String id = Identifiers.makeRandomId(8);
+
+ public Object subscriber;
+ public Object subscriberExecutionManagerTag;
+ /** whether the tag was supplied by user, in which case we should not clear execution semantics */
+ public boolean subscriberExecutionManagerTagSupplied;
+ public final Entity producer;
+ public final Sensor<T> sensor;
+ public final SensorEventListener<? super T> listener;
+ public Map<String,Object> flags;
+ public Predicate<SensorEvent<T>> eventFilter;
+
+ public Subscription(Entity producer, Sensor<T> sensor, SensorEventListener<? super T> listener) {
+ this.producer = producer;
+ this.sensor = sensor;
+ this.listener = listener;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return (other instanceof Subscription && ((Subscription<?>)other).id==id);
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "Subscription["+id+";"+subscriber+"@"+LocalSubscriptionManager.makeEntitySensorToken(producer,sensor)+"]";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/main/java/org/apache/brooklyn/core/management/internal/SubscriptionTracker.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/SubscriptionTracker.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/SubscriptionTracker.java
new file mode 100644
index 0000000..acc0cb6
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/SubscriptionTracker.java
@@ -0,0 +1,137 @@
+/*
+ * 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.management.internal;
+
+import java.util.Collection;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.Group;
+import org.apache.brooklyn.api.event.Sensor;
+import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.management.SubscriptionContext;
+import org.apache.brooklyn.api.management.SubscriptionHandle;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.SetMultimap;
+
+/**
+ * Tracks subscriptions associated that are registered with particular entities. Gives utilities for unsubscribing from all
+ * subscriptions on a given entity, etc.
+ */
+public class SubscriptionTracker {
+
+ // This class is thread-safe. All modifications to subscriptions are synchronized on the
+ // "subscriptions" field. However, calls to alien code (i.e. context.subscribe etc) is
+ // done without holding the lock.
+ //
+ // If two threads do subscribe() and unsubscribeAll() concurrently, then it's non-derministic
+ // whether the subscription will be in place at the end (but that's unavoidable). However, it
+ // is guaranteed that the internal state of the SubscriptionTracker will be consistent: if
+ // the "subscriptions" includes the new subscription then that subscription will really exist,
+ // and vice versa.
+
+ protected SubscriptionContext context;
+
+ private final SetMultimap<Entity, SubscriptionHandle> subscriptions = HashMultimap.create();
+
+ public SubscriptionTracker(SubscriptionContext subscriptionContext) {
+ this.context = subscriptionContext;
+ }
+
+ /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */
+ public <T> SubscriptionHandle subscribe(Entity producer, Sensor<T> sensor, SensorEventListener<? super T> listener) {
+ SubscriptionHandle handle = context.subscribe(producer, sensor, listener);
+ synchronized (subscriptions) {
+ subscriptions.put(producer, handle);
+ }
+ return handle;
+ }
+
+ /** @see SubscriptionContext#subscribeToChildren(Entity, Sensor, SensorEventListener) */
+ public <T> SubscriptionHandle subscribeToChildren(Entity parent, Sensor<T> sensor, SensorEventListener<? super T> listener) {
+ SubscriptionHandle handle = context.subscribeToChildren(parent, sensor, listener);
+ synchronized (subscriptions) {
+ subscriptions.put(parent, handle);
+ }
+ return handle;
+ }
+
+ /**
+ * @see SubscriptionContext#subscribeToMembers(Group, Sensor, SensorEventListener)
+ */
+ public <T> SubscriptionHandle subscribeToMembers(Group parent, Sensor<T> sensor, SensorEventListener<? super T> listener) {
+ SubscriptionHandle handle = context.subscribeToMembers(parent, sensor, listener);
+ synchronized (subscriptions) {
+ subscriptions.put(parent, handle);
+ }
+ return handle;
+ }
+
+ /**
+ * Unsubscribes the given producer.
+ *
+ * @see SubscriptionContext#unsubscribe(SubscriptionHandle)
+ */
+ public boolean unsubscribe(Entity producer) {
+ Collection<SubscriptionHandle> handles;
+ synchronized (subscriptions) {
+ handles = subscriptions.removeAll(producer);
+ }
+ if (handles != null) {
+ for (SubscriptionHandle handle : handles) {
+ context.unsubscribe(handle);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Unsubscribes the given producer.
+ *
+ * @see SubscriptionContext#unsubscribe(SubscriptionHandle)
+ */
+ public boolean unsubscribe(Entity producer, SubscriptionHandle handle) {
+ synchronized (subscriptions) {
+ subscriptions.remove(producer, handle);
+ }
+ return context.unsubscribe(handle);
+ }
+
+ /**
+ * @return an ordered list of all subscription handles
+ */
+ public Collection<SubscriptionHandle> getAllSubscriptions() {
+ synchronized (subscriptions) {
+ return ImmutableList.copyOf(subscriptions.values());
+ }
+ }
+
+ public void unsubscribeAll() {
+ Collection<SubscriptionHandle> subscriptionsSnapshot;
+ synchronized (subscriptions) {
+ subscriptionsSnapshot = ImmutableList.copyOf(subscriptions.values());
+ subscriptions.clear();
+ }
+ for (SubscriptionHandle s: subscriptionsSnapshot) {
+ context.unsubscribe(s);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/main/java/org/apache/brooklyn/core/management/internal/UsageListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/UsageListener.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/UsageListener.java
new file mode 100644
index 0000000..566c0f0
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/UsageListener.java
@@ -0,0 +1,103 @@
+/*
+ * 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.management.internal;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.core.management.usage.ApplicationUsage.ApplicationEvent;
+import org.apache.brooklyn.core.management.usage.LocationUsage.LocationEvent;
+
+import com.google.common.annotations.Beta;
+
+@Beta
+public interface UsageListener {
+
+ /**
+ * A no-op implementation of {@link UsageListener}, for users to extend.
+ *
+ * Users are encouraged to extend this class, which will shield the user
+ * from the addition of other usage event methods being added. If additional
+ * methods are added in a future release, a no-op implementation will be
+ * added to this class.
+ */
+ @Beta
+ public static class BasicUsageListener implements UsageListener {
+ @Override
+ public void onApplicationEvent(ApplicationMetadata app, ApplicationEvent event) {
+ }
+
+ @Override public void onLocationEvent(LocationMetadata loc, LocationEvent event) {
+ }
+ }
+
+ /**
+ * Users should never implement this interface directly; methods may be added in future releases
+ * without notice.
+ */
+ @Beta
+ public interface ApplicationMetadata {
+ /**
+ * Access the application directly with caution: by the time the listener fires,
+ * the application may no longer be managed.
+ */
+ @Beta
+ Application getApplication();
+
+ String getApplicationId();
+
+ String getApplicationName();
+
+ String getEntityType();
+
+ String getCatalogItemId();
+
+ Map<String, String> getMetadata();
+ }
+
+ /**
+ * Users should never implement this interface directly; methods may be added in future releases
+ * without notice.
+ */
+ @Beta
+ public interface LocationMetadata {
+ /**
+ * Access the location directly with caution: by the time the listener fires,
+ * the location may no longer be managed.
+ */
+ @Beta
+ Location getLocation();
+
+ String getLocationId();
+
+ Map<String, String> getMetadata();
+ }
+
+ public static final UsageListener NOOP = new UsageListener() {
+ @Override public void onApplicationEvent(ApplicationMetadata app, ApplicationEvent event) {}
+ @Override public void onLocationEvent(LocationMetadata loc, LocationEvent event) {}
+ };
+
+ @Beta
+ void onApplicationEvent(ApplicationMetadata app, ApplicationEvent event);
+
+ @Beta
+ void onLocationEvent(LocationMetadata loc, LocationEvent event);
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/main/java/org/apache/brooklyn/core/management/internal/UsageManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/UsageManager.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/UsageManager.java
new file mode 100644
index 0000000..75c242a
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/UsageManager.java
@@ -0,0 +1,166 @@
+/*
+ * 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.management.internal;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.core.management.usage.ApplicationUsage;
+import org.apache.brooklyn.core.management.usage.LocationUsage;
+import org.apache.brooklyn.core.management.usage.ApplicationUsage.ApplicationEvent;
+import org.apache.brooklyn.core.management.usage.LocationUsage.LocationEvent;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Lifecycle;
+import brooklyn.util.time.Duration;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.reflect.TypeToken;
+
+@Beta
+public interface UsageManager {
+
+ @SuppressWarnings("serial")
+ public static final ConfigKey<List<org.apache.brooklyn.core.management.internal.UsageListener>> USAGE_LISTENERS = ConfigKeys.newConfigKey(
+ new TypeToken<List<org.apache.brooklyn.core.management.internal.UsageListener>>() {},
+ "brooklyn.usageManager.listeners", "Optional usage listeners (i.e. for metering)",
+ ImmutableList.<org.apache.brooklyn.core.management.internal.UsageListener>of());
+
+ public static final ConfigKey<Duration> USAGE_LISTENER_TERMINATION_TIMEOUT = ConfigKeys.newConfigKey(
+ Duration.class,
+ "brooklyn.usageManager.listeners.timeout",
+ "Timeout on termination, to wait for queue of usage listener events to be processed",
+ Duration.TEN_SECONDS);
+
+ /**
+ * @since 0.7.0
+ * @deprecated since 0.7.0; use {@link org.apache.brooklyn.core.management.internal.UsageListener}; see {@link UsageListenerAdapter}
+ */
+ public interface UsageListener {
+ public static final UsageListener NOOP = new UsageListener() {
+ @Override public void onApplicationEvent(String applicationId, String applicationName, String entityType,
+ String catalogItemId, Map<String, String> metadata, ApplicationEvent event) {}
+ @Override public void onLocationEvent(String locationId, Map<String, String> metadata, LocationEvent event) {}
+ };
+
+ public static class UsageListenerAdapter implements org.apache.brooklyn.core.management.internal.UsageListener {
+ private final UsageListener listener;
+
+ public UsageListenerAdapter(UsageListener listener) {
+ this.listener = checkNotNull(listener, "listener");
+ }
+
+ @Override
+ public void onApplicationEvent(ApplicationMetadata app, ApplicationEvent event) {
+ listener.onApplicationEvent(app.getApplicationId(), app.getApplicationName(), app.getEntityType(), app.getCatalogItemId(), app.getMetadata(), event);
+ }
+
+ @Override
+ public void onLocationEvent(LocationMetadata loc, LocationEvent event) {
+ listener.onLocationEvent(loc.getLocationId(), loc.getMetadata(), event);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof UsageListenerAdapter) && listener.equals(((UsageListenerAdapter)obj).listener);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(listener);
+ }
+ }
+
+ void onApplicationEvent(String applicationId, String applicationName, String entityType, String catalogItemId,
+ Map<String, String> metadata, ApplicationEvent event);
+
+ void onLocationEvent(String locationId, Map<String, String> metadata, LocationEvent event);
+ }
+
+ /**
+ * Adds this application event to the usage record for the given app (creating the usage
+ * record if one does not already exist).
+ */
+ void recordApplicationEvent(Application app, Lifecycle state);
+
+ /**
+ * Adds this location event to the usage record for the given location (creating the usage
+ * record if one does not already exist).
+ */
+ void recordLocationEvent(Location loc, Lifecycle state);
+
+ /**
+ * Returns the usage info for the location with the given id, or null if unknown.
+ */
+ LocationUsage getLocationUsage(String locationId);
+
+ /**
+ * Returns the usage info that matches the given predicate.
+ * For example, could be used to find locations used within a given time period.
+ */
+ Set<LocationUsage> getLocationUsage(Predicate<? super LocationUsage> filter);
+
+ /**
+ * Returns the usage info for the application with the given id, or null if unknown.
+ */
+ ApplicationUsage getApplicationUsage(String appId);
+
+ /**
+ * Returns the usage info that matches the given predicate.
+ * For example, could be used to find applications used within a given time period.
+ */
+ Set<ApplicationUsage> getApplicationUsage(Predicate<? super ApplicationUsage> filter);
+
+ /**
+ * @since 0.7.0
+ * @deprecated since 0.7.0; use {@link #removeUsageListener(org.apache.brooklyn.core.management.internal.UsageListener)};
+ * see {@link org.apache.brooklyn.core.management.internal.UsageManager.UsageListener.UsageListenerAdapter}
+ */
+ void addUsageListener(org.apache.brooklyn.core.management.internal.UsageManager.UsageListener listener);
+
+ /**
+ * @since 0.7.0
+ * @deprecated since 0.7.0; use {@link #removeUsageListener(org.apache.brooklyn.core.management.internal.UsageListener)}
+ */
+ @Deprecated
+ void removeUsageListener(org.apache.brooklyn.core.management.internal.UsageManager.UsageListener listener);
+
+ /**
+ * Adds the given listener, to be notified on recording of application/location events.
+ * The listener notifications may be asynchronous.
+ *
+ * As of 0.7.0, the listener is not persisted so will be lost on restart/rebind. This
+ * behaviour may change in a subsequent release.
+ */
+ void addUsageListener(org.apache.brooklyn.core.management.internal.UsageListener listener);
+
+ /**
+ * Removes the given listener.
+ */
+ void removeUsageListener(org.apache.brooklyn.core.management.internal.UsageListener listener);
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/main/java/org/apache/brooklyn/core/management/usage/ApplicationUsage.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/usage/ApplicationUsage.java b/core/src/main/java/org/apache/brooklyn/core/management/usage/ApplicationUsage.java
new file mode 100644
index 0000000..8260923
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/management/usage/ApplicationUsage.java
@@ -0,0 +1,126 @@
+/*
+ * 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.management.usage;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import brooklyn.entity.basic.Lifecycle;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+/**
+ */
+public class ApplicationUsage {
+
+ public static class ApplicationEvent {
+ private final Date date;
+ private final Lifecycle state;
+ private final String user;
+
+ public ApplicationEvent(Lifecycle state, String user) {
+ this(new Date(), state, user);
+ }
+
+ public ApplicationEvent(Date date, Lifecycle state) {
+ this(date,state, null);
+ }
+
+ public ApplicationEvent(Date date, Lifecycle state, String user) {
+ this.date = checkNotNull(date, "date");
+ this.state = checkNotNull(state, "state");
+ this.user = user;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public Lifecycle getState() {
+ return state;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof ApplicationEvent)) return false;
+ ApplicationEvent o = (ApplicationEvent) other;
+ return Objects.equal(date, o.date) && Objects.equal(state, o.state) && Objects.equal(user, o.user);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(date, state, user);
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this).add("date", date).add("state", state).add("entitlementContext", user).toString();
+ }
+ }
+
+ private final String applicationId;
+ private final String applicationName;
+ private final String entityType;
+ private final Map<String, String> metadata;
+ private final List<ApplicationEvent> events = Collections.synchronizedList(Lists.<ApplicationEvent>newArrayList());
+
+ public ApplicationUsage(String applicationId, String applicationName, String entityType, Map<String, String> metadata) {
+ this.applicationId = checkNotNull(applicationId, "applicationId");
+ // allow name to be null, happens in certain failed rebind cases
+ this.applicationName = applicationName;
+ this.entityType = checkNotNull(entityType, "entityType");
+ this.metadata = checkNotNull(metadata, "metadata");
+ }
+
+ public String getApplicationId() {
+ return applicationId;
+ }
+
+ public String getApplicationName() {
+ return applicationName;
+ }
+
+ public String getEntityType() {
+ return entityType;
+ }
+
+ public Map<String, String> getMetadata() {
+ return metadata;
+ }
+
+ public List<ApplicationEvent> getEvents() {
+ synchronized (events) {
+ return ImmutableList.copyOf(events);
+ }
+ }
+
+ public void addEvent(ApplicationEvent event) {
+ events.add(checkNotNull(event, "event"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/main/java/org/apache/brooklyn/core/management/usage/LocationUsage.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/usage/LocationUsage.java b/core/src/main/java/org/apache/brooklyn/core/management/usage/LocationUsage.java
new file mode 100644
index 0000000..32bd03b
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/management/usage/LocationUsage.java
@@ -0,0 +1,135 @@
+/*
+ * 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.management.usage;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import brooklyn.entity.basic.Lifecycle;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+/**
+ */
+public class LocationUsage {
+
+ public static class LocationEvent {
+ private final Date date;
+ private final Lifecycle state;
+ private final String entityId;
+ private final String entityType;
+ private final String applicationId;
+ private final String user;
+
+ public LocationEvent(Lifecycle state, String entityId, String entityType, String applicationId, String user) {
+ this(new Date(), state, entityId, entityType, applicationId, user);
+ }
+
+ public LocationEvent(Date date, Lifecycle state, String entityId, String entityType, String applicationId, String user) {
+ this.date = checkNotNull(date, "date");
+ this.state = checkNotNull(state, "state");
+ this.entityId = checkNotNull(entityId, "entityId");
+ this.entityType = checkNotNull(entityType, "entityType");
+ this.applicationId = checkNotNull(applicationId, "applicationId (entity "+entityId+")");
+ this.user = user;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public Lifecycle getState() {
+ return state;
+ }
+
+ public String getEntityId() {
+ return entityId;
+ }
+
+ public String getEntityType() {
+ return entityType;
+ }
+
+ public String getApplicationId() {
+ return applicationId;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof LocationEvent)) return false;
+ LocationEvent o = (LocationEvent) other;
+ return Objects.equal(date, o.date) && Objects.equal(state, o.state)
+ && Objects.equal(entityId, o.entityId) && Objects.equal(entityType, o.entityType)
+ && Objects.equal(applicationId, o.applicationId) && Objects.equal(user, o.user);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(date, state, entityId, entityType, applicationId, user);
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .add("date", date)
+ .add("state", state)
+ .add("entityId", entityId)
+ .add("appId", applicationId)
+ .add("user", user)
+ .toString();
+ }
+ }
+
+ private final String locationId;
+ private final Map<String, String> metadata;
+ private final List<LocationEvent> events = Collections.synchronizedList(Lists.<LocationEvent>newArrayList());
+
+ public LocationUsage(String locationId, Map<String, String> metadata) {
+ this.locationId = checkNotNull(locationId, "locationId");
+ this.metadata = checkNotNull(metadata, "metadata");
+ }
+
+ public String getLocationId() {
+ return locationId;
+ }
+
+ public Map<String, String> getMetadata() {
+ return metadata;
+ }
+
+ public List<LocationEvent> getEvents() {
+ synchronized (events) {
+ return ImmutableList.copyOf(events);
+ }
+ }
+
+ public void addEvent(LocationEvent event) {
+ events.add(checkNotNull(event, "event"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
index 47dca3e..c5a74a0 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
@@ -35,6 +35,8 @@ import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.management.Task;
import org.apache.brooklyn.api.mementos.LocationMemento;
+import org.apache.brooklyn.core.management.internal.LocalLocationManager;
+import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -53,8 +55,6 @@ import brooklyn.internal.storage.impl.BasicReference;
import org.apache.brooklyn.location.geo.HasHostGeoInfo;
import org.apache.brooklyn.location.geo.HostGeoInfo;
-import brooklyn.management.internal.LocalLocationManager;
-import brooklyn.management.internal.ManagementContextInternal;
import brooklyn.util.collections.SetFromLiveMap;
import brooklyn.util.config.ConfigBag;
import brooklyn.util.flags.FlagUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java
index 490335a..9a6466e 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java
@@ -40,12 +40,12 @@ import org.apache.brooklyn.api.location.LocationRegistry;
import org.apache.brooklyn.api.location.LocationResolver;
import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.core.management.internal.LocalLocationManager;
import brooklyn.catalog.CatalogPredicates;
import brooklyn.config.ConfigMap;
import brooklyn.config.ConfigPredicates;
import brooklyn.config.ConfigUtils;
-import brooklyn.management.internal.LocalLocationManager;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.config.ConfigBag;
import brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java
index 127a665..70735e5 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java
@@ -28,6 +28,7 @@ import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.location.LocationRegistry;
import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.core.management.internal.LocalLocationManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,7 +41,6 @@ import com.google.common.net.HostAndPort;
import brooklyn.config.ConfigKey;
import brooklyn.entity.basic.ConfigKeys;
import brooklyn.entity.basic.Sanitizer;
-import brooklyn.management.internal.LocalLocationManager;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.config.ConfigBag;
import brooklyn.util.flags.TypeCoercions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/BrooklynVersionTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/BrooklynVersionTest.java b/core/src/test/java/brooklyn/BrooklynVersionTest.java
index 7fbe976..179e698 100644
--- a/core/src/test/java/brooklyn/BrooklynVersionTest.java
+++ b/core/src/test/java/brooklyn/BrooklynVersionTest.java
@@ -37,8 +37,9 @@ import com.google.common.collect.Lists;
import brooklyn.catalog.internal.CatalogEntityItemDto;
import brooklyn.catalog.internal.CatalogItemBuilder;
import brooklyn.catalog.internal.CatalogItemDtoAbstract;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.management.osgi.OsgiTestResources;
+
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
+import org.apache.brooklyn.core.management.osgi.OsgiTestResources;
import org.apache.brooklyn.test.TestResourceUnavailableException;
import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java b/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java
index 0917b0e..73cf5ce 100644
--- a/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java
+++ b/core/src/test/java/brooklyn/camp/lite/CampYamlLiteTest.java
@@ -49,6 +49,8 @@ import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.proxying.EntitySpec;
import org.apache.brooklyn.api.management.Task;
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
+import org.apache.brooklyn.core.management.osgi.OsgiStandaloneTest;
import brooklyn.catalog.CatalogPredicates;
import brooklyn.catalog.internal.BasicBrooklynCatalog;
@@ -59,8 +61,6 @@ import brooklyn.entity.basic.ConfigKeys;
import brooklyn.entity.basic.Entities;
import brooklyn.entity.effector.AddChildrenEffector;
import brooklyn.entity.effector.Effectors;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.management.osgi.OsgiStandaloneTest;
import brooklyn.util.ResourceUtils;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/catalog/internal/CatalogDtoTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/catalog/internal/CatalogDtoTest.java b/core/src/test/java/brooklyn/catalog/internal/CatalogDtoTest.java
index 731a2d8..25a050e 100644
--- a/core/src/test/java/brooklyn/catalog/internal/CatalogDtoTest.java
+++ b/core/src/test/java/brooklyn/catalog/internal/CatalogDtoTest.java
@@ -28,13 +28,13 @@ import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.test.entity.TestApplication;
import org.apache.brooklyn.test.entity.TestEntity;
import brooklyn.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
import brooklyn.entity.basic.Entities;
-import brooklyn.management.internal.LocalManagementContext;
import brooklyn.util.BrooklynMavenArtifacts;
import brooklyn.util.maven.MavenRetriever;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/catalog/internal/CatalogScanTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/catalog/internal/CatalogScanTest.java b/core/src/test/java/brooklyn/catalog/internal/CatalogScanTest.java
index 8630430..c417421 100644
--- a/core/src/test/java/brooklyn/catalog/internal/CatalogScanTest.java
+++ b/core/src/test/java/brooklyn/catalog/internal/CatalogScanTest.java
@@ -30,13 +30,13 @@ import org.apache.brooklyn.api.catalog.BrooklynCatalog;
import org.apache.brooklyn.api.catalog.CatalogItem;
import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
import brooklyn.catalog.CatalogPredicates;
import brooklyn.catalog.internal.MyCatalogItems.MySillyAppTemplate;
import brooklyn.config.BrooklynProperties;
import brooklyn.config.BrooklynServerConfig;
import brooklyn.entity.basic.Entities;
-import brooklyn.management.internal.LocalManagementContext;
import brooklyn.util.ResourceUtils;
import brooklyn.util.net.Urls;
import brooklyn.util.text.Strings;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/catalog/internal/CatalogVersioningTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/catalog/internal/CatalogVersioningTest.java b/core/src/test/java/brooklyn/catalog/internal/CatalogVersioningTest.java
index 53a0b9c..78c11ea 100644
--- a/core/src/test/java/brooklyn/catalog/internal/CatalogVersioningTest.java
+++ b/core/src/test/java/brooklyn/catalog/internal/CatalogVersioningTest.java
@@ -28,11 +28,11 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.apache.brooklyn.api.catalog.BrooklynCatalog;
import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
import brooklyn.catalog.CatalogPredicates;
import brooklyn.entity.basic.Entities;
-import brooklyn.management.internal.LocalManagementContext;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/entity/BrooklynAppLiveTestSupport.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/BrooklynAppLiveTestSupport.java b/core/src/test/java/brooklyn/entity/BrooklynAppLiveTestSupport.java
index 668a788..626a035 100644
--- a/core/src/test/java/brooklyn/entity/BrooklynAppLiveTestSupport.java
+++ b/core/src/test/java/brooklyn/entity/BrooklynAppLiveTestSupport.java
@@ -18,6 +18,7 @@
*/
package brooklyn.entity;
+import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.test.entity.TestApplication;
import org.slf4j.Logger;
@@ -28,7 +29,6 @@ import org.testng.annotations.BeforeMethod;
import brooklyn.config.BrooklynProperties;
import brooklyn.entity.basic.ApplicationBuilder;
import brooklyn.entity.basic.Entities;
-import brooklyn.management.internal.ManagementContextInternal;
/**
* To be extended by live tests.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/entity/BrooklynAppUnitTestSupport.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/BrooklynAppUnitTestSupport.java b/core/src/test/java/brooklyn/entity/BrooklynAppUnitTestSupport.java
index 4e23de0..bb7beaf 100644
--- a/core/src/test/java/brooklyn/entity/BrooklynAppUnitTestSupport.java
+++ b/core/src/test/java/brooklyn/entity/BrooklynAppUnitTestSupport.java
@@ -19,6 +19,7 @@
package brooklyn.entity;
import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.test.entity.TestApplication;
import org.slf4j.Logger;
@@ -29,7 +30,6 @@ import org.testng.annotations.BeforeMethod;
import brooklyn.entity.basic.ApplicationBuilder;
import brooklyn.entity.basic.BrooklynConfigKeys;
import brooklyn.entity.basic.Entities;
-import brooklyn.management.internal.ManagementContextInternal;
/**
* To be extended by unit/integration tests.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java b/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java
index 66daf0b..337cbfd 100644
--- a/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java
+++ b/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java
@@ -29,6 +29,7 @@ import org.apache.brooklyn.api.entity.ParameterType;
import org.apache.brooklyn.api.entity.proxying.EntitySpec;
import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.core.management.internal.EffectorUtils;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -39,7 +40,6 @@ import brooklyn.entity.basic.BasicParameterType;
import brooklyn.entity.basic.MethodEffector;
import brooklyn.entity.effector.Effectors;
import brooklyn.entity.trait.Startable;
-import brooklyn.management.internal.EffectorUtils;
import com.google.common.collect.ImmutableList;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/entity/EffectorSayHiGroovyTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/EffectorSayHiGroovyTest.groovy b/core/src/test/java/brooklyn/entity/EffectorSayHiGroovyTest.groovy
index 5ce49a2..57362f2 100644
--- a/core/src/test/java/brooklyn/entity/EffectorSayHiGroovyTest.groovy
+++ b/core/src/test/java/brooklyn/entity/EffectorSayHiGroovyTest.groovy
@@ -42,7 +42,7 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.management.ManagementContext
import org.apache.brooklyn.api.management.Task
-import brooklyn.management.internal.EffectorUtils
+import org.apache.brooklyn.core.management.internal.EffectorUtils
import org.apache.brooklyn.test.entity.TestApplication
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/entity/EffectorSayHiTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/EffectorSayHiTest.java b/core/src/test/java/brooklyn/entity/EffectorSayHiTest.java
index 0505456..62579e3 100644
--- a/core/src/test/java/brooklyn/entity/EffectorSayHiTest.java
+++ b/core/src/test/java/brooklyn/entity/EffectorSayHiTest.java
@@ -33,6 +33,7 @@ import org.apache.brooklyn.api.entity.proxying.EntitySpec;
import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
import org.apache.brooklyn.api.management.ExecutionContext;
import org.apache.brooklyn.api.management.Task;
+import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.BeforeMethod;
@@ -43,7 +44,6 @@ import brooklyn.entity.basic.AbstractEntity;
import brooklyn.entity.basic.BrooklynTaskTags;
import brooklyn.entity.basic.MethodEffector;
import brooklyn.entity.trait.Startable;
-import brooklyn.management.internal.ManagementContextInternal;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.task.BasicTask;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java b/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java
index 64bfcd4..472b3d9 100644
--- a/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java
@@ -24,6 +24,7 @@ import static org.testng.Assert.fail;
import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver;
import org.apache.brooklyn.api.entity.proxying.EntitySpec;
import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
import org.apache.brooklyn.test.entity.TestApplication;
import org.apache.brooklyn.test.entity.TestEntity;
import org.testng.annotations.AfterMethod;
@@ -38,8 +39,6 @@ import brooklyn.entity.basic.Entities;
import org.apache.brooklyn.location.basic.SimulatedLocation;
-import brooklyn.management.internal.LocalManagementContext;
-
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6602f694/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java
index 2ed52e4..afda43a 100644
--- a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java
@@ -26,6 +26,7 @@ import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.
import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadTargets;
import org.apache.brooklyn.api.entity.proxying.EntitySpec;
import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
import org.apache.brooklyn.test.entity.TestApplication;
import org.apache.brooklyn.test.entity.TestEntity;
import org.testng.annotations.AfterMethod;
@@ -39,8 +40,6 @@ import brooklyn.entity.basic.Entities;
import org.apache.brooklyn.location.basic.SimulatedLocation;
-import brooklyn.management.internal.LocalManagementContext;
-
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;