You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sv...@apache.org on 2015/11/24 22:19:35 UTC
[1/3] incubator-brooklyn git commit: Fix javadoc typo in SshTool
Repository: incubator-brooklyn
Updated Branches:
refs/heads/master b264fc98a -> 3922b0ef9
Fix javadoc typo in SshTool
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/f8c76736
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/f8c76736
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/f8c76736
Branch: refs/heads/master
Commit: f8c7673604ebc572f3eb3bb01d0dfe53a954c8e6
Parents: 42c1113
Author: Aled Sage <al...@gmail.com>
Authored: Wed Nov 18 15:33:22 2015 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Nov 18 22:05:45 2015 +0000
----------------------------------------------------------------------
.../java/org/apache/brooklyn/util/core/internal/ssh/SshTool.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f8c76736/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/SshTool.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/SshTool.java b/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/SshTool.java
index df3947f..ee1a626 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/SshTool.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/SshTool.java
@@ -46,7 +46,7 @@ import org.apache.brooklyn.util.time.Duration;
public interface SshTool extends ShellTool {
/** Public-facing global config keys for Brooklyn are defined in ConfigKeys,
- * and have this prefix pre-prended to the config keys in this class.
+ * and have this prefix prepended to the config keys in this class.
* These keys are detected from entity/global config and automatically applied to ssh executions. */
public static final String BROOKLYN_CONFIG_KEY_PREFIX = "brooklyn.ssh.config.";
[3/3] incubator-brooklyn git commit: Closes #1045
Posted by sv...@apache.org.
Closes #1045
Adds WinRmTool interface
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/3922b0ef
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/3922b0ef
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/3922b0ef
Branch: refs/heads/master
Commit: 3922b0ef94259e2b1789a18b5e1f83886113581c
Parents: b264fc9 f8c7673
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Nov 24 23:19:25 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Tue Nov 24 23:19:25 2015 +0200
----------------------------------------------------------------------
.../core/entity/BrooklynConfigKeys.java | 9 +
.../util/core/internal/ssh/SshTool.java | 2 +-
.../AbstractSoftwareProcessWinRmDriver.java | 31 ++-
.../location/WinRmMachineLocationLiveTest.java | 5 +-
.../windows/WindowsPerformanceCounterFeed.java | 2 +-
.../location/winrm/WinRmMachineLocation.java | 265 +++++++++----------
.../util/core/internal/winrm/WinRmTool.java | 74 ++++++
.../core/internal/winrm/WinRmToolResponse.java | 46 ++++
.../internal/winrm/pywinrm/Winrm4jTool.java | 156 +++++++++++
.../WindowsPerformanceCounterFeedTest.java | 3 +-
10 files changed, 439 insertions(+), 154 deletions(-)
----------------------------------------------------------------------
[2/3] incubator-brooklyn git commit: Adds WinRmTool interface
Posted by sv...@apache.org.
Adds WinRmTool interface
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/42c11132
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/42c11132
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/42c11132
Branch: refs/heads/master
Commit: 42c1113258bb66ba98c7fcde6c304dad4faed38c
Parents: ca89ed4
Author: Aled Sage <al...@gmail.com>
Authored: Wed Nov 18 15:33:07 2015 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Nov 18 22:05:45 2015 +0000
----------------------------------------------------------------------
.../core/entity/BrooklynConfigKeys.java | 9 +
.../AbstractSoftwareProcessWinRmDriver.java | 31 ++-
.../location/WinRmMachineLocationLiveTest.java | 5 +-
.../windows/WindowsPerformanceCounterFeed.java | 2 +-
.../location/winrm/WinRmMachineLocation.java | 265 +++++++++----------
.../util/core/internal/winrm/WinRmTool.java | 74 ++++++
.../core/internal/winrm/WinRmToolResponse.java | 46 ++++
.../internal/winrm/pywinrm/Winrm4jTool.java | 156 +++++++++++
.../WindowsPerformanceCounterFeedTest.java | 3 +-
9 files changed, 438 insertions(+), 153 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/42c11132/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java b/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java
index 1185791..974f88c 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java
@@ -177,6 +177,10 @@ public class BrooklynConfigKeys {
* and have this prefix pre-prended to the config keys in this class. */
public static final String BROOKLYN_SSH_CONFIG_KEY_PREFIX = "brooklyn.ssh.config.";
+ /** Public-facing global config keys for Brooklyn are defined in ConfigKeys,
+ * and have this prefix pre-prended to the config keys in this class. */
+ public static final String BROOKLYN_WINRM_CONFIG_KEY_PREFIX = "brooklyn.winrm.config.";
+
// some checks (this line, and a few Preconditions below) that the remote values aren't null,
// because they have some funny circular references
static { assert BROOKLYN_SSH_CONFIG_KEY_PREFIX.equals(SshTool.BROOKLYN_CONFIG_KEY_PREFIX) : "static final initializer classload ordering problem"; }
@@ -186,6 +190,11 @@ public class BrooklynConfigKeys {
"SshTool implementation to use (or null for default)",
null);
+ public static final ConfigKey<String> WINRM_TOOL_CLASS = newStringConfigKey(
+ BROOKLYN_WINRM_CONFIG_KEY_PREFIX + "winrmToolClass",
+ "WinRmTool implementation to use (or null for default)",
+ null);
+
/**
* @deprecated since 0.9.0; use {@link #SSH_TOOL_CLASS}
*/
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/42c11132/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java
index 4b3da76..6a39cc2 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java
@@ -18,9 +18,17 @@
*/
package org.apache.brooklyn.entity.software.base;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Maps;
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+import static org.apache.brooklyn.util.JavaGroovyEquivalents.elvis;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.api.sensor.AttributeSensor;
@@ -31,6 +39,8 @@ import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.software.base.lifecycle.NativeWindowsScriptRunner;
import org.apache.brooklyn.entity.software.base.lifecycle.WinRmExecuteHelper;
import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
+import org.apache.brooklyn.util.core.internal.winrm.WinRmTool;
+import org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.exceptions.ReferenceWithError;
@@ -42,16 +52,9 @@ import org.python.core.PyException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-import static org.apache.brooklyn.util.JavaGroovyEquivalents.elvis;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
public abstract class AbstractSoftwareProcessWinRmDriver extends AbstractSoftwareProcessDriver implements NativeWindowsScriptRunner {
private static final Logger LOG = LoggerFactory.getLogger(AbstractSoftwareProcessWinRmDriver.class);
@@ -260,7 +263,7 @@ public abstract class AbstractSoftwareProcessWinRmDriver extends AbstractSoftwar
}
public int executePsScriptNoRetry(List<String> psScript) {
- return getLocation().executePsScriptNoRetry(psScript).getStatusCode();
+ return getLocation().executePsScript(ImmutableMap.of(WinRmTool.PROP_EXEC_TRIES, 1), psScript).getStatusCode();
}
public int executePsScript(List<String> psScript) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/42c11132/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
index 4eab220..bfca1d8 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/location/WinRmMachineLocationLiveTest.java
@@ -39,6 +39,7 @@ import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
+import org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse;
import org.apache.brooklyn.util.text.Identifiers;
import org.apache.brooklyn.util.time.Time;
import org.slf4j.Logger;
@@ -59,8 +60,6 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
-
/**
* Tests execution of commands (batch and powershell) on Windows over WinRM, and of
* file upload.
@@ -72,8 +71,8 @@ import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
* Please update the docs if you encountered new situations, or change the behaviuor
* of existing use-cases.
*/
-public class WinRmMachineLocationLiveTest {
+public class WinRmMachineLocationLiveTest {
private static final int MAX_EXECUTOR_THREADS = 100;
/*
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/42c11132/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java b/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
index 73a76cb..b6f8684 100644
--- a/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
+++ b/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
@@ -20,7 +20,6 @@ package org.apache.brooklyn.feed.windows;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
import java.util.Collection;
import java.util.Iterator;
@@ -49,6 +48,7 @@ import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterPollConfig;
import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/42c11132/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
index 3a7dbd5..7f2e4ed 100644
--- a/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
+++ b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
@@ -18,15 +18,11 @@
*/
package org.apache.brooklyn.location.winrm;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.InetAddress;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -37,65 +33,74 @@ import org.apache.brooklyn.api.location.MachineDetails;
import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.api.location.OsDetails;
import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.ConfigUtils;
+import org.apache.brooklyn.core.config.Sanitizer;
+import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.location.AbstractLocation;
import org.apache.brooklyn.core.location.access.PortForwardManager;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.internal.ssh.SshTool;
+import org.apache.brooklyn.util.core.internal.winrm.WinRmTool;
+import org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse;
+import org.apache.brooklyn.util.core.internal.winrm.pywinrm.Winrm4jTool;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.text.Strings;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Charsets;
+import com.google.common.base.Function;
import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
+import com.google.common.collect.Iterables;
import com.google.common.net.HostAndPort;
import com.google.common.reflect.TypeToken;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.stream.Streams;
-import org.apache.brooklyn.util.time.Duration;
-import org.apache.brooklyn.util.time.Time;
-
-import io.cloudsoft.winrm4j.winrm.WinRmTool;
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
-
public class WinRmMachineLocation extends AbstractLocation implements MachineLocation {
private static final Logger LOG = LoggerFactory.getLogger(WinRmMachineLocation.class);
- // FIXME Respect `port` config when using {@link WinRmTool}
- public static final ConfigKey<Integer> WINRM_PORT = ConfigKeys.newIntegerConfigKey(
- "port",
- "WinRM port to use when connecting to the remote machine",
- 5985);
-
- // TODO merge with {link SshTool#PROP_USER} and {@link SshMachineLocation#user}
- public static final ConfigKey<String> USER = ConfigKeys.newStringConfigKey("user",
- "Username to use when connecting to the remote machine");
-
- // TODO merge with {link SshTool#PROP_PASSWORD}
- public static final ConfigKey<String> PASSWORD = ConfigKeys.newStringConfigKey("password",
- "Password to use when connecting to the remote machine");
-
- public static final ConfigKey<Integer> COPY_FILE_CHUNK_SIZE_BYTES = ConfigKeys.newIntegerConfigKey("windows.copy.file.size.bytes",
- "Size of file chunks (in bytes) to be used when copying a file to the remote server", 1024);
-
- public static final ConfigKey<InetAddress> ADDRESS = ConfigKeys.newConfigKey(
+ public static final ConfigKey<InetAddress> ADDRESS = ConfigKeys.newConfigKey(
InetAddress.class,
"address",
"Address of the remote machine");
+ public static final ConfigKey<Integer> WINRM_PORT = WinRmTool.PROP_PORT;
+
+ // TODO merge with {link SshTool#PROP_USER} and {@link SshMachineLocation#user}?
+ public static final ConfigKey<String> USER = WinRmTool.PROP_USER;
+
+ // TODO merge with {link SshTool#PROP_PASSWORD}?
+ public static final ConfigKey<String> PASSWORD = WinRmTool.PROP_PASSWORD;
+
+ // TODO Delete once winrm4j supports this better?
+ public static final ConfigKey<Integer> COPY_FILE_CHUNK_SIZE_BYTES = WinRmTool.COPY_FILE_CHUNK_SIZE_BYTES;
+
+ // Note that SshTool's implementation class *must* use a different key name. Both may be used
+ // within a location's configuration to indicate the implementation to use for WinRmTool and
+ // for SshTool - that will require two different configuration values.
+ public static final ConfigKey<String> WINRM_TOOL_CLASS = ConfigKeys.newConfigKeyWithPrefixRemoved(
+ BrooklynConfigKeys.BROOKLYN_WINRM_CONFIG_KEY_PREFIX,
+ Preconditions.checkNotNull(BrooklynConfigKeys.WINRM_TOOL_CLASS, "static final initializer classload ordering problem"));
+
+ /**
+ * @deprecated since 0.9.0; config never read; will be removed in future version.
+ */
+ @Deprecated
public static final ConfigKey<Integer> EXECUTION_ATTEMPTS = ConfigKeys.newIntegerConfigKey(
"windows.exec.attempts",
"Number of attempts to execute a remote command",
1);
// TODO See SshTool#PROP_SSH_TRIES, where it was called "sshTries"; remove duplication? Merge into one well-named thing?
- public static final ConfigKey<Integer> EXEC_TRIES = ConfigKeys.newIntegerConfigKey(
- "execTries",
- "Max number of times to attempt WinRM operations",
- 10);
+ public static final ConfigKey<Integer> EXEC_TRIES = WinRmTool.PROP_EXEC_TRIES;
public static final ConfigKey<Iterable<String>> PRIVATE_ADDRESSES = ConfigKeys.newConfigKey(
new TypeToken<Iterable<String>>() {},
@@ -109,6 +114,43 @@ public class WinRmMachineLocation extends AbstractLocation implements MachineLoc
"NAT'ed ports, giving the mapping from private TCP port to a public host:port",
null);
+ public static final Set<HasConfigKey<?>> ALL_WINRM_CONFIG_KEYS =
+ ImmutableSet.<HasConfigKey<?>>builder()
+ .addAll(ConfigUtils.getStaticKeysOnClass(WinRmMachineLocation.class))
+ .addAll(ConfigUtils.getStaticKeysOnClass(WinRmTool.class))
+ .build();
+
+ public static final Set<String> ALL_SSH_CONFIG_KEY_NAMES =
+ ImmutableSet.copyOf(Iterables.transform(ALL_WINRM_CONFIG_KEYS, new Function<HasConfigKey<?>,String>() {
+ @Override
+ public String apply(HasConfigKey<?> input) {
+ return input.getConfigKey().getName();
+ }
+ }));
+
+ @Override
+ public void init() {
+ super.init();
+
+ // Register any pre-existing port-mappings with the PortForwardManager
+ Map<Integer, String> tcpPortMappings = getConfig(TCP_PORT_MAPPINGS);
+ if (tcpPortMappings != null) {
+ PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
+ for (Map.Entry<Integer, String> entry : tcpPortMappings.entrySet()) {
+ int targetPort = entry.getKey();
+ HostAndPort publicEndpoint = HostAndPort.fromString(entry.getValue());
+ if (!publicEndpoint.hasPort()) {
+ throw new IllegalArgumentException("Invalid portMapping ('"+entry.getValue()+"') for port "+targetPort+" in machine "+this);
+ }
+ pfm.associate(publicEndpoint.getHostText(), publicEndpoint, this, targetPort);
+ }
+ }
+ }
+
+ public String getUser() {
+ return config().get(USER);
+ }
+
@Override
public InetAddress getAddress() {
return getConfig(ADDRESS);
@@ -154,63 +196,66 @@ public class WinRmMachineLocation extends AbstractLocation implements MachineLoc
}
public WinRmToolResponse executeScript(List<String> script) {
- int execTries = getRequiredConfig(EXEC_TRIES);
- Collection<Throwable> exceptions = Lists.newArrayList();
- for (int i = 0; i < execTries; i++) {
- try {
- return executeScriptNoRetry(script);
- } catch (Exception e) {
- Exceptions.propagateIfFatal(e);
- if (i == (execTries+1)) {
- LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
- } else if (i == 0) {
- LOG.warn("Ignoring WinRM exception and retrying (attempt "+(i+1)+" of "+execTries+")", e);
- } else {
- LOG.debug("Ignoring WinRM exception and retrying (attempt "+(i+1)+" of "+execTries+")", e);
- }
- exceptions.add(e);
- }
- }
- throw Exceptions.propagate("failed to execute shell script", exceptions);
+ return executeScript(ImmutableMap.of(), script);
}
-
- protected WinRmToolResponse executeScriptNoRetry(List<String> script) {
- WinRmTool winRmTool = WinRmTool.connect(getHostAndPort(), getUser(), getPassword());
- WinRmToolResponse response = winRmTool.executeScript(script);
- return response;
+
+ public WinRmToolResponse executeScript(Map<?,?> props, List<String> script) {
+ WinRmTool tool = newWinRmTool(props);
+ return tool.executeScript(script);
}
public WinRmToolResponse executePsScript(String psScript) {
- return executePsScript(ImmutableList.of(psScript));
+ return executePsScript(ImmutableMap.of(), ImmutableList.of(psScript));
}
public WinRmToolResponse executePsScript(List<String> psScript) {
- int execTries = getRequiredConfig(EXEC_TRIES);
- Collection<Throwable> exceptions = Lists.newArrayList();
- for (int i = 0; i < execTries; i++) {
- try {
- return executePsScriptNoRetry(psScript);
- } catch (Exception e) {
- Exceptions.propagateIfFatal(e);
- if (i == (execTries+1)) {
- LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
- } else if (i == 0) {
- LOG.warn("Ignoring WinRM exception and retrying after 5 seconds (attempt "+(i+1)+" of "+execTries+")", e);
- Time.sleep(Duration.FIVE_SECONDS);
+ return executePsScript(ImmutableMap.of(), psScript);
+ }
+
+ public WinRmToolResponse executePsScript(Map<?,?> props, List<String> psScript) {
+ WinRmTool tool = newWinRmTool(props);
+ return tool.executePs(psScript);
+ }
+
+ protected WinRmTool newWinRmTool(Map<?,?> props) {
+ // TODO See comments/TODOs in SshMachineLocation.connectSsh()
+ try {
+ ConfigBag args = new ConfigBag();
+
+ for (Map.Entry<String,Object> entry: config().getBag().getAllConfig().entrySet()) {
+ String key = entry.getKey();
+ if (key.startsWith(WinRmTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
+ key = Strings.removeFromStart(key, WinRmTool.BROOKLYN_CONFIG_KEY_PREFIX);
+ args.putStringKey(key, entry.getValue());
+ }
+ }
+
+ for (Map.Entry<String,Object> entry: config().getBag().getAllConfig().entrySet()) {
+ String key = entry.getKey();
+ if (ALL_SSH_CONFIG_KEY_NAMES.contains(key)) {
} else {
- LOG.debug("Ignoring WinRM exception and retrying after 5 seconds (attempt "+(i+1)+" of "+execTries+")", e);
- Time.sleep(Duration.FIVE_SECONDS);
+ // this key is not applicable here; ignore it
+ continue;
}
- exceptions.add(e);
+ args.putStringKey(key, entry.getValue());
}
- }
- throw Exceptions.propagate("failed to execute powershell script", exceptions);
- }
- public WinRmToolResponse executePsScriptNoRetry(List<String> psScript) {
- WinRmTool winRmTool = WinRmTool.connect(getHostAndPort(), getUser(), getPassword());
- WinRmToolResponse response = winRmTool.executePs(psScript);
- return response;
+ args.putAll(props);
+ args.configure(SshTool.PROP_HOST, getAddress().getHostAddress());
+
+ if (LOG.isTraceEnabled()) LOG.trace("creating WinRM session for "+Sanitizer.sanitize(args));
+
+ // look up tool class
+ String toolClass = args.get(WINRM_TOOL_CLASS);
+ if (toolClass == null) toolClass = Winrm4jTool.class.getName();
+ WinRmTool tool = (WinRmTool) Class.forName(toolClass).getConstructor(Map.class).newInstance(args.getAllConfig());
+
+ if (LOG.isTraceEnabled()) LOG.trace("using ssh-tool {} (of type {}); props ", tool, toolClass);
+
+ return tool;
+ } catch (Exception e) {
+ throw Exceptions.propagate(e);
+ }
}
public int copyTo(File source, String destination) {
@@ -228,61 +273,15 @@ public class WinRmMachineLocation extends AbstractLocation implements MachineLoc
}
public int copyTo(InputStream source, String destination) {
- executePsScript(ImmutableList.of("rm -ErrorAction SilentlyContinue " + destination));
- try {
- int chunkSize = getConfig(COPY_FILE_CHUNK_SIZE_BYTES);
- byte[] inputData = new byte[chunkSize];
- int bytesRead;
- int expectedFileSize = 0;
- while ((bytesRead = source.read(inputData)) > 0) {
- byte[] chunk;
- if (bytesRead == chunkSize) {
- chunk = inputData;
- } else {
- chunk = Arrays.copyOf(inputData, bytesRead);
- }
- executePsScript(ImmutableList.of("If ((!(Test-Path " + destination + ")) -or ((Get-Item '" + destination + "').length -eq " +
- expectedFileSize + ")) {Add-Content -Encoding Byte -path " + destination +
- " -value ([System.Convert]::FromBase64String(\"" + new String(Base64.encodeBase64(chunk)) + "\"))}"));
- expectedFileSize += bytesRead;
- }
-
- return 0;
- } catch (java.io.IOException e) {
- throw Exceptions.propagate(e);
- }
- }
-
- @Override
- public void init() {
- super.init();
-
- // Register any pre-existing port-mappings with the PortForwardManager
- Map<Integer, String> tcpPortMappings = getConfig(TCP_PORT_MAPPINGS);
- if (tcpPortMappings != null) {
- PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
- for (Map.Entry<Integer, String> entry : tcpPortMappings.entrySet()) {
- int targetPort = entry.getKey();
- HostAndPort publicEndpoint = HostAndPort.fromString(entry.getValue());
- if (!publicEndpoint.hasPort()) {
- throw new IllegalArgumentException("Invalid portMapping ('"+entry.getValue()+"') for port "+targetPort+" in machine "+this);
- }
- pfm.associate(publicEndpoint.getHostText(), publicEndpoint, this, targetPort);
- }
- }
+ return copyTo(ImmutableMap.of(), source, destination);
}
- public String getUser() {
- return config().get(USER);
- }
-
- private String getPassword() {
- return config().get(PASSWORD);
+
+ public int copyTo(Map<?,?> props, InputStream source, String destination) {
+ WinRmTool tool = newWinRmTool(props);
+ WinRmToolResponse response = tool.copyToServer(source, destination);
+ return response.getStatusCode();
}
- private <T> T getRequiredConfig(ConfigKey<T> key) {
- return checkNotNull(getConfig(key), "key %s must be set", key);
- }
-
public static String getDefaultUserMetadataString() {
// Using an encoded command obviates the need to escape
String unencodePowershell = Joiner.on("\r\n").join(ImmutableList.of(
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/42c11132/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmTool.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmTool.java b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmTool.java
new file mode 100644
index 0000000..6d2fb06
--- /dev/null
+++ b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmTool.java
@@ -0,0 +1,74 @@
+/*
+ * 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.internal.winrm;
+
+import static org.apache.brooklyn.core.config.ConfigKeys.newConfigKey;
+import static org.apache.brooklyn.core.config.ConfigKeys.newIntegerConfigKey;
+import static org.apache.brooklyn.core.config.ConfigKeys.newStringConfigKey;
+
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
+import org.apache.brooklyn.util.time.Duration;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+
+@Beta
+public interface WinRmTool {
+
+ /** Public-facing global config keys for Brooklyn are defined in ConfigKeys,
+ * and have this prefix prepended to the config keys in this class.
+ * These keys are detected from entity/global config and automatically applied to ssh executions. */
+ String BROOKLYN_CONFIG_KEY_PREFIX = Preconditions.checkNotNull(BrooklynConfigKeys.BROOKLYN_WINRM_CONFIG_KEY_PREFIX,
+ "static final initializer classload ordering problem");
+
+ ConfigKey<String> PROP_HOST = newStringConfigKey("host", "Host to connect to (required)", null);
+ ConfigKey<Integer> PROP_PORT = newIntegerConfigKey("port", "WinRM port to use when connecting to the remote machine", 5985);
+ ConfigKey<String> PROP_USER = newStringConfigKey("user", "User to connect as", null);
+ ConfigKey<String> PROP_PASSWORD = newStringConfigKey("password", "Password to use to connect", null);
+
+ // TODO See SshTool#PROP_SSH_TRIES, where it was called "sshTries"; remove duplication? Merge into one well-named thing?
+ ConfigKey<Integer> PROP_EXEC_TRIES = ConfigKeys.newIntegerConfigKey(
+ "execTries",
+ "Max number of times to attempt WinRM operations",
+ 10);
+
+ ConfigKey<Duration> PROP_EXEC_RETRY_DELAY = newConfigKey(
+ Duration.class,
+ "execRetryDelay",
+ "Max time between retries (backing off exponentially to this delay)",
+ Duration.TEN_SECONDS);
+
+ // May be ignored by implementations that more efficiently copy the file.
+ @Beta
+ ConfigKey<Integer> COPY_FILE_CHUNK_SIZE_BYTES = ConfigKeys.newIntegerConfigKey(
+ "windows.copy.file.size.bytes",
+ "Size of file chunks (in bytes) to be used when copying a file to the remote server",
+ 1024);
+
+ WinRmToolResponse executeScript(List<String> commands);
+
+ WinRmToolResponse executePs(List<String> commands);
+
+ WinRmToolResponse copyToServer(InputStream source, String destination);
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/42c11132/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmToolResponse.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmToolResponse.java b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmToolResponse.java
new file mode 100644
index 0000000..a3ef888
--- /dev/null
+++ b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/WinRmToolResponse.java
@@ -0,0 +1,46 @@
+/*
+ * 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.internal.winrm;
+
+import com.google.common.annotations.Beta;
+
+@Beta
+public class WinRmToolResponse {
+ private final String stdout;
+ private final String stderr;
+ private final int statusCode;
+
+ public WinRmToolResponse(String stdout, String stderr, int statusCode) {
+ this.stdout = stdout;
+ this.stderr = stderr;
+ this.statusCode = statusCode;
+ }
+
+ public String getStdOut() {
+ return stdout;
+ }
+
+ public String getStdErr() {
+ return stderr;
+ }
+
+ public int getStatusCode() {
+ return statusCode;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/42c11132/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/pywinrm/Winrm4jTool.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/pywinrm/Winrm4jTool.java b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/pywinrm/Winrm4jTool.java
new file mode 100644
index 0000000..9a4dfb9
--- /dev/null
+++ b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/pywinrm/Winrm4jTool.java
@@ -0,0 +1,156 @@
+/*
+ * 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.internal.winrm.pywinrm;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.Sanitizer;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+import org.apache.commons.codec.binary.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+
+@Beta
+public class Winrm4jTool implements org.apache.brooklyn.util.core.internal.winrm.WinRmTool {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Winrm4jTool.class);
+
+ private final ConfigBag bag;
+ private final String host;
+ private final Integer port;
+ private final String user;
+ private final String password;
+ private final int execTries;
+ private final Duration execRetryDelay;
+
+ public Winrm4jTool(Map<String,?> config) {
+ this(ConfigBag.newInstance(config));
+ }
+
+ public Winrm4jTool(ConfigBag config) {
+ this.bag = checkNotNull(config, "config bag");
+ host = getRequiredConfig(config, PROP_HOST);
+ port = getRequiredConfig(config, PROP_PORT);
+ user = getRequiredConfig(config, PROP_USER);
+ password = getRequiredConfig(config, PROP_PASSWORD);
+ execTries = getRequiredConfig(config, PROP_EXEC_TRIES);
+ execRetryDelay = getRequiredConfig(config, PROP_EXEC_RETRY_DELAY);
+ }
+
+ @Override
+ public org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse executeScript(final List<String> commands) {
+ return exec(new Callable<io.cloudsoft.winrm4j.winrm.WinRmToolResponse>() {
+ @Override public WinRmToolResponse call() throws Exception {
+ return connect().executeScript(commands);
+ }
+ });
+ }
+
+ @Override
+ public org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse executePs(final List<String> commands) {
+ return exec(new Callable<io.cloudsoft.winrm4j.winrm.WinRmToolResponse>() {
+ @Override public WinRmToolResponse call() throws Exception {
+ return connect().executePs(commands);
+ }
+ });
+ }
+
+ @Override
+ public org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse copyToServer(InputStream source, String destination) {
+ executePs(ImmutableList.of("rm -ErrorAction SilentlyContinue " + destination));
+ try {
+ int chunkSize = getRequiredConfig(bag, COPY_FILE_CHUNK_SIZE_BYTES);
+ byte[] inputData = new byte[chunkSize];
+ int bytesRead;
+ int expectedFileSize = 0;
+ while ((bytesRead = source.read(inputData)) > 0) {
+ byte[] chunk;
+ if (bytesRead == chunkSize) {
+ chunk = inputData;
+ } else {
+ chunk = Arrays.copyOf(inputData, bytesRead);
+ }
+ executePs(ImmutableList.of("If ((!(Test-Path " + destination + ")) -or ((Get-Item '" + destination + "').length -eq " +
+ expectedFileSize + ")) {Add-Content -Encoding Byte -path " + destination +
+ " -value ([System.Convert]::FromBase64String(\"" + new String(Base64.encodeBase64(chunk)) + "\"))}"));
+ expectedFileSize += bytesRead;
+ }
+
+ return new org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse("", "", 0);
+ } catch (java.io.IOException e) {
+ throw Exceptions.propagate(e);
+ }
+ }
+
+ private org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse exec(Callable<io.cloudsoft.winrm4j.winrm.WinRmToolResponse> task) {
+ Collection<Throwable> exceptions = Lists.newArrayList();
+ for (int i = 0; i < execTries; i++) {
+ try {
+ return wrap(task.call());
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ Duration sleep = Duration.millis(Math.min(Math.pow(2, i) * 1000, execRetryDelay.toMilliseconds()));
+ if (i == (execTries+1)) {
+ LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
+ } else if (i == 0) {
+ LOG.warn("Ignoring WinRM exception and will retry after "+sleep+" (attempt "+(i+1)+" of "+execTries+")", e);
+ Time.sleep(sleep);
+ } else {
+ LOG.debug("Ignoring WinRM exception and will retry after "+sleep+" (attempt "+(i+1)+" of "+execTries+")", e);
+ Time.sleep(sleep);
+ }
+ exceptions.add(e);
+ }
+ }
+ throw Exceptions.propagate("failed to execute command", exceptions);
+ }
+
+ private io.cloudsoft.winrm4j.winrm.WinRmTool connect() {
+ return io.cloudsoft.winrm4j.winrm.WinRmTool.connect(host+":"+port, user, password);
+ }
+
+ private <T> T getRequiredConfig(ConfigBag bag, ConfigKey<T> key) {
+ T result = bag.get(key);
+ if (result == null) {
+ throw new IllegalArgumentException("Missing config "+key+" in "+Sanitizer.sanitize(bag));
+ }
+ return result;
+ }
+
+ private org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse wrap(io.cloudsoft.winrm4j.winrm.WinRmToolResponse resp) {
+ return new org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse(resp.getStdOut(), resp.getStdErr(), resp.getStatusCode());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/42c11132/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java b/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
index 059797b..17d7f0a 100644
--- a/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
+++ b/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
@@ -34,6 +34,7 @@ import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.core.internal.winrm.WinRmToolResponse;
import org.apache.brooklyn.util.text.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,8 +43,6 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
-
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;