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(); + +}
