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/01/30 04:45:51 UTC

[05/10] incubator-brooklyn git commit: support dynamic cluster restart

support dynamic cluster restart


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/ecbd90e2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/ecbd90e2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/ecbd90e2

Branch: refs/heads/master
Commit: ecbd90e22c989c7d24983942b7426c8a17c29463
Parents: 9141c99
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Jan 21 13:55:30 2016 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Jan 21 13:55:53 2016 +0000

----------------------------------------------------------------------
 .../brooklyn/core/effector/Effectors.java       | 16 +++++++++++--
 .../brooklyn/entity/group/DynamicCluster.java   |  8 +++++++
 .../entity/group/DynamicClusterImpl.java        | 24 +++++++++++++++++++-
 3 files changed, 45 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ecbd90e2/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java
index 63ea52d..9b10d1d 100644
--- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java
+++ b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java
@@ -173,14 +173,26 @@ public class Effectors {
         return ConfigKeys.newConfigKey(paramType.getParameterClass(), paramType.getName(), paramType.getDescription(), paramType.getDefaultValue());
     }
 
-    /** returns an unsubmitted task which will invoke the given effector on the given entities;
-     * return type is Task<List<T>> (but haven't put in the blood sweat toil and tears to make the generics work) */
+    /** convenience for {@link #invocationParallel(Effector, Map, Iterable)} */
     public static TaskAdaptable<List<?>> invocation(Effector<?> eff, Map<?,?> params, Iterable<? extends Entity> entities) {
+        return invocationParallel(eff, params, entities);
+    }
+    
+    /** returns an unsubmitted task which will invoke the given effector on the given entities in parallel;
+     * return type is Task<List<T>> (but haven't put in the blood sweat toil and tears to make the generics work) */
+    public static TaskAdaptable<List<?>> invocationParallel(Effector<?> eff, Map<?,?> params, Iterable<? extends Entity> entities) {
         List<TaskAdaptable<?>> tasks = new ArrayList<TaskAdaptable<?>>();
         for (Entity e: entities) tasks.add(invocation(e, eff, params));
         return Tasks.parallel("invoking "+eff+" on "+tasks.size()+" node"+(Strings.s(tasks.size())), tasks.toArray(new TaskAdaptable[tasks.size()]));
     }
 
+    /** as {@link #invocationParallel(Effector, Map, Iterable)} but executing sequentially */
+    public static TaskAdaptable<List<?>> invocationSequential(Effector<?> eff, Map<?,?> params, Iterable<? extends Entity> entities) {
+        List<TaskAdaptable<?>> tasks = new ArrayList<TaskAdaptable<?>>();
+        for (Entity e: entities) tasks.add(invocation(e, eff, params));
+        return Tasks.sequential("invoking "+eff+" on "+tasks.size()+" node"+(Strings.s(tasks.size())), tasks.toArray(new TaskAdaptable[tasks.size()]));
+    }
+
     /** returns an unsubmitted task which will invoke the given effector on the given entities
      * (this form of method is a convenience for {@link #invocation(Effector, Map, Iterable)}) */
     public static TaskAdaptable<List<?>> invocation(Effector<?> eff, MutableMap<?, ?> params, Entity ...entities) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ecbd90e2/brooklyn-server/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java
index 781cb0c..f09e72f 100644
--- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java
+++ b/brooklyn-server/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java
@@ -98,6 +98,14 @@ public interface DynamicCluster extends AbstractGroup, Cluster, MemberReplaceabl
 
     MethodEffector<Collection<Entity>> RESIZE_BY_DELTA = new MethodEffector<Collection<Entity>>(DynamicCluster.class, "resizeByDelta");
 
+    @SetFromFlag("restartMode")
+    ConfigKey<String> RESTART_MODE = ConfigKeys.newStringConfigKey(
+            "dynamiccluster.restartMode", 
+            "How this cluster should handle restarts; "
+            + "by default it is disallowed, but this key can specify a different mode. "
+            + "Modes supported by dynamic cluster are 'off', 'sequqential', or 'parallel'. "
+            + "However subclasses can define their own modes or may ignore this.", null);
+
     @SetFromFlag("quarantineFailedEntities")
     ConfigKey<Boolean> QUARANTINE_FAILED_ENTITIES = ConfigKeys.newBooleanConfigKey(
             "dynamiccluster.quarantineFailedEntities", "If true, will quarantine entities that fail to start; if false, will get rid of them (i.e. delete them)", true);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ecbd90e2/brooklyn-server/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
index f434fcf..aaf06c5 100644
--- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
+++ b/brooklyn-server/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
@@ -47,6 +47,7 @@ import org.apache.brooklyn.core.config.Sanitizer;
 import org.apache.brooklyn.core.config.render.RendererHints;
 import org.apache.brooklyn.core.effector.Effectors;
 import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityPredicates;
 import org.apache.brooklyn.core.entity.factory.EntityFactory;
 import org.apache.brooklyn.core.entity.factory.EntityFactoryForLocation;
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
@@ -522,7 +523,28 @@ public class DynamicClusterImpl extends AbstractGroupImpl implements DynamicClus
 
     @Override
     public void restart() {
-        throw new UnsupportedOperationException();
+        String mode = getConfig(RESTART_MODE);
+        if (mode==null) {
+            throw new UnsupportedOperationException("Restart not supported for this cluster: "+RESTART_MODE.getName()+" is not configured.");
+        }
+        if ("off".equalsIgnoreCase(mode)) {
+            throw new UnsupportedOperationException("Restart not supported for this cluster.");
+        }
+        
+        if ("sequential".equalsIgnoreCase(mode)) {
+            ServiceStateLogic.setExpectedState(this, Lifecycle.STARTING);
+            DynamicTasks.queue(Effectors.invocationSequential(Startable.RESTART, null, 
+                Iterables.filter(getChildren(), Predicates.and(Predicates.instanceOf(Startable.class), EntityPredicates.isManaged()))));
+        } else if ("parallel".equalsIgnoreCase(mode)) {
+            ServiceStateLogic.setExpectedState(this, Lifecycle.STARTING);
+            DynamicTasks.queue(Effectors.invocationParallel(Startable.RESTART, null, 
+                Iterables.filter(getChildren(), Predicates.and(Predicates.instanceOf(Startable.class), EntityPredicates.isManaged()))));
+        } else {
+            throw new IllegalArgumentException("Unknown "+RESTART_MODE.getName()+" '"+mode+"'");
+        }
+        
+        DynamicTasks.waitForLast();
+        ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING);
     }
 
     @Override