Move SshEffectorTasks into core’s effector.ssh package

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

Branch: refs/heads/master
Commit: 4820fa46722e980f3b90b55849977c3b115492e0
Parents: 0eab0fa
Author: Aled Sage <[email protected]>
Authored: Wed Aug 19 22:35:40 2015 +0100
Committer: Aled Sage <[email protected]>
Committed: Wed Aug 19 22:35:40 2015 +0100

----------------------------------------------------------------------
 .../effector/core/ssh/SshEffectorTasks.java     | 334 +++++++++++++++++++
 .../util/core/task/ssh/SshEffectorTasks.java    | 329 ------------------
 .../brooklyn/util/core/task/ssh/SshTasks.java   |   1 +
 .../effector/core/ssh/SshEffectorTasksTest.java | 264 +++++++++++++++
 .../core/task/ssh/SshEffectorTasksTest.java     | 264 ---------------
 .../util/core/task/ssh/SshTasksTest.java        |   1 +
 .../brooklyn/demo/CumulusRDFApplication.java    |   2 +-
 .../postgresql/PostgreSqlNodeSaltImpl.java      |   2 +-
 .../entity/salt/SaltLifecycleEffectorTasks.java |   2 +-
 .../apache/brooklyn/entity/salt/SaltTasks.java  |   2 +-
 .../postgresql/PostgreSqlSaltLiveTest.java      |   2 +-
 .../brooklynnode/BrooklynNodeSshDriver.java     |   2 +-
 .../BrooklynNodeUpgradeEffectorBody.java        |   2 +-
 .../entity/chef/ChefLifecycleEffectorTasks.java |   2 +-
 .../brooklyn/entity/chef/ChefSoloTasks.java     |   2 +-
 .../apache/brooklyn/entity/chef/ChefTasks.java  |   2 +-
 .../java/JavaSoftwareProcessSshDriver.java      |   2 +-
 .../entity/machine/MachineEntityImpl.java       |   2 +-
 .../base/AbstractSoftwareProcessSshDriver.java  |   2 +-
 .../MachineLifecycleEffectorTasks.java          |   2 +-
 .../brooklyn/sensor/ssh/SshCommandEffector.java |   4 +-
 .../ChefSoloDriverMySqlEntityLiveTest.java      |   2 +-
 .../mysql/ChefSoloDriverToyMySqlEntity.java     |   2 +-
 .../software/base/SoftwareEffectorTest.java     |   4 +-
 .../test/mysql/AbstractToyMySqlEntityTest.java  |   2 +-
 .../mysql/DynamicToyMySqlEntityBuilder.java     |   2 +-
 .../database/mariadb/MariaDbSshDriver.java      |   2 +-
 .../entity/database/mysql/MySqlSshDriver.java   |   2 +-
 .../PostgreSqlNodeChefImplFromScratch.java      |   2 +-
 .../postgresql/PostgreSqlSshDriver.java         |   2 +-
 .../database/postgresql/PostgreSqlChefTest.java |   2 +-
 .../nosql/cassandra/CassandraNodeSshDriver.java |   2 +-
 .../nosql/couchbase/CouchbaseNodeSshDriver.java |   2 +-
 .../entity/nosql/riak/RiakNodeSshDriver.java    |   2 +-
 .../entity/osgi/karaf/KarafContainerTest.java   |   2 +-
 .../qa/load/SimulatedMySqlNodeImpl.java         |   2 +-
 36 files changed, 632 insertions(+), 625 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/core/src/main/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasks.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasks.java
 
