You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2015/08/19 13:09:36 UTC

[18/72] [abbrv] incubator-brooklyn git commit: BROOKLYN-162 - apply org.apache package prefix to software-base, tidying package names, and moving a few sensory things to core

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/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
new file mode 100644
index 0000000..671348b
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
@@ -0,0 +1,102 @@
+/*
+ * 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.sensor.ssh;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.effector.ParameterType;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+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.entity.software.base.SoftwareProcess;
+import org.apache.brooklyn.sensor.ssh.SshEffectorTasks.SshEffectorTaskFactory;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.text.Strings;
+
+import com.google.common.base.Preconditions;
+
+public final class SshCommandEffector extends AddEffector {
+    
+    public static final ConfigKey<String> EFFECTOR_COMMAND = ConfigKeys.newStringConfigKey("command");
+    public static final ConfigKey<String> EFFECTOR_EXECUTION_DIR = SshCommandSensor.SENSOR_EXECUTION_DIR;
+    
+    public SshCommandEffector(ConfigBag params) {
+        super(newEffectorBuilder(params).build());
+    }
+    
+    public SshCommandEffector(Map<String,String> params) {
+        this(ConfigBag.newInstance(params));
+    }
+
+    public static EffectorBuilder<String> newEffectorBuilder(ConfigBag params) {
+        EffectorBuilder<String> eff = AddEffector.newEffectorBuilder(String.class, params);
+        eff.impl(new Body(eff.buildAbstract(), params));
+        return eff;
+    }
+
+
+    protected static class Body extends EffectorBody<String> {
+        private final Effector<?> effector;
+        private final String command;
+        private final String executionDir;
+
+        public Body(Effector<?> eff, ConfigBag params) {
+            this.effector = eff;
+            this.command = Preconditions.checkNotNull(params.get(EFFECTOR_COMMAND), "command must be supplied when defining this effector");
+            this.executionDir = params.get(EFFECTOR_EXECUTION_DIR);
+            // TODO could take a custom "env" aka effectorShellEnv
+        }
+
+        @Override
+        public String call(ConfigBag params) {
+            String command = this.command;
+            
+            command = SshCommandSensor.makeCommandExecutingInDirectory(command, executionDir, entity());
+            
+            MutableMap<String, String> env = MutableMap.of();
+            // first set all declared parameters, including default values
+            for (ParameterType<?> param: effector.getParameters()) {
+                env.addIfNotNull(param.getName(), Strings.toString( params.get(Effectors.asConfigKey(param)) ));
+            }
+            
+            // then set things from the entities defined shell environment, if applicable
+            env.putAll(Strings.toStringMap(entity().getConfig(SoftwareProcess.SHELL_ENVIRONMENT), ""));
+            
+            // if we wanted to resolve the surrounding environment in real time -- see above
+//            Map<String,Object> paramsResolved = (Map<String, Object>) Tasks.resolveDeepValue(effectorShellEnv, Map.class, entity().getExecutionContext());
+            
+            // finally set the parameters we've been passed; this will repeat declared parameters but to no harm,
+            // it may pick up additional values (could be a flag defining whether this is permitted or not)
+            env.putAll(Strings.toStringMap(params.getAllConfig()));
+            
+            SshEffectorTaskFactory<String> t = SshEffectorTasks.ssh(command)
+                .requiringZeroAndReturningStdout()
+                .summary("effector "+effector.getName())
+                .environmentVariables(env);
+            return queue(t).get();
+        }
+        
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
new file mode 100644
index 0000000..03c2cb6
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
@@ -0,0 +1,142 @@
+/*
+ * 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.sensor.ssh;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.EntityInitializer;
+import org.apache.brooklyn.api.internal.EntityLocal;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.effector.core.AddSensor;
+import org.apache.brooklyn.entity.java.JmxAttributeSensor;
+import org.apache.brooklyn.entity.software.base.SoftwareProcess;
+import org.apache.brooklyn.sensor.core.HttpRequestSensor;
+import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
+import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
+import org.apache.brooklyn.sensor.feed.ssh.SshValueFunctions;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.os.Os;
+import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Supplier;
+
+/** 
+ * Configurable {@link EntityInitializer} which adds an SSH sensor feed running the <code>command</code> supplied
+ * in order to populate the sensor with the indicated <code>name</code>. Note that the <code>targetType</code> is ignored,
+ * and always set to {@link String}.
+ *
+ * @see HttpRequestSensor
+ * @see JmxAttributeSensor
+ */
+@Beta
+public final class SshCommandSensor<T> extends AddSensor<T> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SshCommandSensor.class);
+
+    public static final ConfigKey<String> SENSOR_COMMAND = ConfigKeys.newStringConfigKey("command", "SSH command to execute for sensor");
+    public static final ConfigKey<String> SENSOR_EXECUTION_DIR = ConfigKeys.newStringConfigKey("executionDir", "Directory where the command should run; "
+        + "if not supplied, executes in the entity's run dir (or home dir if no run dir is defined); "
+        + "use '~' to always execute in the home dir, or 'custom-feed/' to execute in a custom-feed dir relative to the run dir");
+
+    protected final String command;
+    protected final String executionDir;
+
+    public SshCommandSensor(final ConfigBag params) {
+        super(params);
+
+        // TODO create a supplier for the command string to support attribute embedding
+        command = Preconditions.checkNotNull(params.get(SENSOR_COMMAND), "command");
+        
+        executionDir = params.get(SENSOR_EXECUTION_DIR);
+    }
+
+    @Override
+    public void apply(final EntityLocal entity) {
+        super.apply(entity);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Adding SSH sensor {} to {}", name, entity);
+        }
+
+        Supplier<Map<String,String>> envSupplier = new Supplier<Map<String,String>>() {
+            @Override
+            public Map<String, String> get() {
+                return MutableMap.copyOf(Strings.toStringMap(entity.getConfig(SoftwareProcess.SHELL_ENVIRONMENT), ""));
+            }
+        };
+
+        Supplier<String> commandSupplier = new Supplier<String>() {
+            @Override
+            public String get() {
+                return makeCommandExecutingInDirectory(command, executionDir, entity);
+            }
+        };
+
+        SshPollConfig<T> pollConfig = new SshPollConfig<T>(sensor)
+                .period(period)
+                .env(envSupplier)
+                .command(commandSupplier)
+                .checkSuccess(SshValueFunctions.exitStatusEquals(0))
+                .onFailureOrException(Functions.constant((T) null))
+                .onSuccess(Functions.compose(new Function<String, T>() {
+                        @Override
+                        public T apply(String input) {
+                            return TypeCoercions.coerce(input, getType(type));
+                        }}, SshValueFunctions.stdout()));
+
+        SshFeed.builder()
+                .entity(entity)
+                .onlyIfServiceUp()
+                .poll(pollConfig)
+                .build();
+    }
+
+    static String makeCommandExecutingInDirectory(String command, String executionDir, EntityLocal entity) {
+        String finalCommand = command;
+        String execDir = executionDir;
+        if (Strings.isBlank(execDir)) {
+            // default to run dir
+            execDir = entity.getAttribute(SoftwareProcess.RUN_DIR);
+            // if no run dir, default to home
+            if (Strings.isBlank(execDir)) {
+                execDir = "~";
+            }
+        } else if (!Os.isAbsolutish(execDir)) {
+            // relative paths taken wrt run dir
+            String runDir = entity.getAttribute(SoftwareProcess.RUN_DIR);
+            if (!Strings.isBlank(runDir)) {
+                execDir = Os.mergePaths(runDir, execDir);
+            }
+        }
+        if (!"~".equals(execDir)) {
+            finalCommand = "mkdir -p '"+execDir+"' && cd '"+execDir+"' && "+finalCommand;
+        }
+        return finalCommand;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasks.java b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasks.java
new file mode 100644
index 0000000..4ea5ed5
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/sensor/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.sensor.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.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.apache.brooklyn.entity.core.EntityInternal;
+import org.apache.brooklyn.entity.software.base.SoftwareProcess;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.basic.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 a {@link SoftwareProcess}
+     * (or other 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/64c2b2e5/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java b/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java
new file mode 100644
index 0000000..5acdd1c
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java
@@ -0,0 +1,73 @@
+/*
+ * 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.sensor.winrm;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.EntityInitializer;
+import org.apache.brooklyn.api.internal.EntityLocal;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.entity.core.EntityInternal;
+import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.sensor.feed.windows.WindowsPerformanceCounterFeed;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.reflect.TypeToken;
+
+public class WindowsPerformanceCounterSensors implements EntityInitializer {
+
+    private static final Logger LOG = LoggerFactory.getLogger(WindowsPerformanceCounterSensors.class);
+
+    public final static ConfigKey<Set<Map<String, String>>> PERFORMANCE_COUNTERS = ConfigKeys.newConfigKey(new TypeToken<Set<Map<String, String>>>(){}, "performance.counters");
+
+    protected final Set<Map<String, String>> sensors;
+
+    public WindowsPerformanceCounterSensors(ConfigBag params) {
+        sensors = params.get(PERFORMANCE_COUNTERS);
+    }
+
+    public WindowsPerformanceCounterSensors(Map<String, String> params) {
+        this(ConfigBag.newInstance(params));
+    }
+
+    @Override
+    public void apply(EntityLocal entity) {
+        WindowsPerformanceCounterFeed.Builder builder = WindowsPerformanceCounterFeed.builder()
+                .entity(entity);
+        for (Map<String, String> sensorConfig : sensors) {
+            String name = sensorConfig.get("name");
+            String sensorType = sensorConfig.get("sensorType");
+            Class<?> clazz;
+            try {
+                clazz = Strings.isNonEmpty(sensorType)
+                        ? ((EntityInternal)entity).getManagementContext().getCatalog().getRootClassLoader().loadClass(sensorType) 
+                        : String.class;
+            } catch (ClassNotFoundException e) {
+                throw new IllegalStateException("Could not load type "+sensorType+" for sensor "+name, e);
+            }
+            builder.addSensor(sensorConfig.get("counter"), Sensors.newSensor(clazz, name, sensorConfig.get("description")));
+        }
+        builder.build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/resources/brooklyn/entity/brooklynnode/brooklyn-cluster.yaml
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/brooklyn/entity/brooklynnode/brooklyn-cluster.yaml b/software/base/src/main/resources/brooklyn/entity/brooklynnode/brooklyn-cluster.yaml
deleted file mode 100644
index cb32596..0000000
--- a/software/base/src/main/resources/brooklyn/entity/brooklynnode/brooklyn-cluster.yaml
+++ /dev/null
@@ -1,33 +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.
-#
-
-name: Example Brooklyn Cluster
-
-services:
-- type: brooklyn.entity.brooklynnode.BrooklynCluster
-  initialSize: 2
-  memberSpec:
-    $brooklyn:entitySpec: 
-#      type: classpath://brooklyn/entity/brooklynnode/brooklyn-node-persisting-to-tmp.yaml
-      type: brooklyn.entity.brooklynnode.BrooklynNode
-      brooklyn.config:
-        # persistence location must be the same for all nodes; if anywhere other than localhost configure a shared obj store or nfs mount
-        brooklynnode.launch.parameters.extra: --persist auto --persistenceDir /tmp/brooklyn-persistence-example/
-
-# location: localhost

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/resources/brooklyn/entity/brooklynnode/brooklyn-node-persisting-to-tmp.yaml
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/brooklyn/entity/brooklynnode/brooklyn-node-persisting-to-tmp.yaml b/software/base/src/main/resources/brooklyn/entity/brooklynnode/brooklyn-node-persisting-to-tmp.yaml
deleted file mode 100644
index afb53e7..0000000
--- a/software/base/src/main/resources/brooklyn/entity/brooklynnode/brooklyn-node-persisting-to-tmp.yaml
+++ /dev/null
@@ -1,27 +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.
-#
-
-name: Example Persisting Brooklyn Node
-
-services:
-- type: classpath://brooklyn/entity/brooklynnode/brooklyn-node.yaml
-  brooklyn.config:
-    brooklynnode.launch.parameters.extra: --persist auto --persistenceDir /tmp/brooklyn-persistence-example/
-
-location: localhost

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/resources/brooklyn/entity/brooklynnode/brooklyn-node.yaml
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/brooklyn/entity/brooklynnode/brooklyn-node.yaml b/software/base/src/main/resources/brooklyn/entity/brooklynnode/brooklyn-node.yaml
deleted file mode 100644
index db5b1c7..0000000
--- a/software/base/src/main/resources/brooklyn/entity/brooklynnode/brooklyn-node.yaml
+++ /dev/null
@@ -1,35 +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.
-#
-
-name: Example Brooklyn Node
-
-services:
-- type: brooklyn.entity.brooklynnode.BrooklynNode
-
-  ## URL for uploading the brooklyn distro (retrieved locally and pushed to remote install location)
-  # brooklynnode.distro.uploadurl: file:///tmp/brooklyn-dist-<version>-dist.tar.gz
-
-  ## if deploying to anything other than localhost you must also configure login details, e.g.:
-  # managementUsername: admin
-  # managementPassword: p4ssw0rd
-  # brooklynLocalPropertiesContents: |
-  #   brooklyn.webconsole.security.users=admin
-  #   brooklyn.webconsole.security.user.admin.password=p4ssw0rd
-
-# location: localhost

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/resources/brooklyn/entity/service/service.sh
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/brooklyn/entity/service/service.sh b/software/base/src/main/resources/brooklyn/entity/service/service.sh
deleted file mode 100644
index 4a1b293..0000000
--- a/software/base/src/main/resources/brooklyn/entity/service/service.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-#
-# chkconfig: - 80 20
-#
-### BEGIN INIT INFO
-# Provides:          ${service.name}
-# Required-Start:    $network $syslog
-# Required-Stop:     $network $syslog
-# Default-Start:
-# Default-Stop:
-# Short-Description: Brooklyn entity service
-# Description:       Service for Brooklyn managed entity
-### END INIT INFO
-
-case $1 in
- start)
-  touch ${service.log_path}/${service.name}.log
-  chown ${service.user} ${service.log_path}/${service.name}.log
-  sudo -u ${service.user} ${service.launch_script} >> ${service.log_path}/${service.name}.log 2>&1
-  ;;
-# stop)
-#  ;;
-# restart)
-#  ;;
-# status)
-#  ;;
-# reload)
-#  ;;
- *)
-#  echo "Usage: $0 {start|stop|restart|reload|status}"
-  echo "Usage: $0 {start}"
-  exit 2
-  ;;
-esac

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/resources/org/apache/brooklyn/entity/brooklynnode/brooklyn-cluster.yaml
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/org/apache/brooklyn/entity/brooklynnode/brooklyn-cluster.yaml b/software/base/src/main/resources/org/apache/brooklyn/entity/brooklynnode/brooklyn-cluster.yaml
new file mode 100644
index 0000000..97a7fc1
--- /dev/null
+++ b/software/base/src/main/resources/org/apache/brooklyn/entity/brooklynnode/brooklyn-cluster.yaml
@@ -0,0 +1,33 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+name: Example Brooklyn Cluster
+
+services:
+- type: org.apache.brooklyn.entity.brooklynnode.BrooklynCluster
+  initialSize: 2
+  memberSpec:
+    $brooklyn:entitySpec: 
+#      type: classpath://org/apache/brooklyn/entity/brooklynnode/brooklyn-node-persisting-to-tmp.yaml
+      type: org.apache.brooklyn.entity.brooklynnode.BrooklynNode
+      brooklyn.config:
+        # persistence location must be the same for all nodes; if anywhere other than localhost configure a shared obj store or nfs mount
+        brooklynnode.launch.parameters.extra: --persist auto --persistenceDir /tmp/brooklyn-persistence-example/
+
+# location: localhost

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/resources/org/apache/brooklyn/entity/brooklynnode/brooklyn-node-persisting-to-tmp.yaml
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/org/apache/brooklyn/entity/brooklynnode/brooklyn-node-persisting-to-tmp.yaml b/software/base/src/main/resources/org/apache/brooklyn/entity/brooklynnode/brooklyn-node-persisting-to-tmp.yaml
new file mode 100644
index 0000000..6081bd6
--- /dev/null
+++ b/software/base/src/main/resources/org/apache/brooklyn/entity/brooklynnode/brooklyn-node-persisting-to-tmp.yaml
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+
+name: Example Persisting Brooklyn Node
+
+services:
+- type: classpath://org/apache/brooklyn/entity/brooklynnode/brooklyn-node.yaml
+  brooklyn.config:
+    brooklynnode.launch.parameters.extra: --persist auto --persistenceDir /tmp/brooklyn-persistence-example/
+
+location: localhost

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/resources/org/apache/brooklyn/entity/brooklynnode/brooklyn-node.yaml
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/org/apache/brooklyn/entity/brooklynnode/brooklyn-node.yaml b/software/base/src/main/resources/org/apache/brooklyn/entity/brooklynnode/brooklyn-node.yaml
new file mode 100644
index 0000000..6d813d1
--- /dev/null
+++ b/software/base/src/main/resources/org/apache/brooklyn/entity/brooklynnode/brooklyn-node.yaml
@@ -0,0 +1,35 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+name: Example Brooklyn Node
+
+services:
+- type: org.apache.brooklyn.entity.brooklynnode.BrooklynNode
+
+  ## URL for uploading the brooklyn distro (retrieved locally and pushed to remote install location)
+  # brooklynnode.distro.uploadurl: file:///tmp/brooklyn-dist-<version>-dist.tar.gz
+
+  ## if deploying to anything other than localhost you must also configure login details, e.g.:
+  # managementUsername: admin
+  # managementPassword: p4ssw0rd
+  # brooklynLocalPropertiesContents: |
+  #   brooklyn.webconsole.security.users=admin
+  #   brooklyn.webconsole.security.user.admin.password=p4ssw0rd
+
+# location: localhost

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/main/resources/org/apache/brooklyn/entity/system_service/service.sh
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/org/apache/brooklyn/entity/system_service/service.sh b/software/base/src/main/resources/org/apache/brooklyn/entity/system_service/service.sh
new file mode 100644
index 0000000..4a1b293
--- /dev/null
+++ b/software/base/src/main/resources/org/apache/brooklyn/entity/system_service/service.sh
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+# chkconfig: - 80 20
+#
+### BEGIN INIT INFO
+# Provides:          ${service.name}
+# Required-Start:    $network $syslog
+# Required-Stop:     $network $syslog
+# Default-Start:
+# Default-Stop:
+# Short-Description: Brooklyn entity service
+# Description:       Service for Brooklyn managed entity
+### END INIT INFO
+
+case $1 in
+ start)
+  touch ${service.log_path}/${service.name}.log
+  chown ${service.user} ${service.log_path}/${service.name}.log
+  sudo -u ${service.user} ${service.launch_script} >> ${service.log_path}/${service.name}.log 2>&1
+  ;;
+# stop)
+#  ;;
+# restart)
+#  ;;
+# status)
+#  ;;
+# reload)
+#  ;;
+ *)
+#  echo "Usage: $0 {start|stop|restart|reload|status}"
+  echo "Usage: $0 {start}"
+  exit 2
+  ;;
+esac

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java b/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java
deleted file mode 100644
index ad10b00..0000000
--- a/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java
+++ /dev/null
@@ -1,139 +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 brooklyn.entity;
-
-import java.util.Map;
-
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.core.internal.BrooklynProperties;
-import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.location.jclouds.JcloudsLocation;
-import org.apache.brooklyn.location.jclouds.JcloudsLocationConfig;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-/**
- * Runs a test with many different distros and versions.
- */
-public abstract class AbstractEc2LiveTest extends BrooklynAppLiveTestSupport {
-    
-    // FIXME Currently have just focused on test_Debian_6; need to test the others as well!
-
-    // TODO No nice fedora VMs
-    
-    // TODO Instead of this sub-classing approach, we could use testng's "provides" mechanism
-    // to say what combo of provider/region/flags should be used. The problem with that is the
-    // IDE integration: one can't just select a single test to run.
-    
-    public static final String PROVIDER = "aws-ec2";
-    public static final String REGION_NAME = "us-east-1";
-    public static final String LOCATION_SPEC = PROVIDER + (REGION_NAME == null ? "" : ":" + REGION_NAME);
-    public static final String TINY_HARDWARE_ID = "t1.micro";
-    public static final String SMALL_HARDWARE_ID = "m1.small";
-    
-    protected BrooklynProperties brooklynProperties;
-    
-    protected Location jcloudsLocation;
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        // Don't let any defaults from brooklyn.properties (except credentials) interfere with test
-        brooklynProperties = BrooklynProperties.Factory.newDefault();
-        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".image-description-regex");
-        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".image-name-regex");
-        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".image-id");
-        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".inboundPorts");
-        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".hardware-id");
-
-        // Also removes scriptHeader (e.g. if doing `. ~/.bashrc` and `. ~/.profile`, then that can cause "stdin: is not a tty")
-        brooklynProperties.remove("brooklyn.ssh.config.scriptHeader");
-        
-        mgmt = new LocalManagementContextForTests(brooklynProperties);
-        
-        super.setUp();
-    }
-
-    // Image ids for Debian: https://wiki.debian.org/Cloud/AmazonEC2Image/Squeeze
-    @Test(groups = {"Live"})
-    public void test_Debian_6() throws Exception {
-        // release codename "squeeze"
-        runTest(ImmutableMap.of("imageId", "us-east-1/ami-5e12dc36", "loginUser", "admin", "hardwareId", SMALL_HARDWARE_ID));
-    }
-
-    @Test(groups = {"Live"})
-    public void test_Debian_7_2() throws Exception {
-        // release codename "wheezy"
-        runTest(ImmutableMap.of("imageId", "us-east-1/ami-5586a43c", "loginUser", "admin", "hardwareId", SMALL_HARDWARE_ID));
-    }
-
-    @Test(groups = {"Live"})
-    public void test_Ubuntu_10_0() throws Exception {
-        // Image: {id=us-east-1/ami-5e008437, providerId=ami-5e008437, name=RightImage_Ubuntu_10.04_x64_v5.8.8.3, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=10.04, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, is64Bit=true}, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, version=5.8.8.3, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=instance-store, virtualizationType=paravirtual, hypervisor=xen}}
-        runTest(ImmutableMap.of("imageId", "us-east-1/ami-5e008437", "loginUser", "root", "hardwareId", SMALL_HARDWARE_ID));
-    }
-
-    @Test(groups = {"Live"})
-    public void test_Ubuntu_12_0() throws Exception {
-        // Image: {id=us-east-1/ami-d0f89fb9, providerId=ami-d0f89fb9, name=ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=12.04, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, is64Bit=true}, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, version=20130411.1, status=AVAILABLE[available], loginUser=ubuntu, userMetadata={owner=099720109477, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}}
-        runTest(ImmutableMap.of("imageId", "us-east-1/ami-d0f89fb9", "loginUser", "ubuntu", "hardwareId", SMALL_HARDWARE_ID));
-    }
-
-    @Test(groups = {"Live"})
-    public void test_CentOS_6_3() throws Exception {
-        // TODO Should openIptables=true be the default?!
-        // Image: {id=us-east-1/ami-a96b01c0, providerId=ami-a96b01c0, name=CentOS-6.3-x86_64-GA-EBS-02-85586466-5b6c-4495-b580-14f72b4bcf51-ami-bb9af1d2.1, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=centos, arch=paravirtual, version=6.3, description=aws-marketplace/CentOS-6.3-x86_64-GA-EBS-02-85586466-5b6c-4495-b580-14f72b4bcf51-ami-bb9af1d2.1, is64Bit=true}, description=CentOS-6.3-x86_64-GA-EBS-02 on EBS x86_64 20130527:1219, version=bb9af1d2.1, status=AVAILABLE[available], loginUser=root, userMetadata={owner=679593333241, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}})
-        runTest(ImmutableMap.of("imageId", "us-east-1/ami-a96b01c0", "hardwareId", SMALL_HARDWARE_ID, JcloudsLocation.OPEN_IPTABLES.getName(), true));
-    }
-
-    @Test(groups = {"Live"})
-    public void test_CentOS_5() throws Exception {
-        // Image: {id=us-east-1/ami-e4bffe8d, providerId=ami-e4bffe8d, name=RightImage_CentOS_5.9_x64_v12.11.4_EBS, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=centos, arch=paravirtual, version=5.0, description=411009282317/RightImage_CentOS_5.9_x64_v12.11.4_EBS, is64Bit=true}, description=RightImage_CentOS_5.9_x64_v12.11.4_EBS, version=12.11.4_EBS, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}}
-        runTest(ImmutableMap.of("imageId", "us-east-1/ami-e4bffe8d", "hardwareId", SMALL_HARDWARE_ID));
-    }
-
-    @Test(groups = {"Live"})
-    public void test_Red_Hat_Enterprise_Linux_6() throws Exception {
-        // Image: {id=us-east-1/ami-a35a33ca, providerId=ami-a35a33ca, name=RHEL-6.3_GA-x86_64-5-Hourly2, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=rhel, arch=paravirtual, version=6.0, description=309956199498/RHEL-6.3_GA-x86_64-5-Hourly2, is64Bit=true}, description=309956199498/RHEL-6.3_GA-x86_64-5-Hourly2, version=Hourly2, status=AVAILABLE[available], loginUser=root, userMetadata={owner=309956199498, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}}
-        runTest(ImmutableMap.of("imageId", "us-east-1/ami-a35a33ca", "hardwareId", SMALL_HARDWARE_ID, JcloudsLocationConfig.OPEN_IPTABLES.getName(), "true"));
-    }
-    
-    @Test(groups = {"Live"})
-    public void test_Suse_11sp3() throws Exception {
-        // Image: {id=us-east-1/ami-c08fcba8, providerId=ami-c08fcba8, name=suse-sles-11-sp3-v20150127-pv-ssd-x86_64, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=suse, arch=paravirtual, version=, description=amazon/suse-sles-11-sp3-v20150127-pv-ssd-x86_64, is64Bit=true}, description=SUSE Linux Enterprise Server 11 Service Pack 3 (PV, 64-bit, SSD-Backed), version=x86_64, status=AVAILABLE[available], loginUser=root, userMetadata={owner=013907871322, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}}
-        runTest(ImmutableMap.of("imageId", "us-east-1/ami-c08fcba8", "hardwareId", SMALL_HARDWARE_ID, "loginUser", "ec2-user"));//, JcloudsLocationConfig.OPEN_IPTABLES.getName(), "true"));
-    }
-    
-    protected void runTest(Map<String,?> flags) throws Exception {
-        Map<String,?> allFlags = MutableMap.<String,Object>builder()
-                .put("tags", ImmutableList.of(getClass().getName()))
-                .putAll(flags)
-                .build();
-        jcloudsLocation = mgmt.getLocationRegistry().resolve(LOCATION_SPEC, allFlags);
-
-        doTest(jcloudsLocation);
-    }
-    
-    protected abstract void doTest(Location loc) throws Exception;
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java b/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java
deleted file mode 100644
index 0301e1a..0000000
--- a/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java
+++ /dev/null
@@ -1,137 +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 brooklyn.entity;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.core.internal.BrooklynProperties;
-import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.entity.core.Entities;
-import org.apache.brooklyn.entity.factory.ApplicationBuilder;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.CaseFormat;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-/**
- * Runs a test with many different distros and versions.
- */
-public abstract class AbstractGoogleComputeLiveTest {
-    
-    // TODO See todos in AbstractEc2LiveTest
-    
-    public static final String PROVIDER = "google-compute-engine";
-    public static final String REGION_NAME = null;//"us-central1";
-    public static final String LOCATION_SPEC = PROVIDER + (REGION_NAME == null ? "" : ":" + REGION_NAME);
-    public static final String STANDARD_HARDWARE_ID = "us-central1-b/n1-standard-1-d";
-    private static final int MAX_TAG_LENGTH = 63;
-
-    protected BrooklynProperties brooklynProperties;
-    protected ManagementContext ctx;
-    
-    protected TestApplication app;
-    protected Location jcloudsLocation;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        List<String> propsToRemove = ImmutableList.of("imageId", "imageDescriptionRegex", "imageNameRegex", "inboundPorts", "hardwareId", "minRam");
-        
-     // Don't let any defaults from brooklyn.properties (except credentials) interfere with test
-        brooklynProperties = BrooklynProperties.Factory.newDefault();
-        for (String propToRemove : propsToRemove) {
-            for (String propVariant : ImmutableList.of(propToRemove, CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, propToRemove))) {
-                brooklynProperties.remove("brooklyn.locations.jclouds."+PROVIDER+"."+propVariant);
-                brooklynProperties.remove("brooklyn.locations."+propVariant);
-                brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+"."+propVariant);
-                brooklynProperties.remove("brooklyn.jclouds."+propVariant);
-            }
-        }
-
-        // Also removes scriptHeader (e.g. if doing `. ~/.bashrc` and `. ~/.profile`, then that can cause "stdin: is not a tty")
-        brooklynProperties.remove("brooklyn.ssh.config.scriptHeader");
-        
-        ctx = new LocalManagementContext(brooklynProperties);
-        app = ApplicationBuilder.newManagedApp(TestApplication.class, ctx);
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (app != null) Entities.destroyAllCatching(app.getManagementContext());
-    }
-
-    @Test(groups = {"Live"})
-    public void test_DefaultImage() throws Exception {
-        runTest(ImmutableMap.<String,String>of());
-    }
-
-    // most of these not available
-    
-//    @Test(groups = {"Live"})
-//    public void test_GCEL_10_04() throws Exception {
-//        // release codename "squeeze"
-//        runTest(ImmutableMap.of("imageId", "gcel-10-04-v20130325", "loginUser", "admin", "hardwareId", STANDARD_HARDWARE_ID));
-//    }
-//
-//    @Test(groups = {"Live"})
-//    public void test_GCEL_12_04() throws Exception {
-//        // release codename "squeeze"
-//        runTest(ImmutableMap.of("imageId", "gcel-12-04-v20130325", "loginUser", "admin", "hardwareId", STANDARD_HARDWARE_ID));
-//    }
-//
-//    @Test(groups = {"Live"})
-//    public void test_Ubuntu_10_04() throws Exception {
-//        // release codename "squeeze"
-//        runTest(ImmutableMap.of("imageId", "ubuntu-10-04-v20120912", "loginUser", "admin", "hardwareId", STANDARD_HARDWARE_ID));
-//    }
-//
-//    @Test(groups = {"Live"})
-//    public void test_Ubuntu_12_04() throws Exception {
-//        // release codename "squeeze"
-//        runTest(ImmutableMap.of("imageId", "ubuntu-10-04-v20120912", "loginUser", "admin", "hardwareId", STANDARD_HARDWARE_ID));
-//    }
-//
-//    @Test(groups = {"Live"})
-//    public void test_CentOS_6() throws Exception {
-//        runTest(ImmutableMap.of("imageId", "centos-6-v20130325", "hardwareId", STANDARD_HARDWARE_ID));
-//    }
-
-    protected void runTest(Map<String,?> flags) throws Exception {
-        String tag = getClass().getSimpleName().toLowerCase();
-        int length = tag.length();
-        if (length > MAX_TAG_LENGTH)
-            tag = tag.substring(length - MAX_TAG_LENGTH, length);
-        Map<String,?> allFlags = MutableMap.<String,Object>builder()
-                .put("tags", ImmutableList.of(tag))
-                .putAll(flags)
-                .build();
-        jcloudsLocation = ctx.getLocationRegistry().resolve(LOCATION_SPEC, allFlags);
-
-        doTest(jcloudsLocation);
-    }
-
-    protected abstract void doTest(Location loc) throws Exception;
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java b/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java
deleted file mode 100644
index 58c3260..0000000
--- a/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java
+++ /dev/null
@@ -1,115 +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 brooklyn.entity;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.core.internal.BrooklynProperties;
-import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.entity.core.Entities;
-import org.apache.brooklyn.entity.factory.ApplicationBuilder;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.text.StringShortener;
-import org.apache.brooklyn.util.text.Strings;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.CaseFormat;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-/**
- * Runs a test with many different distros and versions.
- */
-public abstract class AbstractSoftlayerLiveTest {
-    
-    public static final String PROVIDER = "softlayer";
-    public static final int MAX_TAG_LENGTH = 20;
-    public static final int MAX_VM_NAME_LENGTH = 30;
-
-    protected BrooklynProperties brooklynProperties;
-    protected ManagementContext ctx;
-    
-    protected TestApplication app;
-    protected Location jcloudsLocation;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        List<String> propsToRemove = ImmutableList.of("imageId", "imageDescriptionRegex", "imageNameRegex", "inboundPorts", "hardwareId", "minRam");
-
-        // Don't let any defaults from brooklyn.properties (except credentials) interfere with test
-        brooklynProperties = BrooklynProperties.Factory.newDefault();
-        for (String propToRemove : propsToRemove) {
-            for (String propVariant : ImmutableList.of(propToRemove, CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, propToRemove))) {
-                brooklynProperties.remove("brooklyn.locations.jclouds."+PROVIDER+"."+propVariant);
-                brooklynProperties.remove("brooklyn.locations."+propVariant);
-                brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+"."+propVariant);
-                brooklynProperties.remove("brooklyn.jclouds."+propVariant);
-            }
-        }
-
-        // Also removes scriptHeader (e.g. if doing `. ~/.bashrc` and `. ~/.profile`, then that can cause "stdin: is not a tty")
-        brooklynProperties.remove("brooklyn.ssh.config.scriptHeader");
-        
-        ctx = new LocalManagementContext(brooklynProperties);
-        app = ApplicationBuilder.newManagedApp(TestApplication.class, ctx);
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-
-    @Test(groups = {"Live"})
-    public void test_Default() throws Exception {
-        runTest(ImmutableMap.<String,Object>of());
-    }
-
-    @Test(groups = {"Live"})
-    public void test_Ubuntu_12_0_4() throws Exception {
-        // Image: {id=UBUNTU_12_64, providerId=UBUNTU_12_64, os={family=ubuntu, version=12.04, description=Ubuntu / Ubuntu / 12.04.0-64 Minimal, is64Bit=true}, description=UBUNTU_12_64, status=AVAILABLE, loginUser=root}
-        runTest(ImmutableMap.<String,Object>of("imageId", "UBUNTU_12_64"));
-    }
-
-    @Test(groups = {"Live"})
-    public void test_Centos_6_0() throws Exception {
-      // Image: {id=CENTOS_6_64, providerId=CENTOS_6_64, os={family=centos, version=6.5, description=CentOS / CentOS / 6.5-64 LAMP for Bare Metal, is64Bit=true}, description=CENTOS_6_64, status=AVAILABLE, loginUser=root}
-        runTest(ImmutableMap.<String,Object>of("imageId", "CENTOS_6_64"));
-    }
-    
-    protected void runTest(Map<String,?> flags) throws Exception {
-        StringShortener shortener = Strings.shortener().separator("-");
-        shortener.canTruncate(getClass().getSimpleName(), MAX_TAG_LENGTH);
-        Map<String,?> allFlags = MutableMap.<String,Object>builder()
-                .put("tags", ImmutableList.of(shortener.getStringOfMaxLength(MAX_TAG_LENGTH)))
-                .put("vmNameMaxLength", MAX_VM_NAME_LENGTH)
-                .putAll(flags)
-                .build();
-        jcloudsLocation = ctx.getLocationRegistry().resolve(PROVIDER, allFlags);
-
-        doTest(jcloudsLocation);
-    }
-    
-    protected abstract void doTest(Location loc) throws Exception;
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/brooklyn/entity/basic/AbstractSoftwareProcessRestartIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/AbstractSoftwareProcessRestartIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/basic/AbstractSoftwareProcessRestartIntegrationTest.java
deleted file mode 100644
index cb610d7..0000000
--- a/software/base/src/test/java/brooklyn/entity/basic/AbstractSoftwareProcessRestartIntegrationTest.java
+++ /dev/null
@@ -1,97 +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 brooklyn.entity.basic;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.entity.core.Entities;
-import org.apache.brooklyn.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.entity.lifecycle.ServiceStateLogic;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.CollectionFunctionals;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.SoftwareProcess.RestartSoftwareParameters;
-import brooklyn.entity.basic.SoftwareProcess.StopSoftwareParameters;
-
-import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-/**
- * Tests restart of the software *process* (as opposed to the VM).
- */
-public abstract class AbstractSoftwareProcessRestartIntegrationTest extends BrooklynAppLiveTestSupport {
-    
-    // TODO Remove duplication from TomcatServerRestartIntegrationTest and MySqlRestartIntegrationTest
-    
-    @SuppressWarnings("unused")
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractSoftwareProcessRestartIntegrationTest.class);
-
-    protected abstract EntitySpec<? extends SoftwareProcess> newEntitySpec();
-    
-    @Test(groups="Integration")
-    public void testStopProcessAndRestart() throws Exception {
-        runStopProcessAndRestart(
-                SoftwareProcess.RESTART, 
-                ImmutableMap.of(RestartSoftwareParameters.RESTART_MACHINE.getName(), RestartSoftwareParameters.RestartMachineMode.FALSE));
-    }
-    
-    @Test(groups="Integration")
-    public void testStopProcessAndStart() throws Exception {
-        runStopProcessAndRestart(
-                SoftwareProcess.START, 
-                ImmutableMap.of("locations", ImmutableList.of()));
-    }
-    
-    protected void runStopProcessAndRestart(Effector<?> restartEffector, Map<String, ?> args) throws Exception {
-        LocalhostMachineProvisioningLocation loc = app.newLocalhostProvisioningLocation();
-        SoftwareProcess entity = app.createAndManageChild(newEntitySpec());
-        
-        // Start the app
-        app.start(ImmutableList.of(loc));
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_UP, true);
-        EntityTestUtils.assertAttributeEqualsEventually(app, SoftwareProcess.SERVICE_UP, true);
-
-        // Stop the process
-        Entities.invokeEffector(app, entity, SoftwareProcess.STOP, ImmutableMap.of(
-                StopSoftwareParameters.STOP_MACHINE_MODE.getName(), StopSoftwareParameters.StopMode.NEVER))
-                .get();
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_UP, false);
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_STATE_ACTUAL, Lifecycle.STOPPED);
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_PROCESS_IS_RUNNING, false);
-        EntityTestUtils.assertAttributeEventually(entity, ServiceStateLogic.SERVICE_NOT_UP_INDICATORS, CollectionFunctionals.<String>mapSizeEquals(1));
-        
-        // Restart the process
-        Entities.invokeEffector(app, entity, restartEffector, args).get();
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_UP, true);
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-        EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_PROCESS_IS_RUNNING, true);
-        EntityTestUtils.assertAttributeEqualsEventually(entity, ServiceStateLogic.SERVICE_NOT_UP_INDICATORS, ImmutableMap.<String, Object>of());
-
-        EntityTestUtils.assertAttributeEqualsEventually(app, SoftwareProcess.SERVICE_UP, true);
-        EntityTestUtils.assertAttributeEqualsEventually(app, SoftwareProcess.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcess.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcess.java b/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcess.java
deleted file mode 100644
index d0ddf38..0000000
--- a/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcess.java
+++ /dev/null
@@ -1,32 +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 brooklyn.entity.basic;
-
-import org.apache.brooklyn.api.entity.ImplementedBy;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.entity.core.BrooklynConfigKeys;
-
-@ImplementedBy(DoNothingSoftwareProcessImpl.class)
-public interface DoNothingSoftwareProcess extends SoftwareProcess {
-    
-    public static final ConfigKey<Boolean> SKIP_ON_BOX_BASE_DIR_RESOLUTION = ConfigKeys.newConfigKeyWithDefault(
-            BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION,
-            true);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessDriver.java b/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessDriver.java
deleted file mode 100644
index 3439f1f..0000000
--- a/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessDriver.java
+++ /dev/null
@@ -1,68 +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 brooklyn.entity.basic;
-
-import org.apache.brooklyn.api.internal.EntityLocal;
-import org.apache.brooklyn.location.basic.SshMachineLocation;
-
-/**
- * Implements methods in {@link brooklyn.entity.basic.AbstractSoftwareProcessSshDriver}
- * such that no actions are performed.
- * <p>
- * {@link #isRunning()} returns true.
- */
-public class DoNothingSoftwareProcessDriver extends AbstractSoftwareProcessSshDriver {
-
-    public DoNothingSoftwareProcessDriver(EntityLocal entity, SshMachineLocation machine) {
-        super(entity, machine);
-    }
-
-    @Override
-    public boolean isRunning() {
-        return true;
-    }
-
-    @Override
-    public void copyPreInstallResources() {
-    }
-
-    @Override
-    public void copyInstallResources() {
-    }
-
-    @Override
-    public void copyRuntimeResources() {
-    }
-
-    @Override
-    public void install() {
-    }
-
-    @Override
-    public void customize() {
-    }
-
-    @Override
-    public void launch() {
-    }
-
-    @Override
-    public void stop() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessImpl.java b/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessImpl.java
deleted file mode 100644
index dc862fe..0000000
--- a/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessImpl.java
+++ /dev/null
@@ -1,37 +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 brooklyn.entity.basic;
-
-import org.apache.brooklyn.entity.lifecycle.Lifecycle;
-
-public class DoNothingSoftwareProcessImpl extends SoftwareProcessImpl implements DoNothingSoftwareProcess {
-
-    @Override
-    public Class getDriverInterface() {
-        return DoNothingSoftwareProcessDriver.class;
-    }
-    
-    @Override
-    protected void connectSensors() {
-        super.connectSensors();
-        if (getAttribute(SERVICE_STATE_ACTUAL) == Lifecycle.STARTING) {
-            setAttribute(SERVICE_UP, true);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java b/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java
deleted file mode 100644
index 3b2838a..0000000
--- a/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java
+++ /dev/null
@@ -1,83 +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 brooklyn.entity.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.entity.core.Entities;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-public class SameServerEntityTest {
-
-    private LocalhostMachineProvisioningLocation loc;
-    private ManagementContext mgmt;
-    private TestApplication app;
-    private SameServerEntity entity;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() {
-        loc = new LocalhostMachineProvisioningLocation();
-        app = TestApplication.Factory.newManagedInstanceForTests();
-        mgmt = app.getManagementContext();
-        entity = app.createAndManageChild(EntitySpec.create(SameServerEntity.class));
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() {
-        if (app != null) Entities.destroyAll(mgmt);
-    }
-    
-    @Test
-    public void testUsesSameMachineLocationForEachChild() throws Exception {
-        Entity child1 = entity.addChild(EntitySpec.create(TestEntity.class));
-        Entity child2 = entity.addChild(EntitySpec.create(TestEntity.class));
-        Entities.manage(child1);
-        Entities.manage(child2);
-        
-        app.start(ImmutableList.of(loc));
-        
-        Location child1Loc = Iterables.getOnlyElement(child1.getLocations());
-        Location child2Loc = Iterables.getOnlyElement(child2.getLocations());
-        
-        assertSame(child1Loc, child2Loc);
-        assertTrue(child1Loc instanceof LocalhostMachine, "loc="+child1Loc);
-        
-        assertEquals(ImmutableSet.of(child1Loc), ImmutableSet.copyOf(loc.getInUse()));
-
-        app.stop();
-        
-        assertEquals(ImmutableSet.of(), ImmutableSet.copyOf(loc.getInUse()));
-    }
-}