brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aleds...@apache.org
Subject [07/29] git commit: main cleanup of brooklyn HA and upgrade
Date Mon, 03 Nov 2014 15:51:51 GMT
main cleanup of brooklyn HA and upgrade


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

Branch: refs/heads/master
Commit: 44382b7ca60612711786ea639636484a326aa5ab
Parents: d66c440
Author: Alex Heneveld <alex.heneveld@cloudsoftcorp.com>
Authored: Sat Oct 18 01:44:32 2014 +0100
Committer: Alex Heneveld <alex.heneveld@cloudsoftcorp.com>
Committed: Fri Oct 31 09:38:19 2014 -0500

----------------------------------------------------------------------
 .../brooklyn/config/BrooklynProperties.java     |  1 +
 .../location/basic/BasicLocationRegistry.java   |  4 +-
 .../java/brooklyn/util/config/ConfigBag.java    |  2 +-
 .../entity/brooklynnode/BrooklynNode.java       |  6 +-
 .../entity/brooklynnode/BrooklynNodeImpl.java   |  1 +
 .../brooklynnode/BrooklynUpgradeEffector.java   | 83 +++++++++++++++++---
 .../entity/brooklynnode/brooklyn-node.yaml      |  3 +-
 .../java/brooklyn/util/repeat/Repeater.java     |  5 ++
 8 files changed, 89 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44382b7c/core/src/main/java/brooklyn/config/BrooklynProperties.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/config/BrooklynProperties.java b/core/src/main/java/brooklyn/config/BrooklynProperties.java