b/core/src/main/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasks.java
new file mode 100644
index 0000000..b904ba7
--- /dev/null
+++ 
b/core/src/main/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasks.java
@@ -0,0 +1,334 @@
+/*
+ * 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.effector.core.ssh;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.config.StringConfigMap;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.ConfigUtils;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.location.internal.LocationInternal;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.effector.core.EffectorBody;
+import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.internal.ssh.SshTool;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskFactory;
+import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
+import org.apache.brooklyn.util.core.task.ssh.SshPutTaskFactory;
+import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
+import org.apache.brooklyn.util.core.task.ssh.SshTasks;
+import 
org.apache.brooklyn.util.core.task.ssh.internal.AbstractSshExecTaskFactory;
+import org.apache.brooklyn.util.core.task.ssh.internal.PlainSshExecTaskFactory;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.ssh.BashCommands;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.collect.Maps;
+
+/**
+ * Conveniences for generating {@link Task} instances to perform SSH 
activities.
+ * <p>
+ * If the {@link SshMachineLocation machine} is not specified directly it
+ * will be inferred from the {@link Entity} context of either the {@link 
Effector}
+ * or the current {@link Task}.
+ * 
+ * @see SshTasks
+ * @since 0.6.0
+ */
+@Beta
+public class SshEffectorTasks {
+
+    private static final Logger log = 
LoggerFactory.getLogger(SshEffectorTasks.class);
+    
+    public static final ConfigKey<Boolean> IGNORE_ENTITY_SSH_FLAGS = 
ConfigKeys.newBooleanConfigKey("ignoreEntitySshFlags",
+        "Whether to ignore any ssh flags (behaviour constraints) set on the 
entity or location " +
+        "where this is running, using only flags explicitly specified", false);
+    
+    /**
+     * Like {@link EffectorBody} but providing conveniences when in an entity 
with a single machine location.
+     */
+    public abstract static class SshEffectorBody<T> extends EffectorBody<T> {
+        
+        /** convenience for accessing the machine */
+        public SshMachineLocation machine() {
+            return EffectorTasks.getSshMachine(entity());
+        }
+
+        /** convenience for generating an {@link PlainSshExecTaskFactory} 
which can be further customised if desired, and then (it must be explicitly) 
queued */
+        public ProcessTaskFactory<Integer> ssh(String ...commands) {
+            return new 
SshEffectorTaskFactory<Integer>(commands).machine(machine());
+        }
+    }
+
+    /** variant of {@link PlainSshExecTaskFactory} which fulfills the {@link 
EffectorTaskFactory} signature so can be used directly as an impl for an 
effector,
+     * also injects the machine automatically; can also be used outwith 
effector contexts, and machine is still injected if it is
+     * run from inside a task at an entity with a single SshMachineLocation */
+    public static class SshEffectorTaskFactory<RET> extends 
AbstractSshExecTaskFactory<SshEffectorTaskFactory<RET>,RET> implements 
EffectorTaskFactory<RET> {
+
+        public SshEffectorTaskFactory(String ...commands) {
+            super(commands);
+        }
+        public SshEffectorTaskFactory(SshMachineLocation machine, String 
...commands) {
+            super(machine, commands);
+        }
+        @Override
+        public ProcessTaskWrapper<RET> newTask(Entity entity, Effector<RET> 
effector, ConfigBag parameters) {
+            markDirty();
+            if (summary==null) summary(effector.getName()+" (ssh)");
+            machine(EffectorTasks.getSshMachine(entity));
+            return newTask();
+        }
+        @Override
+        public synchronized ProcessTaskWrapper<RET> newTask() {
+            Entity entity = 
BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+            if (machine==null) {
+                if (log.isDebugEnabled())
+                    log.debug("Using an ssh task not in an effector without 
any machine; will attempt to infer the machine: "+this);
+                if (entity!=null)
+                    machine(EffectorTasks.getSshMachine(entity));
+            }
+            applySshFlags(getConfig(), entity, getMachine());
+            return super.newTask();
+        }
+        
+        @Override
+        public <T2> SshEffectorTaskFactory<T2> returning(ScriptReturnType 
type) {
+            return (SshEffectorTaskFactory<T2>) super.<T2>returning(type);
+        }
+
+        @Override
+        public SshEffectorTaskFactory<Boolean> returningIsExitCodeZero() {
+            return (SshEffectorTaskFactory<Boolean>) 
super.returningIsExitCodeZero();
+        }
+
+        public SshEffectorTaskFactory<String> 
requiringZeroAndReturningStdout() {
+            return (SshEffectorTaskFactory<String>) 
super.requiringZeroAndReturningStdout();
+        }
+        
+        public <RET2> SshEffectorTaskFactory<RET2> 
returning(Function<ProcessTaskWrapper<?>, RET2> resultTransformation) {
+            return (SshEffectorTaskFactory<RET2>) 
super.returning(resultTransformation);
+        }
+    }
+    
+    public static class SshPutEffectorTaskFactory extends SshPutTaskFactory 
implements EffectorTaskFactory<Void> {
+        public SshPutEffectorTaskFactory(String remoteFile) {
+            super(remoteFile);
+        }
+        public SshPutEffectorTaskFactory(SshMachineLocation machine, String 
remoteFile) {
+            super(machine, remoteFile);
+        }
+        @Override
+        public SshPutTaskWrapper newTask(Entity entity, Effector<Void> 
effector, ConfigBag parameters) {
+            machine(EffectorTasks.getSshMachine(entity));
+            applySshFlags(getConfig(), entity, getMachine());
+            return super.newTask();
+        }
+        @Override
+        public SshPutTaskWrapper newTask() {
+            Entity entity = 
BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+            if (machine==null) {
+                if (log.isDebugEnabled())
+                    log.debug("Using an ssh put task not in an effector 
without any machine; will attempt to infer the machine: "+this);
+                if (entity!=null) {
+                    machine(EffectorTasks.getSshMachine(entity));
+                }
+
+            }
+            applySshFlags(getConfig(), entity, getMachine());
+            return super.newTask();
+        }
+    }
+
+    public static class SshFetchEffectorTaskFactory extends 
SshFetchTaskFactory implements EffectorTaskFactory<String> {
+        public SshFetchEffectorTaskFactory(String remoteFile) {
+            super(remoteFile);
+        }
+        public SshFetchEffectorTaskFactory(SshMachineLocation machine, String 
remoteFile) {
+            super(machine, remoteFile);
+        }
+        @Override
+        public SshFetchTaskWrapper newTask(Entity entity, Effector<String> 
effector, ConfigBag parameters) {
+            machine(EffectorTasks.getSshMachine(entity));
+            applySshFlags(getConfig(), entity, getMachine());
+            return super.newTask();
+        }
+        @Override
+        public SshFetchTaskWrapper newTask() {
+            Entity entity = 
BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+            if (machine==null) {
+                if (log.isDebugEnabled())
+                    log.debug("Using an ssh fetch task not in an effector 
without any machine; will attempt to infer the machine: "+this);
+                if (entity!=null)
+                    machine(EffectorTasks.getSshMachine(entity));
+            }
+            applySshFlags(getConfig(), entity, getMachine());
+            return super.newTask();
+        }
+    }
+
+    public static SshEffectorTaskFactory<Integer> ssh(String ...commands) {
+        return new SshEffectorTaskFactory<Integer>(commands);
+    }
+
+    public static SshEffectorTaskFactory<Integer> ssh(List<String> commands) {
+        return ssh(commands.toArray(new String[commands.size()]));
+    }
+
+    public static SshPutTaskFactory put(String remoteFile) {
+        return new SshPutEffectorTaskFactory(remoteFile);
+    }
+
+    public static SshFetchEffectorTaskFactory fetch(String remoteFile) {
+        return new SshFetchEffectorTaskFactory(remoteFile);
+    }
+
+    /** task which returns 0 if pid is running */
+    public static SshEffectorTaskFactory<Integer> codePidRunning(Integer pid) {
+        return ssh("ps -p "+pid).summary("PID "+pid+" is-running check (exit 
code)").allowingNonZeroExitCode();
+    }
+    
+    /** task which fails if the given PID is not running */
+    public static SshEffectorTaskFactory<?> requirePidRunning(Integer pid) {
+        return codePidRunning(pid).summary("PID "+pid+" is-running check 
(required)").requiringExitCodeZero("Process with PID "+pid+" is required to be 
running");
+    }
+
+    /** as {@link #codePidRunning(Integer)} but returning boolean */
+    public static SshEffectorTaskFactory<Boolean> isPidRunning(Integer pid) {
+        return codePidRunning(pid).summary("PID "+pid+" is-running check 
(boolean)").returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
+            public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { 
return Integer.valueOf(0).equals(input.getExitCode()); }
+        });
+    }
+
+
+    /** task which returns 0 if pid in the given file is running;
+     * method accepts wildcards so long as they match a single file on the 
remote end
+     * <p>
+     * returns 1 if no matching file, 
+     * 1 if matching file but no matching process,
+     * and 2 if 2+ matching files */
+    public static SshEffectorTaskFactory<Integer> codePidFromFileRunning(final 
String pidFile) {
+        return ssh(BashCommands.chain(
+                // this fails, but isn't an error
+                BashCommands.requireTest("-f "+pidFile, "The PID file 
"+pidFile+" does not exist."),
+                // this fails and logs an error picked up later
+                BashCommands.requireTest("`ls "+pidFile+" | wc -w` -eq 1", 
"ERROR: there are multiple matching PID files"),
+                // this fails and logs an error picked up later
+                BashCommands.require("cat "+pidFile, "ERROR: the PID file 
"+pidFile+" cannot be read (permissions?)."),
+                // finally check the process
+                "ps -p `cat "+pidFile+"`")).summary("PID file "+pidFile+" 
is-running check (exit code)")
+                .allowingNonZeroExitCode()
+                .addCompletionListener(new 
Function<ProcessTaskWrapper<?>,Void>() {
+                    public Void apply(ProcessTaskWrapper<?> input) {
+                        if (input.getStderr().contains("ERROR:"))
+                            throw new IllegalStateException("Invalid or 
inaccessible PID filespec: "+pidFile);
+                        return null;
+                    }
+                });
+    }
+    
+    /** task which fails if the pid in the given file is not running (or if 
there is no such PID file);
+     * method accepts wildcards so long as they match a single file on the 
remote end (fails if 0 or 2+ matching files) */
+    public static SshEffectorTaskFactory<?> requirePidFromFileRunning(String 
pidFile) {
+        return codePidFromFileRunning(pidFile)
+                .summary("PID file "+pidFile+" is-running check (required)")
+                .requiringExitCodeZero("Process with PID from file "+pidFile+" 
is required to be running");
+    }
+
+    /** as {@link #codePidFromFileRunning(String)} but returning boolean */
+    public static SshEffectorTaskFactory<Boolean> isPidFromFileRunning(String 
pidFile) {
+        return codePidFromFileRunning(pidFile).summary("PID file "+pidFile+" 
is-running check (boolean)").
+                returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
+                    public Boolean apply(@Nullable ProcessTaskWrapper<?> 
input) { return ((Integer)0).equals(input.getExitCode()); }
+                });
+    }
+
+    /** extracts the values for the main brooklyn.ssh.config.* config keys 
(i.e. those declared in ConfigKeys) 
+     * as declared on the entity, and inserts them in a map using the 
unprefixed state, for ssh.
+     * <p>
+     * currently this is computed for each call, which may be wasteful, but it 
is reliable in the face of config changes.
+     * we could cache the Map.  note that we do _not_ cache (or even own) the 
SshTool; 
+     * the SshTool is created or re-used by the SshMachineLocation making use 
of these properties */
+    @Beta
+    public static Map<String, Object> getSshFlags(Entity entity, Location 
optionalLocation) {
+        ConfigBag allConfig = ConfigBag.newInstance();
+        
+        StringConfigMap globalConfig = 
((EntityInternal)entity).getManagementContext().getConfig();
+        allConfig.putAll(globalConfig.getAllConfig());
+        
+        if (optionalLocation!=null)
+            
allConfig.putAll(((LocationInternal)optionalLocation).config().getBag());
+        
+        allConfig.putAll(((EntityInternal)entity).getAllConfig());
+        
+        Map<String, Object> result = Maps.newLinkedHashMap();
+        for (String keyS : allConfig.getAllConfig().keySet()) {
+            if (keyS.startsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
+                ConfigKey<?> key = ConfigKeys.newConfigKey(Object.class, keyS);
+                
+                Object val = allConfig.getStringKey(keyS);
+                
+                /*
+                 * NOV 2013 changing this to rely on config above being 
inserted in the right order,
+                 * so entity config will be preferred over location, and 
location over global.
+                 * If that is consistent then remove the lines below.
+                 * (We can also accept null entity and so combine with 
SshTasks.getSshFlags.)
+                 */
+                
+//                // have to use raw config to test whether the config is set
+//                Object val = 
((EntityInternal)entity).getConfigMap().getRawConfig(key);
+//                if (val!=null) {
+//                    val = entity.getConfig(key);
+//                } else {
+//                    val = globalConfig.getRawConfig(key);
+//                    if (val!=null) val = globalConfig.getConfig(key);
+//                }
+//                if (val!=null) {
+                    
result.put(ConfigUtils.unprefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, 
key).getName(), val);
+//                }
+            }
+        }
+        return result;
+    }
+
+    private static void applySshFlags(ConfigBag config, Entity entity, 
Location machine) {
+        if (entity!=null) {
+            if (!config.get(IGNORE_ENTITY_SSH_FLAGS)) {
+                config.putIfAbsent(getSshFlags(entity, machine));
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasks.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasks.java
 
b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasks.java
deleted file mode 100644
index 849cd25..0000000
--- 
a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasks.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * 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.util.core.task.ssh;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.config.StringConfigMap;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.config.ConfigUtils;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.location.internal.LocationInternal;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.internal.ssh.SshTool;
-import org.apache.brooklyn.util.core.task.Tasks;
-import 
org.apache.brooklyn.util.core.task.ssh.internal.AbstractSshExecTaskFactory;
-import org.apache.brooklyn.util.core.task.ssh.internal.PlainSshExecTaskFactory;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
-import org.apache.brooklyn.util.ssh.BashCommands;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.collect.Maps;
-
-/**
- * Conveniences for generating {@link Task} instances to perform SSH 
activities.
- * <p>
- * If the {@link SshMachineLocation machine} is not specified directly it
- * will be inferred from the {@link Entity} context of either the {@link 
Effector}
- * or the current {@link Task}.
- * 
- * @see SshTasks
- * @since 0.6.0
- */
-@Beta
-public class SshEffectorTasks {
-
-    private static final Logger log = 
LoggerFactory.getLogger(SshEffectorTasks.class);
-    
-    public static final ConfigKey<Boolean> IGNORE_ENTITY_SSH_FLAGS = 
ConfigKeys.newBooleanConfigKey("ignoreEntitySshFlags",
-        "Whether to ignore any ssh flags (behaviour constraints) set on the 
entity or location " +
-        "where this is running, using only flags explicitly specified", false);
-    
-    /**
-     * Like {@link EffectorBody} but providing conveniences when in an entity 
with a single machine location.
-     */
-    public abstract static class SshEffectorBody<T> extends EffectorBody<T> {
-        
-        /** convenience for accessing the machine */
-        public SshMachineLocation machine() {
-            return EffectorTasks.getSshMachine(entity());
-        }
-
-        /** convenience for generating an {@link PlainSshExecTaskFactory} 
which can be further customised if desired, and then (it must be explicitly) 
queued */
-        public ProcessTaskFactory<Integer> ssh(String ...commands) {
-            return new 
SshEffectorTaskFactory<Integer>(commands).machine(machine());
-        }
-    }
-
-    /** variant of {@link PlainSshExecTaskFactory} which fulfills the {@link 
EffectorTaskFactory} signature so can be used directly as an impl for an 
effector,
-     * also injects the machine automatically; can also be used outwith 
effector contexts, and machine is still injected if it is
-     * run from inside a task at an entity with a single SshMachineLocation */
-    public static class SshEffectorTaskFactory<RET> extends 
AbstractSshExecTaskFactory<SshEffectorTaskFactory<RET>,RET> implements 
EffectorTaskFactory<RET> {
-
-        public SshEffectorTaskFactory(String ...commands) {
-            super(commands);
-        }
-        public SshEffectorTaskFactory(SshMachineLocation machine, String 
...commands) {
-            super(machine, commands);
-        }
-        @Override
-        public ProcessTaskWrapper<RET> newTask(Entity entity, Effector<RET> 
effector, ConfigBag parameters) {
-            markDirty();
-            if (summary==null) summary(effector.getName()+" (ssh)");
-            machine(EffectorTasks.getSshMachine(entity));
-            return newTask();
-        }
-        @Override
-        public synchronized ProcessTaskWrapper<RET> newTask() {
-            Entity entity = 
BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
-            if (machine==null) {
-                if (log.isDebugEnabled())
-                    log.debug("Using an ssh task not in an effector without 
any machine; will attempt to infer the machine: "+this);
-                if (entity!=null)
-                    machine(EffectorTasks.getSshMachine(entity));
-            }
-            applySshFlags(getConfig(), entity, getMachine());
-            return super.newTask();
-        }
-        
-        @Override
-        public <T2> SshEffectorTaskFactory<T2> returning(ScriptReturnType 
type) {
-            return (SshEffectorTaskFactory<T2>) super.<T2>returning(type);
-        }
-
-        @Override
-        public SshEffectorTaskFactory<Boolean> returningIsExitCodeZero() {
-            return (SshEffectorTaskFactory<Boolean>) 
super.returningIsExitCodeZero();
-        }
-
-        public SshEffectorTaskFactory<String> 
requiringZeroAndReturningStdout() {
-            return (SshEffectorTaskFactory<String>) 
super.requiringZeroAndReturningStdout();
-        }
-        
-        public <RET2> SshEffectorTaskFactory<RET2> 
returning(Function<ProcessTaskWrapper<?>, RET2> resultTransformation) {
-            return (SshEffectorTaskFactory<RET2>) 
super.returning(resultTransformation);
-        }
-    }
-    
-    public static class SshPutEffectorTaskFactory extends SshPutTaskFactory 
implements EffectorTaskFactory<Void> {
-        public SshPutEffectorTaskFactory(String remoteFile) {
-            super(remoteFile);
-        }
-        public SshPutEffectorTaskFactory(SshMachineLocation machine, String 
remoteFile) {
-            super(machine, remoteFile);
-        }
-        @Override
-        public SshPutTaskWrapper newTask(Entity entity, Effector<Void> 
effector, ConfigBag parameters) {
-            machine(EffectorTasks.getSshMachine(entity));
-            applySshFlags(getConfig(), entity, getMachine());
-            return super.newTask();
-        }
-        @Override
-        public SshPutTaskWrapper newTask() {
-            Entity entity = 
BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
-            if (machine==null) {
-                if (log.isDebugEnabled())
-                    log.debug("Using an ssh put task not in an effector 
without any machine; will attempt to infer the machine: "+this);
-                if (entity!=null) {
-                    machine(EffectorTasks.getSshMachine(entity));
-                }
-
-            }
-            applySshFlags(getConfig(), entity, getMachine());
-            return super.newTask();
-        }
-    }
-
-    public static class SshFetchEffectorTaskFactory extends 
SshFetchTaskFactory implements EffectorTaskFactory<String> {
-        public SshFetchEffectorTaskFactory(String remoteFile) {
-            super(remoteFile);
-        }
-        public SshFetchEffectorTaskFactory(SshMachineLocation machine, String 
remoteFile) {
-            super(machine, remoteFile);
-        }
-        @Override
-        public SshFetchTaskWrapper newTask(Entity entity, Effector<String> 
effector, ConfigBag parameters) {
-            machine(EffectorTasks.getSshMachine(entity));
-            applySshFlags(getConfig(), entity, getMachine());
-            return super.newTask();
-        }
-        @Override
-        public SshFetchTaskWrapper newTask() {
-            Entity entity = 
BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
-            if (machine==null) {
-                if (log.isDebugEnabled())
-                    log.debug("Using an ssh fetch task not in an effector 
without any machine; will attempt to infer the machine: "+this);
-                if (entity!=null)
-                    machine(EffectorTasks.getSshMachine(entity));
-            }
-            applySshFlags(getConfig(), entity, getMachine());
-            return super.newTask();
-        }
-    }
-
-    public static SshEffectorTaskFactory<Integer> ssh(String ...commands) {
-        return new SshEffectorTaskFactory<Integer>(commands);
-    }
-
-    public static SshEffectorTaskFactory<Integer> ssh(List<String> commands) {
-        return ssh(commands.toArray(new String[commands.size()]));
-    }
-
-    public static SshPutTaskFactory put(String remoteFile) {
-        return new SshPutEffectorTaskFactory(remoteFile);
-    }
-
-    public static SshFetchEffectorTaskFactory fetch(String remoteFile) {
-        return new SshFetchEffectorTaskFactory(remoteFile);
-    }
-
-    /** task which returns 0 if pid is running */
-    public static SshEffectorTaskFactory<Integer> codePidRunning(Integer pid) {
-        return ssh("ps -p "+pid).summary("PID "+pid+" is-running check (exit 
code)").allowingNonZeroExitCode();
-    }
-    
-    /** task which fails if the given PID is not running */
-    public static SshEffectorTaskFactory<?> requirePidRunning(Integer pid) {
-        return codePidRunning(pid).summary("PID "+pid+" is-running check 
(required)").requiringExitCodeZero("Process with PID "+pid+" is required to be 
running");
-    }
-
-    /** as {@link #codePidRunning(Integer)} but returning boolean */
-    public static SshEffectorTaskFactory<Boolean> isPidRunning(Integer pid) {
-        return codePidRunning(pid).summary("PID "+pid+" is-running check 
(boolean)").returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
-            public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { 
return Integer.valueOf(0).equals(input.getExitCode()); }
-        });
-    }
-
-
-    /** task which returns 0 if pid in the given file is running;
-     * method accepts wildcards so long as they match a single file on the 
remote end
-     * <p>
-     * returns 1 if no matching file, 
-     * 1 if matching file but no matching process,
-     * and 2 if 2+ matching files */
-    public static SshEffectorTaskFactory<Integer> codePidFromFileRunning(final 
String pidFile) {
-        return ssh(BashCommands.chain(
-                // this fails, but isn't an error
-                BashCommands.requireTest("-f "+pidFile, "The PID file 
"+pidFile+" does not exist."),
-                // this fails and logs an error picked up later
-                BashCommands.requireTest("`ls "+pidFile+" | wc -w` -eq 1", 
"ERROR: there are multiple matching PID files"),
-                // this fails and logs an error picked up later
-                BashCommands.require("cat "+pidFile, "ERROR: the PID file 
"+pidFile+" cannot be read (permissions?)."),
-                // finally check the process
-                "ps -p `cat "+pidFile+"`")).summary("PID file "+pidFile+" 
is-running check (exit code)")
-                .allowingNonZeroExitCode()
-                .addCompletionListener(new 
Function<ProcessTaskWrapper<?>,Void>() {
-                    public Void apply(ProcessTaskWrapper<?> input) {
-                        if (input.getStderr().contains("ERROR:"))
-                            throw new IllegalStateException("Invalid or 
inaccessible PID filespec: "+pidFile);
-                        return null;
-                    }
-                });
-    }
-    
-    /** task which fails if the pid in the given file is not running (or if 
there is no such PID file);
-     * method accepts wildcards so long as they match a single file on the 
remote end (fails if 0 or 2+ matching files) */
-    public static SshEffectorTaskFactory<?> requirePidFromFileRunning(String 
pidFile) {
-        return codePidFromFileRunning(pidFile)
-                .summary("PID file "+pidFile+" is-running check (required)")
-                .requiringExitCodeZero("Process with PID from file "+pidFile+" 
is required to be running");
-    }
-
-    /** as {@link #codePidFromFileRunning(String)} but returning boolean */
-    public static SshEffectorTaskFactory<Boolean> isPidFromFileRunning(String 
pidFile) {
-        return codePidFromFileRunning(pidFile).summary("PID file "+pidFile+" 
is-running check (boolean)").
-                returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
-                    public Boolean apply(@Nullable ProcessTaskWrapper<?> 
input) { return ((Integer)0).equals(input.getExitCode()); }
-                });
-    }
-
-    /** extracts the values for the main brooklyn.ssh.config.* config keys 
(i.e. those declared in ConfigKeys) 
-     * as declared on the entity, and inserts them in a map using the 
unprefixed state, for ssh.
-     * <p>
-     * currently this is computed for each call, which may be wasteful, but it 
is reliable in the face of config changes.
-     * we could cache the Map.  note that we do _not_ cache (or even own) the 
SshTool; 
-     * the SshTool is created or re-used by the SshMachineLocation making use 
of these properties */
-    @Beta
-    public static Map<String, Object> getSshFlags(Entity entity, Location 
optionalLocation) {
-        ConfigBag allConfig = ConfigBag.newInstance();
-        
-        StringConfigMap globalConfig = 
((EntityInternal)entity).getManagementContext().getConfig();
-        allConfig.putAll(globalConfig.getAllConfig());
-        
-        if (optionalLocation!=null)
-            
allConfig.putAll(((LocationInternal)optionalLocation).config().getBag());
-        
-        allConfig.putAll(((EntityInternal)entity).getAllConfig());
-        
-        Map<String, Object> result = Maps.newLinkedHashMap();
-        for (String keyS : allConfig.getAllConfig().keySet()) {
-            if (keyS.startsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
-                ConfigKey<?> key = ConfigKeys.newConfigKey(Object.class, keyS);
-                
-                Object val = allConfig.getStringKey(keyS);
-                
-                /*
-                 * NOV 2013 changing this to rely on config above being 
inserted in the right order,
-                 * so entity config will be preferred over location, and 
location over global.
-                 * If that is consistent then remove the lines below.
-                 * (We can also accept null entity and so combine with 
SshTasks.getSshFlags.)
-                 */
-                
-//                // have to use raw config to test whether the config is set
-//                Object val = 
((EntityInternal)entity).getConfigMap().getRawConfig(key);
-//                if (val!=null) {
-//                    val = entity.getConfig(key);
-//                } else {
-//                    val = globalConfig.getRawConfig(key);
-//                    if (val!=null) val = globalConfig.getConfig(key);
-//                }
-//                if (val!=null) {
-                    
result.put(ConfigUtils.unprefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, 
key).getName(), val);
-//                }
-            }
-        }
-        return result;
-    }
-
-    private static void applySshFlags(ConfigBag config, Entity entity, 
Location machine) {
-        if (entity!=null) {
-            if (!config.get(IGNORE_ENTITY_SSH_FLAGS)) {
-                config.putIfAbsent(getSshFlags(entity, machine));
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java 
b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
index 022b52b..10eea13 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.core.config.ConfigUtils;
 import org.apache.brooklyn.core.location.AbstractLocation;
 import org.apache.brooklyn.core.location.internal.LocationInternal;
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/core/src/test/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasksTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasksTest.java
 
b/core/src/test/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasksTest.java
new file mode 100644
index 0000000..597d267
--- /dev/null
+++ 
b/core/src/test/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasksTest.java
@@ -0,0 +1,264 @@
+/*
+ * 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.effector.core.ssh;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.api.mgmt.TaskFactory;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
+import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException;
+import org.apache.brooklyn.util.net.Urls;
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import 
org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+
+import com.google.common.io.Files;
+
+public class SshEffectorTasksTest {
+
+    private static final Logger log = 
LoggerFactory.getLogger(SshEffectorTasksTest.class);
+    
+    TestApplication app;
+    ManagementContext mgmt;
+    SshMachineLocation host;
+    File tempDir;
+    
+    boolean failureExpected;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setup() throws Exception {
+        app = TestApplication.Factory.newManagedInstanceForTests();
+        mgmt = app.getManagementContext();
+        
+        LocalhostMachineProvisioningLocation lhc = 
mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
+        host = lhc.obtain();
+        app.start(Arrays.asList(host));
+        clearExpectedFailure();
+        tempDir = Files.createTempDir();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (mgmt != null) Entities.destroyAll(mgmt);
+        mgmt = null;
+        FileUtils.deleteDirectory(tempDir);
+        checkExpectedFailure();
+    }
+
+    protected void checkExpectedFailure() {
+        if (failureExpected) {
+            clearExpectedFailure();
+            Assert.fail("Test should have thrown an exception but it did 
not.");
+        }
+    }
+    
+    protected void clearExpectedFailure() {
+        failureExpected = false;
+    }
+
+    protected void setExpectingFailure() {
+        failureExpected = true;
+    }
+    
+    public <T extends TaskAdaptable<?>> T submit(final TaskFactory<T> 
taskFactory) {
+        return Entities.submit(app, taskFactory);
+    }
+    
+    // ------------------- basic ssh
+    
+    @Test(groups="Integration")
+    public void testSshEchoHello() {
+        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.ssh("sleep 1 ; 
echo hello world"));
+        Assert.assertFalse(t.isDone());
+        Assert.assertEquals(t.get(), (Integer)0);
+        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+        Assert.assertEquals(t.getStdout().trim(), "hello world");
+    }
+
+    @Test(groups="Integration")
+    public void testSshPut() throws IOException {
+        String fn = Urls.mergePaths(tempDir.getPath(), "f1");
+        SshPutTaskWrapper t = submit(SshEffectorTasks.put(fn).contents("hello 
world"));
+        t.block();
+        Assert.assertEquals(FileUtils.readFileToString(new File(fn)), "hello 
world");
+        // and make sure this doesn't throw
+        Assert.assertTrue(t.isDone());
+        Assert.assertTrue(t.isSuccessful());
+        Assert.assertEquals(t.get(), null);
+        Assert.assertEquals(t.getExitCode(), (Integer)0);
+    }
+
+    @Test(groups="Integration")
+    public void testSshFetch() throws IOException {
+        String fn = Urls.mergePaths(tempDir.getPath(), "f2");
+        FileUtils.write(new File(fn), "hello fetched world");
+        
+        SshFetchTaskWrapper t = submit(SshEffectorTasks.fetch(fn));
+        t.block();
+        
+        Assert.assertTrue(t.isDone());
+        Assert.assertEquals(t.get(), "hello fetched world");
+    }
+
+    // ----------------- pid stuff
+    
+    @Test(groups="Integration")
+    public void testNonRunningPid() {
+        ProcessTaskWrapper<Integer> t = 
submit(SshEffectorTasks.codePidRunning(99999));
+        Assert.assertNotEquals(t.getTask().getUnchecked(), (Integer)0);
+        Assert.assertNotEquals(t.getExitCode(), (Integer)0);
+        ProcessTaskWrapper<Boolean> t2 = 
submit(SshEffectorTasks.isPidRunning(99999));
+        Assert.assertFalse(t2.getTask().getUnchecked());
+    }
+
+    @Test(groups="Integration")
+    public void testNonRunningPidRequired() {
+        ProcessTaskWrapper<?> t = 
submit(SshEffectorTasks.requirePidRunning(99999));
+        setExpectingFailure();
+        try {
+            t.getTask().getUnchecked();
+        } catch (Exception e) {
+            log.info("The error if required PID is not found is: "+e);
+            clearExpectedFailure();
+            Assert.assertTrue(e.toString().contains("Process with PID"), 
"Expected nice clue in error but got: "+e);
+        }
+        checkExpectedFailure();
+    }
+
+    public static Integer getMyPid() {
+        try {
+            java.lang.management.RuntimeMXBean runtime = 
+                    java.lang.management.ManagementFactory.getRuntimeMXBean();
+            java.lang.reflect.Field jvm = 
runtime.getClass().getDeclaredField("jvm");
+            jvm.setAccessible(true);
+//            sun.management.VMManagement mgmt = (sun.management.VMManagement) 
jvm.get(runtime);
+            Object mgmt = jvm.get(runtime);
+            java.lang.reflect.Method pid_method =  
+                    mgmt.getClass().getDeclaredMethod("getProcessId");
+            pid_method.setAccessible(true);
+
+            return (Integer) pid_method.invoke(mgmt);
+        } catch (Exception e) {
+            throw new PropagatedRuntimeException("Test depends on (fragile) 
getMyPid method which does not work here", e);
+        }
+    }
+
+    @Test(groups="Integration")
+    public void testRunningPid() {
+        ProcessTaskWrapper<Integer> t = 
submit(SshEffectorTasks.codePidRunning(getMyPid()));
+        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+        ProcessTaskWrapper<Boolean> t2 = 
submit(SshEffectorTasks.isPidRunning(getMyPid()));
+        Assert.assertTrue(t2.getTask().getUnchecked());
+    }
+
+    @Test(groups="Integration")
+    public void testRunningPidFromFile() throws IOException {
+        File f = File.createTempFile("testBrooklynPid", ".pid");
+        Files.write( (""+getMyPid()).getBytes(), f );
+        ProcessTaskWrapper<Integer> t = 
submit(SshEffectorTasks.codePidFromFileRunning(f.getPath()));
+        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+        ProcessTaskWrapper<Boolean> t2 = 
submit(SshEffectorTasks.isPidFromFileRunning(f.getPath()));
+        Assert.assertTrue(t2.getTask().getUnchecked());
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnFailure() throws IOException {
+        File f = File.createTempFile("testBrooklynPid", ".pid");
+        Files.write( "99999".getBytes(), f );
+        ProcessTaskWrapper<?> t = 
submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
+        
+        setExpectingFailure();
+        try {
+            t.getTask().getUnchecked();
+        } catch (Exception e) {
+            log.info("The error if required PID is not found is: "+e);
+            clearExpectedFailure();
+            Assert.assertTrue(e.toString().contains("Process with PID"), 
"Expected nice clue in error but got: "+e);
+            Assert.assertEquals(t.getExitCode(), (Integer)1);
+        }
+        checkExpectedFailure();
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnFailureNoSuchFile() throws IOException 
{
+        ProcessTaskWrapper<?> t = 
submit(SshEffectorTasks.requirePidFromFileRunning("/path/does/not/exist/SADVQW"));
+        
+        setExpectingFailure();
+        try {
+            t.getTask().getUnchecked();
+        } catch (Exception e) {
+            log.info("The error if required PID is not found is: "+e);
+            clearExpectedFailure();
+            Assert.assertTrue(e.toString().contains("Process with PID"), 
"Expected nice clue in error but got: "+e);
+            Assert.assertEquals(t.getExitCode(), (Integer)1);
+        }
+        checkExpectedFailure();
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnFailureTooManyFiles() throws 
IOException {
+        ProcessTaskWrapper<?> t = 
submit(SshEffectorTasks.requirePidFromFileRunning("/*"));
+        
+        setExpectingFailure();
+        try {
+            t.getTask().getUnchecked();
+        } catch (Exception e) {
+            log.info("The error if required PID is not found is: "+e);
+            clearExpectedFailure();
+            Assert.assertTrue(e.toString().contains("Process with PID"), 
"Expected nice clue in error but got: "+e);
+            Assert.assertEquals(t.getExitCode(), (Integer)2);
+        }
+        checkExpectedFailure();
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnSuccess() throws IOException {
+        File f = File.createTempFile("testBrooklynPid", ".pid");
+        Files.write( (""+getMyPid()).getBytes(), f );
+        ProcessTaskWrapper<?> t = 
submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
+        
+        t.getTask().getUnchecked();
+    }
+
+    @Test(groups="Integration")
+    public void testRequirePidFromFileOnSuccessAcceptsWildcards() throws 
IOException {
+        File f = File.createTempFile("testBrooklynPid", ".pid");
+        Files.write( (""+getMyPid()).getBytes(), f );
+        ProcessTaskWrapper<?> t = 
submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()+"*"));
+        
+        t.getTask().getUnchecked();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasksTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasksTest.java
 
b/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasksTest.java
deleted file mode 100644
index 92f45d7..0000000
--- 
a/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasksTest.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * 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.util.core.task.ssh;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-
-import org.apache.brooklyn.api.location.LocationSpec;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.mgmt.TaskAdaptable;
-import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
-import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
-import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException;
-import org.apache.brooklyn.util.net.Urls;
-import org.apache.commons.io.FileUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import 
org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-
-import com.google.common.io.Files;
-
-public class SshEffectorTasksTest {
-
-    private static final Logger log = 
LoggerFactory.getLogger(SshEffectorTasksTest.class);
-    
-    TestApplication app;
-    ManagementContext mgmt;
-    SshMachineLocation host;
-    File tempDir;
-    
-    boolean failureExpected;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setup() throws Exception {
-        app = TestApplication.Factory.newManagedInstanceForTests();
-        mgmt = app.getManagementContext();
-        
-        LocalhostMachineProvisioningLocation lhc = 
mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
-        host = lhc.obtain();
-        app.start(Arrays.asList(host));
-        clearExpectedFailure();
-        tempDir = Files.createTempDir();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (mgmt != null) Entities.destroyAll(mgmt);
-        mgmt = null;
-        FileUtils.deleteDirectory(tempDir);
-        checkExpectedFailure();
-    }
-
-    protected void checkExpectedFailure() {
-        if (failureExpected) {
-            clearExpectedFailure();
-            Assert.fail("Test should have thrown an exception but it did 
not.");
-        }
-    }
-    
-    protected void clearExpectedFailure() {
-        failureExpected = false;
-    }
-
-    protected void setExpectingFailure() {
-        failureExpected = true;
-    }
-    
-    public <T extends TaskAdaptable<?>> T submit(final TaskFactory<T> 
taskFactory) {
-        return Entities.submit(app, taskFactory);
-    }
-    
-    // ------------------- basic ssh
-    
-    @Test(groups="Integration")
-    public void testSshEchoHello() {
-        ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.ssh("sleep 1 ; 
echo hello world"));
-        Assert.assertFalse(t.isDone());
-        Assert.assertEquals(t.get(), (Integer)0);
-        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
-        Assert.assertEquals(t.getStdout().trim(), "hello world");
-    }
-
-    @Test(groups="Integration")
-    public void testSshPut() throws IOException {
-        String fn = Urls.mergePaths(tempDir.getPath(), "f1");
-        SshPutTaskWrapper t = submit(SshEffectorTasks.put(fn).contents("hello 
world"));
-        t.block();
-        Assert.assertEquals(FileUtils.readFileToString(new File(fn)), "hello 
world");
-        // and make sure this doesn't throw
-        Assert.assertTrue(t.isDone());
-        Assert.assertTrue(t.isSuccessful());
-        Assert.assertEquals(t.get(), null);
-        Assert.assertEquals(t.getExitCode(), (Integer)0);
-    }
-
-    @Test(groups="Integration")
-    public void testSshFetch() throws IOException {
-        String fn = Urls.mergePaths(tempDir.getPath(), "f2");
-        FileUtils.write(new File(fn), "hello fetched world");
-        
-        SshFetchTaskWrapper t = submit(SshEffectorTasks.fetch(fn));
-        t.block();
-        
-        Assert.assertTrue(t.isDone());
-        Assert.assertEquals(t.get(), "hello fetched world");
-    }
-
-    // ----------------- pid stuff
-    
-    @Test(groups="Integration")
-    public void testNonRunningPid() {
-        ProcessTaskWrapper<Integer> t = 
submit(SshEffectorTasks.codePidRunning(99999));
-        Assert.assertNotEquals(t.getTask().getUnchecked(), (Integer)0);
-        Assert.assertNotEquals(t.getExitCode(), (Integer)0);
-        ProcessTaskWrapper<Boolean> t2 = 
submit(SshEffectorTasks.isPidRunning(99999));
-        Assert.assertFalse(t2.getTask().getUnchecked());
-    }
-
-    @Test(groups="Integration")
-    public void testNonRunningPidRequired() {
-        ProcessTaskWrapper<?> t = 
submit(SshEffectorTasks.requirePidRunning(99999));
-        setExpectingFailure();
-        try {
-            t.getTask().getUnchecked();
-        } catch (Exception e) {
-            log.info("The error if required PID is not found is: "+e);
-            clearExpectedFailure();
-            Assert.assertTrue(e.toString().contains("Process with PID"), 
"Expected nice clue in error but got: "+e);
-        }
-        checkExpectedFailure();
-    }
-
-    public static Integer getMyPid() {
-        try {
-            java.lang.management.RuntimeMXBean runtime = 
-                    java.lang.management.ManagementFactory.getRuntimeMXBean();
-            java.lang.reflect.Field jvm = 
runtime.getClass().getDeclaredField("jvm");
-            jvm.setAccessible(true);
-//            sun.management.VMManagement mgmt = (sun.management.VMManagement) 
jvm.get(runtime);
-            Object mgmt = jvm.get(runtime);
-            java.lang.reflect.Method pid_method =  
-                    mgmt.getClass().getDeclaredMethod("getProcessId");
-            pid_method.setAccessible(true);
-
-            return (Integer) pid_method.invoke(mgmt);
-        } catch (Exception e) {
-            throw new PropagatedRuntimeException("Test depends on (fragile) 
getMyPid method which does not work here", e);
-        }
-    }
-
-    @Test(groups="Integration")
-    public void testRunningPid() {
-        ProcessTaskWrapper<Integer> t = 
submit(SshEffectorTasks.codePidRunning(getMyPid()));
-        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
-        ProcessTaskWrapper<Boolean> t2 = 
submit(SshEffectorTasks.isPidRunning(getMyPid()));
-        Assert.assertTrue(t2.getTask().getUnchecked());
-    }
-
-    @Test(groups="Integration")
-    public void testRunningPidFromFile() throws IOException {
-        File f = File.createTempFile("testBrooklynPid", ".pid");
-        Files.write( (""+getMyPid()).getBytes(), f );
-        ProcessTaskWrapper<Integer> t = 
submit(SshEffectorTasks.codePidFromFileRunning(f.getPath()));
-        Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
-        ProcessTaskWrapper<Boolean> t2 = 
submit(SshEffectorTasks.isPidFromFileRunning(f.getPath()));
-        Assert.assertTrue(t2.getTask().getUnchecked());
-    }
-
-    @Test(groups="Integration")
-    public void testRequirePidFromFileOnFailure() throws IOException {
-        File f = File.createTempFile("testBrooklynPid", ".pid");
-        Files.write( "99999".getBytes(), f );
-        ProcessTaskWrapper<?> t = 
submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
-        
-        setExpectingFailure();
-        try {
-            t.getTask().getUnchecked();
-        } catch (Exception e) {
-            log.info("The error if required PID is not found is: "+e);
-            clearExpectedFailure();
-            Assert.assertTrue(e.toString().contains("Process with PID"), 
"Expected nice clue in error but got: "+e);
-            Assert.assertEquals(t.getExitCode(), (Integer)1);
-        }
-        checkExpectedFailure();
-    }
-
-    @Test(groups="Integration")
-    public void testRequirePidFromFileOnFailureNoSuchFile() throws IOException 
{
-        ProcessTaskWrapper<?> t = 
submit(SshEffectorTasks.requirePidFromFileRunning("/path/does/not/exist/SADVQW"));
-        
-        setExpectingFailure();
-        try {
-            t.getTask().getUnchecked();
-        } catch (Exception e) {
-            log.info("The error if required PID is not found is: "+e);
-            clearExpectedFailure();
-            Assert.assertTrue(e.toString().contains("Process with PID"), 
"Expected nice clue in error but got: "+e);
-            Assert.assertEquals(t.getExitCode(), (Integer)1);
-        }
-        checkExpectedFailure();
-    }
-
-    @Test(groups="Integration")
-    public void testRequirePidFromFileOnFailureTooManyFiles() throws 
IOException {
-        ProcessTaskWrapper<?> t = 
submit(SshEffectorTasks.requirePidFromFileRunning("/*"));
-        
-        setExpectingFailure();
-        try {
-            t.getTask().getUnchecked();
-        } catch (Exception e) {
-            log.info("The error if required PID is not found is: "+e);
-            clearExpectedFailure();
-            Assert.assertTrue(e.toString().contains("Process with PID"), 
"Expected nice clue in error but got: "+e);
-            Assert.assertEquals(t.getExitCode(), (Integer)2);
-        }
-        checkExpectedFailure();
-    }
-
-    @Test(groups="Integration")
-    public void testRequirePidFromFileOnSuccess() throws IOException {
-        File f = File.createTempFile("testBrooklynPid", ".pid");
-        Files.write( (""+getMyPid()).getBytes(), f );
-        ProcessTaskWrapper<?> t = 
submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
-        
-        t.getTask().getUnchecked();
-    }
-
-    @Test(groups="Integration")
-    public void testRequirePidFromFileOnSuccessAcceptsWildcards() throws 
IOException {
-        File f = File.createTempFile("testBrooklynPid", ".pid");
-        Files.write( (""+getMyPid()).getBytes(), f );
-        ProcessTaskWrapper<?> t = 
submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()+"*"));
-        
-        t.getTask().getUnchecked();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java 
b/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java
index 3ef139e..6b6c0b1 100644
--- 
a/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java
+++ 
b/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java
@@ -26,6 +26,7 @@ import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasksTest;
 import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
----------------------------------------------------------------------
diff --git 
a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
 
b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
index ef925c6..e7e1df9 100644
--- 
a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
+++ 
b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
@@ -46,6 +46,7 @@ import org.apache.brooklyn.core.entity.trait.Startable;
 import org.apache.brooklyn.core.location.PortRanges;
 import org.apache.brooklyn.effector.core.EffectorBody;
 import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.apache.brooklyn.entity.java.UsesJava;
 import org.apache.brooklyn.entity.java.UsesJmx;
 import org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenter;
@@ -64,7 +65,6 @@ import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.text.TemplateProcessor;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
----------------------------------------------------------------------
diff --git 
a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
 
b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
index 70747b5..58ec93f 100644
--- 
a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
+++ 
b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
@@ -22,7 +22,6 @@ import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.entity.salt.SaltConfig;
 import org.apache.brooklyn.entity.salt.SaltConfigs;
 import org.apache.brooklyn.entity.salt.SaltLifecycleEffectorTasks;
@@ -40,6 +39,7 @@ import 
org.apache.brooklyn.entity.software.base.SoftwareProcess;
 import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNode;
 import org.apache.brooklyn.effector.core.EffectorBody;
 import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.apache.brooklyn.sensor.core.DependentConfiguration;
 import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
 import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git 
a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
 
b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
index 4fa3d96..198d139 100644
--- 
a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
+++ 
b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
@@ -23,10 +23,10 @@ import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.server.BrooklynServerConfig;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import 
org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
----------------------------------------------------------------------
diff --git 
a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java 
b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
index 87096a6..c00e48b 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
@@ -32,10 +32,10 @@ import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.text.TemplateProcessor;
 
 import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.ssh.BashCommands;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
----------------------------------------------------------------------
diff --git 
a/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
 
b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
index 1a42cbb..b25c92f 100644
--- 
a/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
+++ 
b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
@@ -24,7 +24,6 @@ import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.location.PortRanges;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNodeSaltImpl;
 import org.apache.brooklyn.entity.salt.SaltConfig;
@@ -40,6 +39,7 @@ import 
org.apache.brooklyn.entity.database.VogellaExampleAccess;
 import 
org.apache.brooklyn.entity.database.postgresql.PostgreSqlIntegrationTest;
 import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNode;
 import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.time.Duration;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
 
b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
index f27a6dc..6962767 100644
--- 
a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
+++ 
b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
@@ -31,6 +31,7 @@ import java.util.Map;
 
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.drivers.downloads.DownloadSubstituters;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import 
org.apache.brooklyn.entity.brooklynnode.BrooklynNode.ExistingFileBehaviour;
 import org.apache.brooklyn.entity.java.JavaSoftwareProcessSshDriver;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
@@ -39,7 +40,6 @@ import org.apache.brooklyn.util.core.file.ArchiveBuilder;
 import org.apache.brooklyn.util.core.file.ArchiveUtils;
 import org.apache.brooklyn.util.core.internal.ssh.SshTool;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.net.Networking;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
 
b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
index 0b1c089..b1cb9be 100644
--- 
a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
+++ 
b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
@@ -34,6 +34,7 @@ import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.entity.EntityTasks;
 import org.apache.brooklyn.effector.core.EffectorBody;
 import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.apache.brooklyn.entity.brooklynnode.BrooklynCluster;
 import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
 import org.apache.brooklyn.entity.brooklynnode.BrooklynNodeDriver;
@@ -43,7 +44,6 @@ import 
org.apache.brooklyn.entity.software.base.SoftwareProcess.StopSoftwarePara
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.text.Identifiers;
 import org.apache.brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
 
b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
index 45c639c..03b7518 100644
--- 
a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
+++ 
b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
@@ -26,6 +26,7 @@ import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.location.Machines;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess;
 import 
org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
 import org.slf4j.Logger;
@@ -37,7 +38,6 @@ import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.TaskTags;
 import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.net.Urls;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
 
b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
index c543779..327b70b 100644
--- 
a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
+++ 
b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.entity.chef;
 import java.util.Map;
 
 import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.ssh.BashCommands;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java 
b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
index a7b79a3..c8a8b39 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
@@ -24,13 +24,13 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.mgmt.TaskAdaptable;
 import org.apache.brooklyn.api.mgmt.TaskFactory;
 import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.file.ArchiveTasks;
 import org.apache.brooklyn.util.core.file.ArchiveUtils.ArchiveType;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.TaskBuilder;
 import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.net.Urls;
 import org.apache.brooklyn.util.ssh.BashCommands;
 import org.apache.brooklyn.util.text.Identifiers;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
 
b/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
index 6e4b7c7..ce5f82d 100644
--- 
a/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
+++ 
b/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
@@ -32,6 +32,7 @@ import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import 
org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -54,7 +55,6 @@ import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.core.internal.ssh.ShellTool;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.ssh.SshTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
 
b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
index 144894b..1bb994d 100644
--- 
a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
+++ 
b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
@@ -24,6 +24,7 @@ import java.util.concurrent.TimeoutException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.core.location.Machines;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import 
org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
 import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessDriver;
 import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessImpl;
@@ -32,7 +33,6 @@ import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
 import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
 import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
 
b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
index 2be96b6..a303f85 100644
--- 
a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
+++ 
b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
 import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.apache.brooklyn.entity.software.base.lifecycle.NaiveScriptRunner;
 import org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper;
 import org.slf4j.Logger;
@@ -53,7 +54,6 @@ import org.apache.brooklyn.util.core.internal.ssh.SshTool;
 import org.apache.brooklyn.util.core.internal.ssh.sshj.SshjTool;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
 
b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
index c2e4cc8..0515166 100644
--- 
a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
+++ 
b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
@@ -55,6 +55,7 @@ import 
org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
 import org.apache.brooklyn.effector.core.EffectorBody;
 import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.apache.brooklyn.entity.machine.MachineInitTasks;
 import org.apache.brooklyn.entity.machine.ProvidesProvisioningFlags;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess;
@@ -80,7 +81,6 @@ import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
 import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
 
b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
index f91be61..da4a9ce 100644
--- 
a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
+++ 
b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
@@ -28,11 +28,11 @@ import org.apache.brooklyn.effector.core.AddEffector;
 import org.apache.brooklyn.effector.core.EffectorBody;
 import org.apache.brooklyn.effector.core.Effectors;
 import org.apache.brooklyn.effector.core.Effectors.EffectorBuilder;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
+import 
org.apache.brooklyn.effector.core.ssh.SshEffectorTasks.SshEffectorTaskFactory;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
-import 
org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks.SshEffectorTaskFactory;
 import org.apache.brooklyn.util.text.Strings;
 
 import com.google.common.base.Preconditions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
 
b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
index 0166d94..8de4bb0 100644
--- 
a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
+++ 
b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.entity.chef.mysql;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.testng.annotations.Test;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
 
b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
index 468b95e..21d1d2f 100644
--- 
a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
+++ 
b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
@@ -22,6 +22,7 @@ import org.apache.brooklyn.api.mgmt.TaskAdaptable;
 import org.apache.brooklyn.api.mgmt.TaskFactory;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
 import org.apache.brooklyn.entity.chef.ChefConfig;
 import org.apache.brooklyn.entity.chef.ChefConfigs;
 import org.apache.brooklyn.entity.chef.ChefSoloDriver;
@@ -29,7 +30,6 @@ import 
org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
 import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
 import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
 import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
 import org.apache.brooklyn.util.time.Duration;
 
 @Deprecated /** @deprecated since 0.7.0 use see examples 
{Dynamic,Typed}ToyMySqlEntityChef */

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
----------------------------------------------------------------------
diff --git 
a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
 
b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
index 1057ef9..244adf8 100644
--- 
a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
+++ 
b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
@@ -27,9 +27,9 @@ import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks.SshEffectorBody;
 import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks.SshEffectorBody;
 import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;


Reply via email to