You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2016/02/01 18:51:29 UTC
[47/51] [abbrv] [partial] brooklyn-server git commit: move subdir
from incubator up a level as it is promoted to its own repo (first
non-incubator commit!)
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/ManagementPlaneSyncRecordPersister.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/ManagementPlaneSyncRecordPersister.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/ManagementPlaneSyncRecordPersister.java
new file mode 100644
index 0000000..16ff913
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/ManagementPlaneSyncRecordPersister.java
@@ -0,0 +1,68 @@
+/*
+ * 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.api.mgmt.ha;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister;
+import org.apache.brooklyn.util.time.Duration;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * Controls the persisting and reading back of mementos relating to the management plane.
+ * This state does not relate to the entities being managed.
+ *
+ * @see {@link HighAvailabilityManager#setPersister(ManagementPlaneSyncRecordPersister)} for its use in management-node failover
+ *
+ * @since 0.7.0
+ */
+@Beta
+public interface ManagementPlaneSyncRecordPersister {
+
+ /**
+ * Analogue to {@link BrooklynMementoPersister#loadMemento(org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister.LookupContext)}
+ * <p>
+ * Note that this method is *not* thread safe.
+ */
+ ManagementPlaneSyncRecord loadSyncRecord() throws IOException;
+
+ void delta(Delta delta);
+
+ void stop();
+
+ @VisibleForTesting
+ void waitForWritesCompleted(Duration timeout) throws InterruptedException, TimeoutException;
+
+ public interface Delta {
+ public enum MasterChange {
+ NO_CHANGE,
+ SET_MASTER,
+ CLEAR_MASTER
+ }
+ Collection<ManagementNodeSyncRecord> getNodes();
+ Collection<String> getRemovedNodeIds();
+ MasterChange getMasterChange();
+ String getNewMasterOrNull();
+ String getExpectedMasterToClear();
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/MementoCopyMode.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/MementoCopyMode.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/MementoCopyMode.java
new file mode 100644
index 0000000..320c264
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/MementoCopyMode.java
@@ -0,0 +1,29 @@
+/*
+ * 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.api.mgmt.ha;
+
+public enum MementoCopyMode {
+ /** Use items currently managed at this node */
+ LOCAL,
+ /** Use items as stored in the remote persistence store */
+ REMOTE,
+ /** Auto-detect whether to use {@link #LOCAL} or {@link #REMOTE} depending on the
+ * HA mode of this management node (usually {@link #LOCAL} for master and {@link #REMOTE} otherwise)*/
+ AUTO
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/ChangeListener.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/ChangeListener.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/ChangeListener.java
new file mode 100644
index 0000000..ce26a82
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/ChangeListener.java
@@ -0,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.api.mgmt.rebind;
+
+import org.apache.brooklyn.api.objs.BrooklynObject;
+
+/**
+ * Listener to be notified of changes within brooklyn, so that the new state
+ * of the entity/location/policy can be persisted.
+ *
+ * Users are not expected to implement this class. It is for use by the {@link RebindManager}.
+ *
+ * @author aled
+ */
+public interface ChangeListener {
+
+ public static final ChangeListener NOOP = new ChangeListener() {
+ @Override public void onChanged(BrooklynObject instance) {}
+ @Override public void onManaged(BrooklynObject instance) {}
+ @Override public void onUnmanaged(BrooklynObject instance) {}
+ };
+
+ void onManaged(BrooklynObject instance);
+
+ void onUnmanaged(BrooklynObject instance);
+
+ void onChanged(BrooklynObject instance);
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/PersistenceExceptionHandler.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/PersistenceExceptionHandler.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/PersistenceExceptionHandler.java
new file mode 100644
index 0000000..759bca6
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/PersistenceExceptionHandler.java
@@ -0,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.api.mgmt.rebind;
+
+import org.apache.brooklyn.api.mgmt.rebind.mementos.Memento;
+import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.objs.BrooklynObjectType;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Handler called on all exceptions to do with persistence.
+ *
+ * @author aled
+ */
+@Beta
+public interface PersistenceExceptionHandler {
+
+ void stop();
+
+ void onGenerateMementoFailed(BrooklynObjectType type, BrooklynObject instance, Exception e);
+
+ void onPersistMementoFailed(Memento memento, Exception e);
+
+ void onPersistRawMementoFailed(BrooklynObjectType type, String id, Exception e);
+
+ void onDeleteMementoFailed(String id, Exception e);
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindContext.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindContext.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindContext.java
new file mode 100644
index 0000000..d928da0
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindContext.java
@@ -0,0 +1,52 @@
+/*
+ * 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.api.mgmt.rebind;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister.LookupContext;
+import org.apache.brooklyn.api.objs.BrooklynObject;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Gives access to things that are being currently rebinding. This is used during a
+ * rebind to wire everything back together again, e.g. to find the necessary entity
+ * instances even before they are available through
+ * {@code managementContext.getEntityManager().getEnties()}.
+ * <p>
+ * Users are not expected to implement this class. It is for use by {@link Rebindable}
+ * instances, and will generally be created by the {@link RebindManager}.
+ * <p>
+ */
+@Beta
+public interface RebindContext {
+
+ /** Returns an unmodifiable view of all objects by ID */
+ Map<String,BrooklynObject> getAllBrooklynObjects();
+
+ Class<?> loadClass(String typeName) throws ClassNotFoundException;
+
+ RebindExceptionHandler getExceptionHandler();
+
+ boolean isReadOnly(BrooklynObject item);
+
+ LookupContext lookup();
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindExceptionHandler.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindExceptionHandler.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindExceptionHandler.java
new file mode 100644
index 0000000..574a680
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindExceptionHandler.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.api.mgmt.rebind;
+
+import java.util.List;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.EntityMemento;
+import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.objs.BrooklynObjectType;
+import org.apache.brooklyn.api.policy.Policy;
+import org.apache.brooklyn.api.sensor.Enricher;
+import org.apache.brooklyn.api.sensor.Feed;
+
+import com.google.common.annotations.Beta;
+import org.apache.brooklyn.config.ConfigKey;
+
+/**
+ * Handler called on all exceptions to do with rebind.
+ * A handler instance is linked to a single rebind pass;
+ * it should not be invoked after {@link #onDone()}.
+ * <p>
+ * {@link #onStart()} must be invoked before the run.
+ * {@link #onDone()} must be invoked after a successful run, and it may throw.
+ * <p>
+ * Implementations may propagate errors or may catch them until {@link #onDone()} is invoked,
+ * and that may throw or report elsewhere, as appropriate.
+ *
+ * @author aled
+ */
+@Beta
+public interface RebindExceptionHandler {
+
+ void onLoadMementoFailed(BrooklynObjectType type, String msg, Exception e);
+
+ /**
+ * @return the entity to use in place of the missing one, or null (if hasn't thrown an exception)
+ */
+ Entity onDanglingEntityRef(String id);
+
+ /**
+ * @return the location to use in place of the missing one, or null (if hasn't thrown an exception)
+ */
+ Location onDanglingLocationRef(String id);
+
+ /**
+ * @return the policy to use in place of the missing one, or null (if hasn't thrown an exception)
+ */
+ Policy onDanglingPolicyRef(String id);
+
+ /**
+ * @return the enricher to use in place of the missing one, or null (if hasn't thrown an exception)
+ */
+ Enricher onDanglingEnricherRef(String id);
+
+ /**
+ * @return the feed to use in place of the missing one, or null (if hasn't thrown an exception)
+ */
+ Feed onDanglingFeedRef(String id);
+
+ /**
+ * @return the catalog item to use in place of the missing one
+ */
+ CatalogItem<?, ?> onDanglingCatalogItemRef(String id);
+
+ /**
+ * @return the item to use in place of the missing one
+ */
+ BrooklynObject onDanglingUntypedItemRef(String id);
+
+ void onCreateFailed(BrooklynObjectType type, String id, String instanceType, Exception e);
+
+ void onNotFound(BrooklynObjectType type, String id);
+
+ void onRebindFailed(BrooklynObjectType type, BrooklynObject instance, Exception e);
+
+ void onAddConfigFailed(EntityMemento type, ConfigKey<?> value, Exception e);
+
+ void onAddPolicyFailed(EntityLocal entity, Policy policy, Exception e);
+
+ void onAddEnricherFailed(EntityLocal entity, Enricher enricher, Exception e);
+
+ void onAddFeedFailed(EntityLocal entity, Feed feed, Exception e);
+
+ void onManageFailed(BrooklynObjectType type, BrooklynObject instance, Exception e);
+
+ /** invoked for any high-level, unexpected, or otherwise uncaught failure;
+ * may be invoked on catching above errors */
+ RuntimeException onFailed(Exception e);
+
+ /** invoked before the rebind pass */
+ void onStart(RebindContext context);
+
+ /** invoked after the complete rebind pass, always on success and possibly on failure */
+ void onDone();
+
+ List<Exception> getExceptions();
+ List<String> getWarnings();
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindManager.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindManager.java
new file mode 100644
index 0000000..c1441db
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindManager.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.api.mgmt.rebind;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeoutException;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoRawData;
+import org.apache.brooklyn.util.time.Duration;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * Manages the persisting of brooklyn's state, and recreating that state, e.g. on
+ * brooklyn restart.
+ *
+ * Users are not expected to implement this class, or to call methods on it directly.
+ */
+public interface RebindManager {
+
+ // FIXME Should we be calling managementContext.getRebindManager().rebind, using a
+ // new empty instance of managementContext?
+ //
+ // Or is that a risky API because you could call it on a non-empty managementContext?
+
+ public enum RebindFailureMode {
+ FAIL_FAST,
+ FAIL_AT_END,
+ CONTINUE;
+ }
+
+ public void setPersister(BrooklynMementoPersister persister);
+
+ public void setPersister(BrooklynMementoPersister persister, PersistenceExceptionHandler exceptionHandler);
+
+ @VisibleForTesting
+ public BrooklynMementoPersister getPersister();
+
+ /** @deprecated since 0.7; use {@link #rebind(ClassLoader, RebindExceptionHandler, ManagementNodeState)} */ @Deprecated
+ public List<Application> rebind();
+
+ /** @deprecated since 0.7; use {@link #rebind(ClassLoader, RebindExceptionHandler, ManagementNodeState)} */ @Deprecated
+ public List<Application> rebind(ClassLoader classLoader);
+ /** @deprecated since 0.7; use {@link #rebind(ClassLoader, RebindExceptionHandler, ManagementNodeState)} */ @Deprecated
+ public List<Application> rebind(ClassLoader classLoader, RebindExceptionHandler exceptionHandler);
+ /** Causes this management context to rebind, loading data from the given backing store.
+ * use wisely, as this can cause local entities to be completely lost, or will throw in many other situations.
+ * in general it may be invoked for a new node becoming {@link ManagementNodeState#MASTER}
+ * or periodically for a node in {@link ManagementNodeState#HOT_STANDBY} or {@link ManagementNodeState#HOT_BACKUP}. */
+ @Beta
+ public List<Application> rebind(ClassLoader classLoader, RebindExceptionHandler exceptionHandler, ManagementNodeState mode);
+
+ public BrooklynMementoRawData retrieveMementoRawData();
+
+ public ChangeListener getChangeListener();
+
+ /**
+ * Starts the background persisting of state
+ * (if persister is set; otherwise will start persisting as soon as persister is set).
+ * Until this is called, no data will be persisted although entities can be rebinded.
+ */
+ public void startPersistence();
+
+ /** Stops the background persistence of state.
+ * Waits for any current persistence to complete. */
+ public void stopPersistence();
+
+ /**
+ * Perform an initial load of state read-only and starts a background process
+ * reading (mirroring) state periodically.
+ */
+ public void startReadOnly(ManagementNodeState mode);
+ /** Stops the background reading (mirroring) of state.
+ * Interrupts any current activity and waits for it to cease. */
+ public void stopReadOnly();
+
+ /** Starts the appropriate background processes, {@link #startPersistence()} if {@link ManagementNodeState#MASTER},
+ * {@link #startReadOnly()} if {@link ManagementNodeState#HOT_STANDBY} or {@link ManagementNodeState#HOT_BACKUP} */
+ public void start();
+ /** Stops the appropriate background processes, {@link #stopPersistence()} or {@link #stopReadOnly()},
+ * waiting for activity there to cease (interrupting in the case of {@link #stopReadOnly()}). */
+ public void stop();
+
+ @VisibleForTesting
+ /** waits for any needed or pending writes to complete */
+ public void waitForPendingComplete(Duration duration, boolean canTrigger) throws InterruptedException, TimeoutException;
+ /** Forcibly performs persistence, in the foreground
+ * @deprecated since 0.7.0; use {@link #forcePersistNow(boolean, PersistenceExceptionHandler)},
+ * default parameter here is false to mean incremental, with null/default exception handler */
+ @VisibleForTesting
+ public void forcePersistNow();
+ /** Forcibly performs persistence, in the foreground, either full (all entities) or incremental;
+ * if no exception handler specified, the default one from the persister is used.
+ * <p>
+ * Note that full persistence does *not* delete items; incremental should normally be sufficient.
+ * (A clear then full persistence would have the same effect, but that is risky in a production
+ * setting if the process fails after the clear!) */
+ @VisibleForTesting
+ public void forcePersistNow(boolean full, @Nullable PersistenceExceptionHandler exceptionHandler);
+
+ /** Whether the management state has changed to a state where a rebind is needed
+ * but we are still awaiting the first run;
+ * ie state is master or hot, but list of apps is not yet accurate */
+ public boolean isAwaitingInitialRebind();
+
+ /** Metrics about rebind, last success, etc. */
+ public Map<String,Object> getMetrics();
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindSupport.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindSupport.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindSupport.java
new file mode 100644
index 0000000..2e8fdbf
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindSupport.java
@@ -0,0 +1,57 @@
+/*
+ * 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.api.mgmt.rebind;
+
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.Memento;
+
+/**
+ * Supporter instance for behaviour related to rebinding a given entity/location/policy.
+ *
+ * For example, the brooklyn framework may call {@code entity.getRebindSupport().getMemento()}
+ * and persist this using a {@link BrooklynMementoPersister}. Later (e.g. after a brooklyn
+ * restart) a new entity instance may be created and populated by the framework calling
+ * {@code entity.getRebindSupport().reconstruct(rebindContext, memento)}.
+ *
+ * @author aled
+ */
+public interface RebindSupport<T extends Memento> {
+
+ /**
+ * Creates a memento representing this entity's current state. This is useful for when restarting brooklyn.
+ */
+ T getMemento();
+
+ /**
+ * Reconstructs this entity, given a memento of its state. Sets the internal state
+ * (including id and config keys), and sets the parent/children/locations of this entity.
+ *
+ * Implementations should be very careful to not invoke or inspect these other entities/locations,
+ * as they may also be being reconstructed at this time.
+ *
+ * Called during rebind, after creation and before the call to start management.
+ */
+ void reconstruct(RebindContext rebindContext, T memento);
+
+ void addPolicies(RebindContext rebindContext, T Memento);
+
+ void addEnrichers(RebindContext rebindContext, T Memento);
+
+ void addFeeds(RebindContext rebindContext, T Memento);
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/Rebindable.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/Rebindable.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/Rebindable.java
new file mode 100644
index 0000000..301e8e0
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/Rebindable.java
@@ -0,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.api.mgmt.rebind;
+
+import org.apache.brooklyn.api.mgmt.rebind.mementos.Memento;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Indicates that this can be recreated, e.g. after a brooklyn restart, and by
+ * using a {@link Memento} it can repopulate the brooklyn objects. The purpose
+ * of the rebind is to reconstruct and reconnect the brooklyn objects, including
+ * binding them to external resources.
+ *
+ * Users are strongly discouraged to call or use this interface.
+ * It is for internal use only, relating to persisting/rebinding entities.
+ * This interface may change (or be removed) in a future release without notice.
+ */
+@Beta
+public interface Rebindable {
+
+ public RebindSupport<?> getRebindSupport();
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMemento.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMemento.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMemento.java
new file mode 100644
index 0000000..1c66c70
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMemento.java
@@ -0,0 +1,64 @@
+/*
+ * 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.api.mgmt.rebind.mementos;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Represents an entire persisted Brooklyn management context, with all its entities and locations.
+ *
+ * The referential integrity of this memento is not guaranteed. For example, an entity memento might
+ * reference a child entity that does not exist. This is an inevitable consequence of not using a
+ * stop-the-world persistence strategy, and is essential for a distributed brooklyn to be performant.
+ *
+ * Code using this memento should be tolerant of such inconsistencies (e.g. log a warning about the
+ * missing entity, and then ignore dangling references when constructing the entities/locations, so
+ * that code will not subsequently get NPEs when iterating over children for example).
+ *
+ * @author aled
+ */
+public interface BrooklynMemento extends Serializable {
+
+ public EntityMemento getEntityMemento(String id);
+ public LocationMemento getLocationMemento(String id);
+ public PolicyMemento getPolicyMemento(String id);
+ public EnricherMemento getEnricherMemento(String id);
+ public FeedMemento getFeedMemento(String id);
+ public CatalogItemMemento getCatalogItemMemento(String id);
+
+ public Collection<String> getApplicationIds();
+ public Collection<String> getTopLevelLocationIds();
+
+ public Collection<String> getEntityIds();
+ public Collection<String> getLocationIds();
+ public Collection<String> getPolicyIds();
+ public Collection<String> getEnricherIds();
+ public Collection<String> getFeedIds();
+ public Collection<String> getCatalogItemIds();
+
+ public Map<String, EntityMemento> getEntityMementos();
+ public Map<String, LocationMemento> getLocationMementos();
+ public Map<String, PolicyMemento> getPolicyMementos();
+ public Map<String, EnricherMemento> getEnricherMementos();
+ public Map<String, FeedMemento> getFeedMementos();
+ public Map<String, CatalogItemMemento> getCatalogItemMementos();
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoManifest.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoManifest.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoManifest.java
new file mode 100644
index 0000000..2efc6f6
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoManifest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.api.mgmt.rebind.mementos;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.brooklyn.api.objs.Identifiable;
+
+/**
+ * Represents a manifest of the entities etc in the overall memento.
+ *
+ * @author aled
+ */
+public interface BrooklynMementoManifest extends Serializable {
+ public interface EntityMementoManifest extends Identifiable{
+ public String getId();
+ public String getType();
+ public String getParent();
+ public String getCatalogItemId();
+ }
+
+ public Map<String, EntityMementoManifest> getEntityIdToManifest();
+
+ public Map<String, String> getLocationIdToType();
+
+ public Map<String, String> getPolicyIdToType();
+
+ public Map<String, String> getEnricherIdToType();
+
+ public Map<String, String> getFeedIdToType();
+
+ public CatalogItemMemento getCatalogItemMemento(String id);
+
+ public Collection<String> getCatalogItemIds();
+
+ public Map<String, CatalogItemMemento> getCatalogItemMementos();
+
+ public boolean isEmpty();
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoPersister.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoPersister.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoPersister.java
new file mode 100644
index 0000000..03673fd
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoPersister.java
@@ -0,0 +1,138 @@
+/*
+ * 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.api.mgmt.rebind.mementos;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.TimeoutException;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.rebind.PersistenceExceptionHandler;
+import org.apache.brooklyn.api.mgmt.rebind.RebindExceptionHandler;
+import org.apache.brooklyn.api.mgmt.rebind.RebindManager;
+import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.objs.BrooklynObjectType;
+import org.apache.brooklyn.api.policy.Policy;
+import org.apache.brooklyn.api.sensor.Enricher;
+import org.apache.brooklyn.api.sensor.Feed;
+import org.apache.brooklyn.util.time.Duration;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * Controls the persisting and reading back of mementos. Used by {@link RebindManager}
+ * to support brooklyn restart.
+ */
+public interface BrooklynMementoPersister {
+
+ public static interface LookupContext {
+ ManagementContext lookupManagementContext();
+ Entity lookupEntity(String id);
+ Location lookupLocation(String id);
+ Policy lookupPolicy(String id);
+ Enricher lookupEnricher(String id);
+ Feed lookupFeed(String id);
+ CatalogItem<?, ?> lookupCatalogItem(String id);
+
+ /** retrieve the item with the given ID, optionally ensuring it is of the indicated type; null if not found */
+ BrooklynObject lookup(@Nullable BrooklynObjectType type, String objectId);
+ /** like {@link #lookup(BrooklynObjectType, String)} but doesn't record an exception if not found */
+ BrooklynObject peek(@Nullable BrooklynObjectType type, String objectId);
+ }
+
+ /**
+ * Loads raw data contents of the mementos.
+ * <p>
+ * Some classes (esp deprecated ones) may return null here,
+ * meaning that the {@link #loadMementoManifest(BrooklynMementoRawData, RebindExceptionHandler)}
+ * and {@link #loadMemento(BrooklynMementoRawData, LookupContext, RebindExceptionHandler)} methods
+ * will populate the raw data via another source.
+ */
+ BrooklynMementoRawData loadMementoRawData(RebindExceptionHandler exceptionHandler);
+
+ /**
+ * Loads minimal manifest information (almost entirely *not* deserialized).
+ * Implementations should load the raw data if {@link BrooklynMementoRawData} is not supplied,
+ * but callers are encouraged to supply that for optimal performance.
+ */
+ BrooklynMementoManifest loadMementoManifest(@Nullable BrooklynMementoRawData mementoData, RebindExceptionHandler exceptionHandler) throws IOException;
+
+ /**
+ * Retrieves the memento class, containing deserialized objects (but not the {@link BrooklynObject} class).
+ * Implementations should load the raw data if {@link BrooklynMementoRawData} is not supplied,
+ * but callers are encouraged to supply that for optimal performance.
+ * <p>
+ * Note that this method is *not* thread safe.
+ */
+ BrooklynMemento loadMemento(@Nullable BrooklynMementoRawData mementoData, LookupContext lookupContext, RebindExceptionHandler exceptionHandler) throws IOException;
+
+ /** applies a full checkpoint (write) of all state */
+ void checkpoint(BrooklynMementoRawData newMemento, PersistenceExceptionHandler exceptionHandler);
+ /** applies a partial write of state delta */
+ void delta(Delta delta, PersistenceExceptionHandler exceptionHandler);
+ /** inserts an additional delta to be written on the next delta request */
+ @Beta
+ void queueDelta(Delta delta);
+
+ void enableWriteAccess();
+ void disableWriteAccess(boolean graceful);
+ /** permanently shuts down all access to the remote store */
+ void stop(boolean graceful);
+
+ @VisibleForTesting
+ void waitForWritesCompleted(Duration timeout) throws InterruptedException, TimeoutException;
+
+ String getBackingStoreDescription();
+
+ /** All methods on this interface are unmodifiable by the caller. Sub-interfaces may introduce modifiers. */
+ // NB: the type-specific methods aren't actually used anymore; we could remove them to simplify the impl (and use a multiset there)
+ public interface Delta {
+ Collection<LocationMemento> locations();
+ Collection<EntityMemento> entities();
+ Collection<PolicyMemento> policies();
+ Collection<EnricherMemento> enrichers();
+ Collection<FeedMemento> feeds();
+ Collection<CatalogItemMemento> catalogItems();
+
+ Collection<String> removedLocationIds();
+ Collection<String> removedEntityIds();
+ Collection<String> removedPolicyIds();
+ Collection<String> removedEnricherIds();
+ Collection<String> removedFeedIds();
+ Collection<String> removedCatalogItemIds();
+
+ Collection<? extends Memento> getObjectsOfType(BrooklynObjectType type);
+ Collection<String> getRemovedIdsOfType(BrooklynObjectType type);
+ }
+
+ @Beta
+ public interface MutableDelta extends Delta {
+ void add(BrooklynObjectType type, Memento memento);
+ void addAll(BrooklynObjectType type, Iterable<? extends Memento> memento);
+ void removed(BrooklynObjectType type, Set<String> removedIdsOfType);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoRawData.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoRawData.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoRawData.java
new file mode 100644
index 0000000..804304d
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoRawData.java
@@ -0,0 +1,185 @@
+/*
+ * 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.api.mgmt.rebind.mementos;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.brooklyn.api.objs.BrooklynObjectType;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.Maps;
+
+/**
+ * Represents the raw persisted data.
+ */
+@Beta
+public class BrooklynMementoRawData {
+
+ // TODO Should this be on an interface?
+ // The file-based (or object-store based) structure for storing data may well change; is this representation sufficient?
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ protected String brooklynVersion;
+ protected final Map<String, String> entities = Maps.newConcurrentMap();
+ protected final Map<String, String> locations = Maps.newConcurrentMap();
+ protected final Map<String, String> policies = Maps.newConcurrentMap();
+ protected final Map<String, String> enrichers = Maps.newConcurrentMap();
+ protected final Map<String, String> feeds = Maps.newConcurrentMap();
+ protected final Map<String, String> catalogItems = Maps.newConcurrentMap();
+
+ public Builder brooklynVersion(String val) {
+ brooklynVersion = val; return this;
+ }
+ public Builder entity(String id, String val) {
+ entities.put(id, val); return this;
+ }
+ public Builder entities(Map<String, String> vals) {
+ entities.putAll(vals); return this;
+ }
+ public Builder location(String id, String val) {
+ locations.put(id, val); return this;
+ }
+ public Builder locations(Map<String, String> vals) {
+ locations.putAll(vals); return this;
+ }
+ public Builder policy(String id, String val) {
+ policies.put(id, val); return this;
+ }
+ public Builder policies(Map<String, String> vals) {
+ policies.putAll(vals); return this;
+ }
+ public Builder enricher(String id, String val) {
+ enrichers.put(id, val); return this;
+ }
+ public Builder enrichers(Map<String, String> vals) {
+ enrichers.putAll(vals); return this;
+ }
+ public Builder feed(String id, String val) {
+ feeds.put(id, val); return this;
+ }
+ public Builder feeds(Map<String, String> vals) {
+ feeds.putAll(vals); return this;
+ }
+ public Builder catalogItem(String id, String val) {
+ catalogItems.put(id, val); return this;
+ }
+ public Builder catalogItems(Map<String, String> vals) {
+ catalogItems.putAll(vals); return this;
+ }
+
+ public Builder put(BrooklynObjectType type, String id, String val) {
+ switch (type) {
+ case ENTITY: return entity(id, val);
+ case LOCATION: return location(id, val);
+ case POLICY: return policy(id, val);
+ case ENRICHER: return enricher(id, val);
+ case FEED: return feed(id, val);
+ case CATALOG_ITEM: return catalogItem(id, val);
+ case UNKNOWN:
+ default:
+ throw new IllegalArgumentException(type+" not supported");
+ }
+ }
+ public Builder putAll(BrooklynObjectType type, Map<String,String> vals) {
+ switch (type) {
+ case ENTITY: return entities(vals);
+ case LOCATION: return locations(vals);
+ case POLICY: return policies(vals);
+ case ENRICHER: return enrichers(vals);
+ case FEED: return feeds(vals);
+ case CATALOG_ITEM: return catalogItems(vals);
+ case UNKNOWN:
+ default:
+ throw new IllegalArgumentException(type+" not supported");
+ }
+ }
+
+ public BrooklynMementoRawData build() {
+ return new BrooklynMementoRawData(this);
+ }
+ }
+
+ private final Map<String, String> entities;
+ private final Map<String, String> locations;
+ private final Map<String, String> policies;
+ private final Map<String, String> enrichers;
+ private final Map<String, String> feeds;
+ private final Map<String, String> catalogItems;
+
+ private BrooklynMementoRawData(Builder builder) {
+ entities = builder.entities;
+ locations = builder.locations;
+ policies = builder.policies;
+ enrichers = builder.enrichers;
+ feeds = builder.feeds;
+ catalogItems = builder.catalogItems;
+ }
+
+ public Map<String, String> getEntities() {
+ return Collections.unmodifiableMap(entities);
+ }
+
+ public Map<String, String> getLocations() {
+ return Collections.unmodifiableMap(locations);
+ }
+
+ public Map<String, String> getPolicies() {
+ return Collections.unmodifiableMap(policies);
+ }
+
+ public Map<String, String> getEnrichers() {
+ return Collections.unmodifiableMap(enrichers);
+ }
+
+ public Map<String, String> getFeeds() {
+ return Collections.unmodifiableMap(feeds);
+ }
+
+ public Map<String, String> getCatalogItems() {
+ return Collections.unmodifiableMap(catalogItems);
+ }
+
+ // to handle reset catalog
+ @Beta
+ public void clearCatalogItems() {
+ catalogItems.clear();
+ }
+
+ public boolean isEmpty() {
+ return entities.isEmpty() && locations.isEmpty() && policies.isEmpty() && enrichers.isEmpty() && feeds.isEmpty() && catalogItems.isEmpty();
+ }
+
+ public Map<String, String> getObjectsOfType(BrooklynObjectType type) {
+ switch (type) {
+ case ENTITY: return getEntities();
+ case LOCATION: return getLocations();
+ case POLICY: return getPolicies();
+ case ENRICHER: return getEnrichers();
+ case FEED: return getFeeds();
+ case CATALOG_ITEM: return getCatalogItems();
+ default:
+ throw new IllegalArgumentException("Type "+type+" not supported");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java
new file mode 100644
index 0000000..57fbb8d
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.api.mgmt.rebind.mementos;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.objs.SpecParameter;
+
+public interface CatalogItemMemento extends Memento {
+
+ String getDescription();
+
+ String getSymbolicName();
+
+ String getIconUrl();
+
+ String getVersion();
+
+ String getPlanYaml();
+
+ String getJavaType();
+
+ List<SpecParameter<?>> getParameters();
+
+ Collection<CatalogItem.CatalogBundle> getLibraries();
+
+ CatalogItem.CatalogItemType getCatalogItemType();
+
+ Class<?> getCatalogItemJavaType();
+
+ Class<?> getSpecType();
+
+ boolean isDeprecated();
+
+ boolean isDisabled();
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/EnricherMemento.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/EnricherMemento.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/EnricherMemento.java
new file mode 100644
index 0000000..c6b7e8c
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/EnricherMemento.java
@@ -0,0 +1,33 @@
+/*
+ * 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.api.mgmt.rebind.mementos;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
+
+/**
+ * Represents the state of an enricher, so that it can be reconstructed (e.g. after restarting brooklyn).
+ *
+ * @see RebindSupport
+ */
+public interface EnricherMemento extends Memento {
+
+ Map<String, Object> getConfig();
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/EntityMemento.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/EntityMemento.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/EntityMemento.java
new file mode 100644
index 0000000..4c74695
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/EntityMemento.java
@@ -0,0 +1,80 @@
+/*
+ * 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.api.mgmt.rebind.mementos;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.config.ConfigKey;
+
+/**
+ * Represents the state of an entity, so that it can be reconstructed (e.g. after restarting brooklyn).
+ *
+ * @see RebindSupport
+ *
+ * @author aled
+ */
+public interface EntityMemento extends Memento, TreeNode {
+
+ /** all dynamic effectors (ie differences between those registered on the entity type */
+ public List<Effector<?>> getEffectors();
+
+ public Map<ConfigKey<?>, Object> getConfig();
+
+ /** true if the entity is top-level (parentless) and an application
+ * (there may be parentless "orphaned" entities, for which this is false,
+ * and "application" instances nested inside other apps, for which this is again)
+ */
+ public boolean isTopLevelApp();
+
+ public Map<String, Object> getConfigUnmatched();
+
+ public Map<AttributeSensor<?>, Object> getAttributes();
+
+ /**
+ * The ids of the member entities, if this is a Group; otherwise empty.
+ *
+ * @see Group.getMembers()
+ */
+ public List<String> getMembers();
+
+ /**
+ * The ids of the locations for this entity.
+ */
+ public List<String> getLocations();
+
+ /**
+ * The ids of the policies of this entity.
+ */
+ public Collection<String> getPolicies();
+
+ /**
+ * The ids of the enrichers of this entity.
+ */
+ public Collection<String> getEnrichers();
+
+ /**
+ * The ids of the sensor feeds attached to this entity.
+ */
+ public Collection<String> getFeeds();
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/FeedMemento.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/FeedMemento.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/FeedMemento.java
new file mode 100644
index 0000000..52424c3
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/FeedMemento.java
@@ -0,0 +1,33 @@
+/*
+ * 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.api.mgmt.rebind.mementos;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
+
+/**
+ * Represents the state of a feed, so that it can be reconstructed (e.g. after restarting brooklyn).
+ *
+ * @see RebindSupport
+ */
+public interface FeedMemento extends Memento {
+
+ Map<String, Object> getConfig();
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/LocationMemento.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/LocationMemento.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/LocationMemento.java
new file mode 100644
index 0000000..016db01
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/LocationMemento.java
@@ -0,0 +1,38 @@
+/*
+ * 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.api.mgmt.rebind.mementos;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
+
+/**
+ * Represents the state of a location, so that it can be reconstructed (e.g. after restarting brooklyn).
+ *
+ * @see RebindSupport
+ *
+ * @author aled
+ */
+public interface LocationMemento extends TreeNode, Memento {
+
+ Map<String, Object> getLocationConfig();
+ Set<String> getLocationConfigUnused();
+ String getLocationConfigDescription();
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/Memento.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/Memento.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/Memento.java
new file mode 100644
index 0000000..5911f28
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/Memento.java
@@ -0,0 +1,85 @@
+/*
+ * 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.api.mgmt.rebind.mementos;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
+import org.apache.brooklyn.api.objs.EntityAdjunct;
+
+/**
+ * Represents the internal state of something in brooklyn, so that it can be reconstructed (e.g. after restarting brooklyn).
+ *
+ * @see RebindSupport
+ *
+ * @author aled
+ */
+public interface Memento extends Serializable {
+
+ /**
+ * The version of brooklyn used when this memento was generated.
+ */
+ String getBrooklynVersion();
+
+ String getId();
+
+ public String getType();
+
+ public String getCatalogItemId();
+
+ public String getDisplayName();
+
+ /**
+ * A (weakly-typed) property set for this memento.
+ * These can be used to avoid sub-classing the entity memento, but developers can sub-class to get strong typing if desired.
+ *
+ * @deprecated since 0.7.0; use config/attributes so generic persistence will work, rather than requiring "custom fields"
+ */
+ @Deprecated
+ public Object getCustomField(String name);
+
+ /**
+ * @deprecated since 0.7.0; use config/attributes so generic persistence will work, rather than requiring "custom fields"
+ */
+ @Deprecated
+ public Map<String, ? extends Object> getCustomFields();
+
+ public String toVerboseString();
+
+ public void injectTypeClass(Class<?> clazz);
+
+ /**
+ * Returns the injected type class, or null if not injected.
+ * <p>
+ * This is useful for ensuring the correct classloader is used (e.g. for {@link EntityMemento}
+ * previously calling {@code EntityTypes.getDefinedSensors(getType())}.
+ */
+ public Class<?> getTypeClass();
+
+ public Collection<Object> getTags();
+
+ public Map<String,Set<String>> getRelations();
+
+ /** Null for {@link Entity}, but important for adjuncts; see {@link EntityAdjunct#getUniqueTag()} */
+ public String getUniqueTag();
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/PolicyMemento.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/PolicyMemento.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/PolicyMemento.java
new file mode 100644
index 0000000..bfec7af
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/PolicyMemento.java
@@ -0,0 +1,35 @@
+/*
+ * 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.api.mgmt.rebind.mementos;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
+
+/**
+ * Represents the state of an policy, so that it can be reconstructed (e.g. after restarting brooklyn).
+ *
+ * @see RebindSupport
+ *
+ * @author aled
+ */
+public interface PolicyMemento extends Memento {
+
+ Map<String, Object> getConfig();
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/TreeNode.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/TreeNode.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/TreeNode.java
new file mode 100644
index 0000000..cde6a34
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/TreeNode.java
@@ -0,0 +1,48 @@
+/*
+ * 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.api.mgmt.rebind.mementos;
+
+import java.util.List;
+
+/**
+ * A simple tree structure, where a node references a parent and children using their ids.
+ *
+ * e.g. could be used to represent the entity hierarchy within mementos, where the
+ * String is the id of parent/child entities.
+ *
+ * @author aled
+ */
+public interface TreeNode {
+
+ /**
+ * The id of this node in the tree. This id will be used by the parent's getChildren(),
+ * and by each child's getParent().
+ */
+ String getId();
+
+ /**
+ * The id of the parent entity, or null if none.
+ */
+ String getParent();
+
+ /**
+ * The ids of the children.
+ */
+ List<String> getChildren();
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObject.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObject.java b/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObject.java
new file mode 100644
index 0000000..b42bc58
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObject.java
@@ -0,0 +1,169 @@
+/*
+ * 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.api.objs;
+
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.Group;
+import org.apache.brooklyn.api.mgmt.SubscriptionContext;
+import org.apache.brooklyn.api.mgmt.SubscriptionHandle;
+import org.apache.brooklyn.api.mgmt.SubscriptionManager;
+import org.apache.brooklyn.api.relations.RelationshipType;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Super-type of entity, location, policy and enricher.
+ */
+public interface BrooklynObject extends Identifiable, Configurable {
+
+ /**
+ * A display name; recommended to be a concise single-line description.
+ */
+ String getDisplayName();
+
+ /**
+ * The catalog item ID this object was loaded from.
+ * <p>
+ * This can be used to understand the appropriate classloading context,
+ * such as for versioning purposes, as well as meta-information such as
+ * branding (maybe you can even get an icon) and
+ * potentially things like resource lifecycle (if a software version is being sunsetted).
+ * <p>
+ * In some cases this may be set heuristically from context and so may not be accurate.
+ * Callers can set an explicit catalog item ID if inferencing is not correct.
+ */
+ String getCatalogItemId();
+
+ /**
+ * Tags are arbitrary objects which can be attached to an entity for subsequent reference.
+ * They must not be null (as {@link ImmutableMap} may be used under the covers; also there is little point!);
+ * and they should be amenable to our persistence (on-disk serialization) and our JSON serialization in the REST API.
+ */
+ TagSupport tags();
+
+ /**
+ * Subscriptions are the mechanism for receiving notifications of sensor-events (e.g. attribute-changed) from
+ * other entities.
+ */
+ SubscriptionSupport subscriptions();
+
+ /**
+ * Relations specify a typed, directed connection between two entities.
+ * Generic type is overridden in sub-interfaces.
+ */
+ public RelationSupport<?> relations();
+
+ public interface TagSupport {
+ /**
+ * @return An immutable copy of the set of tags on this entity.
+ * Note {@link #containsTag(Object)} will be more efficient,
+ * and {@link #addTag(Object)} and {@link #removeTag(Object)} will not work on the returned set.
+ */
+ @Nonnull Set<Object> getTags();
+
+ boolean containsTag(@Nonnull Object tag);
+
+ boolean addTag(@Nonnull Object tag);
+
+ boolean addTags(@Nonnull Iterable<?> tags);
+
+ boolean removeTag(@Nonnull Object tag);
+ }
+
+ @Beta
+ public interface SubscriptionSupport {
+ /**
+ * Allow us to subscribe to data from a {@link Sensor} on another entity.
+ *
+ * @return a subscription id which can be used to unsubscribe
+ *
+ * @see SubscriptionManager#subscribe(Map, Entity, Sensor, SensorEventListener)
+ */
+ @Beta
+ <T> SubscriptionHandle subscribe(Entity producer, Sensor<T> sensor, SensorEventListener<? super T> listener);
+
+ /**
+ * Allow us to subscribe to data from a {@link Sensor} on another entity.
+ *
+ * @return a subscription id which can be used to unsubscribe
+ *
+ * @see SubscriptionManager#subscribe(Map, Entity, Sensor, SensorEventListener)
+ */
+ @Beta
+ <T> SubscriptionHandle subscribe(Map<String, ?> flags, Entity producer, Sensor<T> sensor, SensorEventListener<? super T> listener);
+
+ /** @see SubscriptionManager#subscribeToChildren(Map, Entity, Sensor, SensorEventListener) */
+ @Beta
+ <T> SubscriptionHandle subscribeToChildren(Entity parent, Sensor<T> sensor, SensorEventListener<? super T> listener);
+
+ /** @see SubscriptionManager#subscribeToMembers(Group, Sensor, SensorEventListener) */
+ @Beta
+ <T> SubscriptionHandle subscribeToMembers(Group group, Sensor<T> sensor, SensorEventListener<? super T> listener);
+
+ /**
+ * Unsubscribes from the given producer.
+ *
+ * @see SubscriptionContext#unsubscribe(SubscriptionHandle)
+ */
+ @Beta
+ boolean unsubscribe(Entity producer);
+
+ /**
+ * Unsubscribes the given handle.
+ *
+ * @see SubscriptionContext#unsubscribe(SubscriptionHandle)
+ */
+ @Beta
+ boolean unsubscribe(Entity producer, SubscriptionHandle handle);
+
+ /**
+ * Unsubscribes the given handle.
+ *
+ * It is (currently) more efficient to also pass in the producer -
+ * see {@link SubscriptionSupport#unsubscribe(Entity, SubscriptionHandle)}
+ */
+ boolean unsubscribe(SubscriptionHandle handle);
+ }
+
+ public interface RelationSupport<T extends BrooklynObject> {
+ /** Adds a relationship of the given type from this object pointing at the given target,
+ * and ensures that the inverse relationship (if there is one) is present at the target pointing back at this object.
+ */
+ public <U extends BrooklynObject> void add(RelationshipType<? super T,? super U> relationship, U target);
+
+ /** Removes any and all relationships of the given type from this object pointing at the given target,
+ * and ensures that the inverse relationships (if there are one) are also removed.
+ */
+ public <U extends BrooklynObject> void remove(RelationshipType<? super T,? super U> relationship, U target);
+
+ /** @return the {@link RelationshipType}s originating from this object */
+ public Set<RelationshipType<? super T,? extends BrooklynObject>> getRelationshipTypes();
+
+ /** @return the {@link BrooklynObject}s which are targets of the given {@link RelationshipType} */
+ public <U extends BrooklynObject> Set<U> getRelations(RelationshipType<? super T,U> relationshipType);
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObjectType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObjectType.java b/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObjectType.java
new file mode 100644
index 0000000..e0ef84c
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynObjectType.java
@@ -0,0 +1,79 @@
+/*
+ * 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.api.objs;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.policy.Policy;
+import org.apache.brooklyn.api.policy.PolicySpec;
+import org.apache.brooklyn.api.sensor.Enricher;
+import org.apache.brooklyn.api.sensor.EnricherSpec;
+import org.apache.brooklyn.api.sensor.Feed;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.CaseFormat;
+
+@Beta
+public enum BrooklynObjectType {
+ // these are correctly type-checked by i can't tell how to get java not to warn!
+ @SuppressWarnings("unchecked") ENTITY(Entity.class, EntitySpec.class, "entities"),
+ @SuppressWarnings("unchecked") LOCATION(Location.class, LocationSpec.class, "locations"),
+ @SuppressWarnings("unchecked") POLICY(Policy.class, PolicySpec.class, "policies"),
+ @SuppressWarnings("unchecked") ENRICHER(Enricher.class, EnricherSpec.class, "enrichers"),
+ FEED(Feed.class, null, "feeds"),
+ CATALOG_ITEM(CatalogItem.class, null, "catalog"),
+ UNKNOWN(null, null, "unknown");
+
+ private final Class<? extends BrooklynObject> interfaceType;
+ private final Class<? extends AbstractBrooklynObjectSpec<?,?>> specType;
+ private final String subPathName;
+
+ <T extends BrooklynObject,K extends AbstractBrooklynObjectSpec<T,K>> BrooklynObjectType(Class<T> interfaceType, Class<K> specType, String subPathName) {
+ this.interfaceType = interfaceType;
+ this.specType = specType;
+ this.subPathName = subPathName;
+ }
+ public String toCamelCase() {
+ return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, this.name());
+ }
+
+ public String getSubPathName() {
+ return subPathName;
+ }
+
+ public Class<? extends BrooklynObject> getInterfaceType() {
+ return interfaceType;
+ }
+
+ public Class<? extends AbstractBrooklynObjectSpec<?, ?>> getSpecType() {
+ return specType;
+ }
+
+ public static BrooklynObjectType of(BrooklynObject instance) {
+ for (BrooklynObjectType t: values()) {
+ if (t.getInterfaceType()!=null && t.getInterfaceType().isInstance(instance))
+ return t;
+ }
+ return UNKNOWN;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynType.java b/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynType.java
new file mode 100644
index 0000000..72d0be9
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/objs/BrooklynType.java
@@ -0,0 +1,57 @@
+/*
+ * 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.api.objs;
+
+import java.io.Serializable;
+import java.util.Set;
+
+import org.apache.brooklyn.config.ConfigKey;
+
+/**
+ * Gives type information for a {@link BrooklynObject}. It is an immutable snapshot.
+ *
+ * It reflects a given brooklyn object at the time the snapshot was created: if anything
+ * were added or removed on-the-fly then those changes will be included in subsequent
+ * snapshots. Therefore instances of a given class could have different {@link BrooklynType}s.
+ */
+// TODO rename as BrooklynObjectSignature or BrooklynObjectMetadata;
+// or (perhaps better and easier to retire deprecated usage, if that is required?)
+// introduce new mechanism for storing accessing this information
+public interface BrooklynType extends Serializable {
+
+ /**
+ * The type name of this entity (normally the fully qualified class name).
+ */
+ String getName();
+
+ /**
+ * The simple type name of this entity (normally the unqualified class name).
+ */
+ String getSimpleName();
+
+ /**
+ * ConfigKeys available on this entity.
+ */
+ Set<ConfigKey<?>> getConfigKeys();
+
+ /**
+ * The ConfigKey with the given name, or null if not found.
+ */
+ ConfigKey<?> getConfigKey(String name);
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/objs/Configurable.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/objs/Configurable.java b/api/src/main/java/org/apache/brooklyn/api/objs/Configurable.java
new file mode 100644
index 0000000..d7f2935
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/objs/Configurable.java
@@ -0,0 +1,101 @@
+/*
+ * 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.api.objs;
+
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Something that has mutable config, such as an entity or policy.
+ *
+ * @author aled
+ */
+public interface Configurable {
+
+ // FIXME Moved from core project to api project, as part of moving EntityLocal.
+ // (though maybe it's fine here?)
+
+ /**
+ * @return the old value, or null if there was not one
+ * @deprecated since 0.7.0; use {@link ConfigurationSupport#set(ConfigKey, Object)}, such as {@code config().set(key, val)}
+ */
+ @Deprecated
+ public <T> T setConfig(ConfigKey<T> key, T val);
+
+ /**
+ * Convenience for calling {@link ConfigurationSupport#get(ConfigKey)},
+ * via code like {@code config().get(key)}.
+ *
+ * @since 0.9.0
+ */
+ <T> T getConfig(ConfigKey<T> key);
+
+ ConfigurationSupport config();
+
+ @Beta
+ public interface ConfigurationSupport {
+
+ /**
+ * Gets the given configuration value for this entity, in the following order of precedence:
+ * <ol>
+ * <li> value (including null) explicitly set on the entity
+ * <li> value (including null) explicitly set on an ancestor (inherited)
+ * <li> a default value (including null) on the best equivalent static key of the same name declared on the entity
+ * (where best equivalence is defined as preferring a config key which extends another,
+ * as computed in EntityDynamicType.getConfigKeys)
+ * <li> a default value (including null) on the key itself
+ * <li> null
+ * </ol>
+ */
+ <T> T get(ConfigKey<T> key);
+
+ /**
+ * @see {@link #getConfig(ConfigKey)}
+ */
+ <T> T get(HasConfigKey<T> key);
+
+ /**
+ * Sets the config to the given value.
+ */
+ <T> T set(ConfigKey<T> key, T val);
+
+ /**
+ * @see {@link #setConfig(HasConfigKey, Object)}
+ */
+ <T> T set(HasConfigKey<T> key, T val);
+
+ /**
+ * Sets the config to the value returned by the task.
+ *
+ * Returns immediately without blocking; subsequent calls to {@link #getConfig(ConfigKey)}
+ * will execute the task, and block until the task completes.
+ *
+ * @see {@link #setConfig(ConfigKey, Object)}
+ */
+ <T> T set(ConfigKey<T> key, Task<T> val);
+
+ /**
+ * @see {@link #setConfig(ConfigKey, Task)}
+ */
+ <T> T set(HasConfigKey<T> key, Task<T> val);
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/objs/EntityAdjunct.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/objs/EntityAdjunct.java b/api/src/main/java/org/apache/brooklyn/api/objs/EntityAdjunct.java
new file mode 100644
index 0000000..674d7f2
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/objs/EntityAdjunct.java
@@ -0,0 +1,53 @@
+/*
+ * 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.api.objs;
+
+import javax.annotation.Nullable;
+
+/**
+ * EntityAdjuncts are supplementary logic that can be attached to Entities,
+ * such as providing sensor enrichment or event-driven policy behavior
+ */
+public interface EntityAdjunct extends BrooklynObject {
+ /**
+ * A unique id for this adjunct, typically created by the system with no meaning
+ */
+ @Override
+ String getId();
+
+ /**
+ * Whether the adjunct is destroyed
+ */
+ boolean isDestroyed();
+
+ /**
+ * Whether the adjunct is available/active, ie started and not stopped or interrupted
+ */
+ boolean isRunning();
+
+ /**
+ * An optional tag used to identify adjuncts with a specific purpose, typically created by the caller.
+ * This is used to prevent multiple instances with the same purpose from being created,
+ * and to access and customize adjuncts so created.
+ * <p>
+ * This will be included in the call to {@link #getTags()}.
+ */
+ @Nullable String getUniqueTag();
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/objs/HasShortName.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/objs/HasShortName.java b/api/src/main/java/org/apache/brooklyn/api/objs/HasShortName.java
new file mode 100644
index 0000000..3d13337
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/objs/HasShortName.java
@@ -0,0 +1,26 @@
+/*
+ * 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.api.objs;
+
+public interface HasShortName {
+
+ /** gets a short name, for human-friendly identification e.g. inside the name of a VM */
+ String getShortName();
+
+}