aboutsummaryrefslogtreecommitdiffstats
path: root/vespajlib/src/main/java/com/yahoo/system
diff options
context:
space:
mode:
authorgjoranv <gv@yahoo-inc.com>2017-03-02 00:15:38 +0100
committergjoranv <gv@yahoo-inc.com>2017-03-02 00:29:09 +0100
commitf238d6793d32e139b1c3f17857da6ea492ed2c70 (patch)
tree10b971bdecfa4265f90edcc44fc3b0a134a307ab /vespajlib/src/main/java/com/yahoo/system
parentd37abf742d3fa48ad564ab72689c91a1a1c81209 (diff)
Add a configurable process executor based on commons-exec.
Diffstat (limited to 'vespajlib/src/main/java/com/yahoo/system')
-rw-r--r--vespajlib/src/main/java/com/yahoo/system/execution/ProcessExecutor.java79
-rw-r--r--vespajlib/src/main/java/com/yahoo/system/execution/ProcessResult.java19
-rw-r--r--vespajlib/src/main/java/com/yahoo/system/execution/package-info.java5
3 files changed, 103 insertions, 0 deletions
diff --git a/vespajlib/src/main/java/com/yahoo/system/execution/ProcessExecutor.java b/vespajlib/src/main/java/com/yahoo/system/execution/ProcessExecutor.java
new file mode 100644
index 00000000000..564ee5ea3ac
--- /dev/null
+++ b/vespajlib/src/main/java/com/yahoo/system/execution/ProcessExecutor.java
@@ -0,0 +1,79 @@
+// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.system.execution;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteWatchdog;
+import org.apache.commons.exec.PumpStreamHandler;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author gjoranv
+ * @author bjorncs
+ */
+public class ProcessExecutor {
+
+ public static class Builder {
+ private final int timeoutSeconds;
+ private int[] successExitCodes;
+
+ public Builder(int timeoutSeconds) {
+ this.timeoutSeconds = timeoutSeconds;
+ }
+
+ public Builder setSuccessExitCodes(int... successExitCodes) {
+ this.successExitCodes = successExitCodes;
+ return this;
+ }
+
+ public ProcessExecutor build() {
+ return new ProcessExecutor(timeoutSeconds, successExitCodes);
+ }
+ }
+
+ private ProcessExecutor(int timeoutSeconds, int[] successExitCodes) {
+ this.timeoutSeconds = timeoutSeconds;
+ this.successExitCodes = successExitCodes;
+ }
+
+ public final int timeoutSeconds;
+ private final int[] successExitCodes;
+
+ public Optional<ProcessResult> execute(String command) throws IOException {
+ return execute(command, null);
+ }
+
+ public Optional<ProcessResult> execute(String command, String processInput) throws IOException {
+ ByteArrayOutputStream processErr = new ByteArrayOutputStream();
+ ByteArrayOutputStream processOut = new ByteArrayOutputStream();
+
+ DefaultExecutor executor = new DefaultExecutor();
+ executor.setStreamHandler(createStreamHandler(processOut, processErr, processInput));
+ ExecuteWatchdog watchDog = new ExecuteWatchdog(TimeUnit.SECONDS.toMillis(timeoutSeconds));
+ executor.setWatchdog(watchDog);
+ executor.setExitValues(successExitCodes);
+
+ int exitCode = executor.execute(CommandLine.parse(command));
+ return (watchDog.killedProcess()) ?
+ Optional.empty() : Optional.of(new ProcessResult(exitCode, processOut.toString(), processErr.toString()));
+ }
+
+ private static PumpStreamHandler createStreamHandler(ByteArrayOutputStream processOut,
+ ByteArrayOutputStream processErr,
+ String input) {
+ if (input != null) {
+ InputStream processInput = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8));
+ return new PumpStreamHandler(processOut, processErr, processInput);
+ } else {
+ return new PumpStreamHandler(processOut, processErr);
+ }
+ }
+
+}
diff --git a/vespajlib/src/main/java/com/yahoo/system/execution/ProcessResult.java b/vespajlib/src/main/java/com/yahoo/system/execution/ProcessResult.java
new file mode 100644
index 00000000000..2f277f83a8c
--- /dev/null
+++ b/vespajlib/src/main/java/com/yahoo/system/execution/ProcessResult.java
@@ -0,0 +1,19 @@
+// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.system.execution;
+
+/**
+ * @author bjorncs
+ * @author gjoranv
+ */
+public class ProcessResult {
+ public final String stdOut;
+ public final String stdErr;
+ public final int exitCode;
+
+ public ProcessResult(int exitCode, String stdOut, String stdErr) {
+ this.exitCode = exitCode;
+ this.stdOut = stdOut;
+ this.stdErr = stdErr;
+ }
+
+}
diff --git a/vespajlib/src/main/java/com/yahoo/system/execution/package-info.java b/vespajlib/src/main/java/com/yahoo/system/execution/package-info.java
new file mode 100644
index 00000000000..1f88163d23d
--- /dev/null
+++ b/vespajlib/src/main/java/com/yahoo/system/execution/package-info.java
@@ -0,0 +1,5 @@
+// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage
+package com.yahoo.system.execution;
+
+import com.yahoo.osgi.annotation.ExportPackage;