index 516784c..63c2289 100644
--- a/core/src/main/java/brooklyn/config/BrooklynProperties.java
+++ b/core/src/main/java/brooklyn/config/BrooklynProperties.java
@@ -433,6 +433,7 @@ public class BrooklynProperties extends LinkedHashMap implements StringConfigMap
 
     @Override
     public <T> T getConfig(ConfigKey<T> key, T defaultValue) {
+        // TODO does not support MapConfigKey etc where entries use subkey notation; for
now, access using submap
         if (!containsKey(key.getName())) {
             if (defaultValue!=null) return defaultValue;
             return key.getDefaultValue();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44382b7c/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java b/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
index 09f69e7..365b347 100644
--- a/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
+++ b/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
@@ -153,9 +153,9 @@ public class BasicLocationRegistry implements LocationRegistry {
     public void updateDefinedLocations() {
         synchronized (definedLocations) {
             // first read all properties starting  brooklyn.location.named.xxx
-            // (would be nice to move to a better way, then deprecate this approach, but
first
+            // (would be nice to move to a better way, e.g. yaml, then deprecate this approach,
but first
             // we need ability/format for persisting named locations, and better support
for adding+saving via REST/GUI)
-            int count = 0;
+            int count = 0; 
             String NAMED_LOCATION_PREFIX = "brooklyn.location.named.";
             ConfigMap namedLocationProps = mgmt.getConfig().submap(ConfigPredicates.startingWith(NAMED_LOCATION_PREFIX));
             for (String k: namedLocationProps.asMapWithStringKeys().keySet()) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44382b7c/core/src/main/java/brooklyn/util/config/ConfigBag.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/config/ConfigBag.java b/core/src/main/java/brooklyn/util/config/ConfigBag.java
index e40329a..c57098b 100644
--- a/core/src/main/java/brooklyn/util/config/ConfigBag.java
+++ b/core/src/main/java/brooklyn/util/config/ConfigBag.java
@@ -397,7 +397,7 @@ public class ConfigBag {
     }
 
     protected <T> T get(ConfigKey<T> key, boolean markUsed) {
-        // TODO for now, no evaluation -- closure content / smart (self-extracting) keys
are NOT supported
+        // TODO for now, no evaluation -- maps / closure content / other smart (self-extracting)
keys are NOT supported
         // (need a clean way to inject that behaviour, as well as desired TypeCoercions)
         if (config.containsKey(key.getName()))
             return coerceFirstNonNullKeyValue(key, getStringKey(key.getName(), markUsed));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44382b7c/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java
index 16fdca2..3d8683f 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java
@@ -97,7 +97,7 @@ public interface BrooklynNode extends SoftwareProcess, UsesJava {
 
     @SetFromFlag("managementPassword")
     ConfigKey<String> MANAGEMENT_PASSWORD =
-            ConfigKeys.newStringConfigKey("brooklynnode.managementPassword", "Password for
MANAGEMENT_USER", "password");
+            ConfigKeys.newStringConfigKey("brooklynnode.managementPassword", "Password for
MANAGEMENT_USER", null);
 
     /** useful e.g. with {@link BashCommands#generateKeyInDotSshIdRsaIfNotThere() } */
     @SetFromFlag("extraCustomizationScript")
@@ -159,11 +159,11 @@ public interface BrooklynNode extends SoftwareProcess, UsesJava {
     
     @SetFromFlag("brooklynLocalPropertiesUri")
     public static final ConfigKey<String> BROOKLYN_LOCAL_PROPERTIES_URI = ConfigKeys.newStringConfigKey(
-            "brooklynnode.brooklynproperties.local.uri", "URI for the launch-specific brooklyn
properties file (uploaded to ~/.brooklyn/brooklyn.properties)", null);
+            "brooklynnode.brooklynproperties.local.uri", "URI for the launch-specific brooklyn
properties file", null);
 
     @SetFromFlag("brooklynLocalPropertiesContents")
     public static final ConfigKey<String> BROOKLYN_LOCAL_PROPERTIES_CONTENTS = ConfigKeys.newStringConfigKey(
-            "brooklynnode.brooklynproperties.local.contents", "Contents for the launch-specific
brooklyn properties file (uploaded to ~/.brooklyn/brooklyn.properties)", null);
+            "brooklynnode.brooklynproperties.local.contents", "Contents for the launch-specific
brooklyn properties file", null);
     
     // For use in testing primarily
     @SetFromFlag("brooklynCatalogRemotePath")

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44382b7c/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 6416970..6aa2420 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -109,6 +109,7 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
     @Override
     protected void preStop() {
         super.preStop();
+
         // Shutdown only if accessible: any of stop_* could have already been called.
         // Don't check serviceUp=true because stop() will already have set serviceUp=false
&& expectedState=stopping
         if (Boolean.TRUE.equals(getAttribute(BrooklynNode.WEB_CONSOLE_ACCESSIBLE))) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44382b7c/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynUpgradeEffector.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynUpgradeEffector.java
b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynUpgradeEffector.java
index 08da8d4..a55f077 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynUpgradeEffector.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynUpgradeEffector.java
@@ -19,29 +19,48 @@
 package brooklyn.entity.brooklynnode;
 
 import java.util.Map;
+import java.util.concurrent.Callable;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.Effector;
+import brooklyn.entity.Entity;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.effector.EffectorBody;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.entity.software.SshEffectorTasks;
+import brooklyn.event.AttributeSensor;
 import brooklyn.event.basic.MapConfigKey;
+import brooklyn.management.TaskAdaptable;
+import brooklyn.management.ha.HighAvailabilityMode;
+import brooklyn.management.ha.ManagementNodeState;
 import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.exceptions.ReferenceWithError;
+import brooklyn.util.guava.Functionals;
 import brooklyn.util.net.Urls;
+import brooklyn.util.repeat.Repeater;
 import brooklyn.util.task.DynamicTasks;
 import brooklyn.util.task.Tasks;
+import brooklyn.util.text.Identifiers;
+import brooklyn.util.time.Duration;
 
+import com.google.common.base.Functions;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
 import com.google.common.reflect.TypeToken;
 
 @SuppressWarnings("serial")
+/** Upgrades a brooklyn node in-place on the box, by creating a child brooklyn node and ensuring
it can rebind in HOT_STANDBY;
+ * requires the target node to have persistence enabled 
+ */
 public class BrooklynUpgradeEffector {
 
     private static final Logger log = LoggerFactory.getLogger(BrooklynUpgradeEffector.class);
@@ -70,23 +89,32 @@ public class BrooklynUpgradeEffector {
                 parameters.putAll(extra);
             }
             log.debug(this+" upgrading, using "+parameters);
-            entity().getConfigMap().addToLocalBag(parameters.getAllConfig());
+            
+            // TODO require entity() node state master or hot standby AND require persistence
enabled, or a new 'force_attempt_upgrade' parameter to be applied
+            // TODO could have a 'skip_dry_run_upgrade' parameter
+            // TODO could support 'dry_run_only' parameter, with optional resumption tasks
(eg new dynamic effector)
 
             // 1 add new brooklyn version entity as child (so uses same machine), with same
config apart from things in parameters
             final BrooklynNode dryRunChild = entity().addChild(EntitySpec.create(BrooklynNode.class).configure(parameters.getAllConfig())
                 .displayName("Upgraded Version Dry-Run Node")
-                // TODO enforce hot-standby
+                // force dir and label back to their defaults (do not piggy back on what
may have already been installed)
                 .configure(BrooklynNode.INSTALL_DIR, BrooklynNode.INSTALL_DIR.getConfigKey().getDefaultValue())
-                .configure(BrooklynNode.INSTALL_UNIQUE_LABEL, BrooklynNode.INSTALL_UNIQUE_LABEL.getDefaultValue()));
+                .configure(BrooklynNode.INSTALL_UNIQUE_LABEL, "upgrade-tmp-"+Identifiers.makeRandomId(8))
+                .configure(parameters.getAllConfig()));
+            
+            //force this to start as hot-standby
+            String launchCommand = dryRunChild.getConfig(BrooklynNode.LAUNCH_COMMAND);
+            ((EntityInternal)dryRunChild).setConfig(BrooklynNode.LAUNCH_COMMAND, launchCommand
+ " --highAvailability "+HighAvailabilityMode.HOT_STANDBY);
+            
             Entities.manage(dryRunChild);
-            final String versionUid = dryRunChild.getId();
-            ((EntityInternal)dryRunChild).setDisplayName("Upgraded Version Dry-Run Node ("+versionUid+")");
+            final String dryRunNodeUid = dryRunChild.getId();
+            ((EntityInternal)dryRunChild).setDisplayName("Dry-Run Upgraded Brooklyn Node
("+dryRunNodeUid+")");
 
             DynamicTasks.queue(Effectors.invocation(dryRunChild, BrooklynNode.START, ConfigBag.EMPTY));
             
             // 2 confirm hot standby status
-            // TODO poll, wait for HOT_STANDBY; error if anything else (other than STARTING)
-//            status = dryRun.getAttribute(BrooklynNode.STATUS);
+            DynamicTasks.queue(newWaitForAttributeTask(dryRunChild, BrooklynNode.MANAGEMENT_NODE_STATE,

+                Predicates.equalTo(ManagementNodeState.HOT_STANDBY), Duration.TWO_MINUTES));
 
             // 3 stop new version
             // 4 stop old version
@@ -100,7 +128,7 @@ public class BrooklynUpgradeEffector {
                 @Override
                 public void run() {
                     String runDir = entity().getAttribute(SoftwareProcess.RUN_DIR);
-                    String bkDir = Urls.mergePaths(runDir, "..", Urls.getBasename(runDir)+"-backups",
versionUid);
+                    String bkDir = Urls.mergePaths(runDir, "..", Urls.getBasename(runDir)+"-backups",
dryRunNodeUid);
                     String dryRunDir = Preconditions.checkNotNull(dryRunChild.getAttribute(SoftwareProcess.RUN_DIR));
                     log.debug(this+" storing backup of previous version in "+bkDir);
                     DynamicTasks.queue(SshEffectorTasks.ssh(
@@ -113,6 +141,8 @@ public class BrooklynUpgradeEffector {
                 }
             }).build());
 
+            entity().getConfigMap().addToLocalBag(parameters.getAllConfig());
+            
             // 6 start this entity, running the new version
             DynamicTasks.queue(Effectors.invocation(entity(), BrooklynNode.START, ConfigBag.EMPTY));
             
@@ -121,6 +151,41 @@ public class BrooklynUpgradeEffector {
             
             return null;
         }
+
     }
-    
+
+    private static class WaitForRepeaterCallable implements Callable<Boolean> {
+        protected Repeater repeater;
+        protected boolean requireTrue;
+
+        public WaitForRepeaterCallable(Repeater repeater, boolean requireTrue) {
+            this.repeater = repeater;
+            this.requireTrue = requireTrue;
+        }
+
+        @Override
+        public Boolean call() {
+            ReferenceWithError<Boolean> result = repeater.runKeepingError();
+            if (Boolean.TRUE.equals(result.getWithoutError()))
+                return true;
+            if (result.hasError()) 
+                throw Exceptions.propagate(result.getError());
+            if (requireTrue)
+                throw new IllegalStateException("timeout - "+repeater.getDescription());
+            return false;
+        }
+    }
+
+    private static <T> TaskAdaptable<Boolean> newWaitForAttributeTask(Entity
node, AttributeSensor<T> sensor, Predicate<T> condition, Duration timeout) {
+        return awaiting( Repeater.create("waiting on "+node+" "+sensor.getName()+" "+condition)
+                    .backoff(Duration.millis(10), 1.5, Duration.millis(200))
+                    .limitTimeTo(timeout==null ? Duration.PRACTICALLY_FOREVER : timeout)
+                    .until(Functionals.callable(Functions.forPredicate(EntityPredicates.attributeSatisfies(sensor,
condition)), node)),
+                    true);
+    }
+
+    private static TaskAdaptable<Boolean> awaiting(Repeater repeater, boolean requireTrue)
{
+        return Tasks.<Boolean>builder().name(repeater.getDescription()).body(new WaitForRepeaterCallable(repeater,
requireTrue)).build();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44382b7c/software/base/src/test/resources/brooklyn/entity/brooklynnode/brooklyn-node.yaml
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/brooklyn/entity/brooklynnode/brooklyn-node.yaml
b/software/base/src/test/resources/brooklyn/entity/brooklynnode/brooklyn-node.yaml
index a53e9de..9e6300f 100644
--- a/software/base/src/test/resources/brooklyn/entity/brooklynnode/brooklyn-node.yaml
+++ b/software/base/src/test/resources/brooklyn/entity/brooklynnode/brooklyn-node.yaml
@@ -20,7 +20,8 @@
 services:
 - type: brooklyn.entity.brooklynnode.BrooklynNode
   ## to use a local file, specify something such as the following:
-  # downloadUrl: ~/.m2/repository/io/brooklyn/brooklyn-dist/0.7.0-SNAPSHOT/brooklyn-dist-0.7.0-SNAPSHOT-dist.tar.gz
+  downloadUrl: file:///Users/alex/.m2/repository/org/apache/brooklyn/brooklyn-dist/0.7.0-SNAPSHOT/brooklyn-dist-0.7.0-SNAPSHOT-dist.tar.gz
   # downloadUrl: file:///tmp/brooklyn-dist-0.7.0-SNAPSHOT-dist.tar.gz
 
+## NB if deploying to a remote machine you must also supply management{Username,Password}
and a brooklyn properties with those values set 
 location: localhost

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44382b7c/utils/common/src/main/java/brooklyn/util/repeat/Repeater.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/repeat/Repeater.java b/utils/common/src/main/java/brooklyn/util/repeat/Repeater.java
index 1aafc1f..1e3e188 100644
--- a/utils/common/src/main/java/brooklyn/util/repeat/Repeater.java
+++ b/utils/common/src/main/java/brooklyn/util/repeat/Repeater.java
@@ -382,4 +382,9 @@ public class Repeater {
             Time.sleep(delayThisIteration);
         }
     }
+    
+    public String getDescription() {
+        return description;
+    }
+    
 }


Mime
View raw message