2 * Copyright 2018 Huawei Technologies Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.cli.fw.utils;
19 import java.io.BufferedReader;
20 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.io.OutputStream;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.List;
29 import java.util.concurrent.TimeUnit;
31 import org.apache.commons.io.IOUtils;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
35 public class ProcessRunner {
36 private static Logger log = LoggerFactory.getLogger(ProcessRunner.class);
37 public static final String WIN_SHELL = "cmd.exe /c ";
38 public static final String UNIX_SHELL = "";
39 private String []cmd = null;
40 private String shell = System.getProperty("os.name").toLowerCase().startsWith("windows") ? WIN_SHELL : UNIX_SHELL;
41 private String cwd = System.getProperty("user.home");
42 private String []env = null;
43 private int exitCode = -1;
44 private String output = "";
45 private String error = "";
46 private long timeout = 0;
47 private OutputStream stdout;
48 private OutputStream stderr;
49 public ProcessRunner(String []cmd, String []env, String cwd) {
52 if (cwd != null && !cwd.isEmpty()) {
59 public void setTimeout(long timeout) {
60 this.timeout = timeout;
63 public long getTimeout() {
67 public void overrideToUnix() {
68 this.shell = UNIX_SHELL;
71 public ProcessRunner(String []cmd, String cwd) {
75 public ProcessRunner(String []cmd) {
76 this(cmd, null, null);
79 public ProcessRunner(String cmd, String []env, String cwd) {
80 this(new String []{cmd}, env, cwd);
83 public ProcessRunner(String cmd, String cwd) {
84 this(new String []{cmd}, null, cwd);
87 public ProcessRunner(String cmd) {
88 this(new String []{cmd}, null, null);
91 @SuppressWarnings("unchecked")
92 public void run() throws InterruptedException, IOException {
95 File workingDirectory = null;
97 workingDirectory = new File(cwd);
99 if (this.cmd.length == 1) {
100 p = Runtime.getRuntime().exec(this.shell + this.cmd[0], this.env, workingDirectory); //NOSONAR
102 List list = new ArrayList(Arrays.asList(this.shell.split(" ")));
103 list.addAll(Arrays.asList(this.cmd));
104 String []cmds = Arrays.copyOf(list.toArray(), list.size(), String[].class);
105 p = Runtime.getRuntime().exec(cmds, this.env, workingDirectory); //NOSONAR
108 boolean readOutput = false;
109 if (this.getStdout() == null) {
110 this.setStdout(new ByteArrayOutputStream());
114 boolean readError = false;
115 if (this.getStderr() == null) {
116 this.setStderr(new ByteArrayOutputStream());
120 final OutputStream stdout = this.getStdout();
121 final OutputStream stderr = this.getStderr();
123 final InputStream stdoutP = p.getInputStream();
124 final InputStream stderrP = p.getErrorStream();
126 Thread outThread = new Thread(new Runnable() {
129 IOUtils.copy(stdoutP, stdout);
130 } catch (IOException e) {
135 Thread errThread = new Thread(new Runnable() {
138 IOUtils.copy(stderrP, stderr);
139 } catch (IOException e) {
147 boolean completed = p.waitFor(this.getTimeout(), TimeUnit.MILLISECONDS);
152 this.exitCode = p.exitValue();
156 this.output = new String(((ByteArrayOutputStream)this.getStdout()).toByteArray(), "UTF-8");
159 this.error = new String(((ByteArrayOutputStream)this.getStderr()).toByteArray(), "UTF-8");;
163 log.debug("CMD: " + Arrays.asList(this.cmd).toString() +
164 "\nWORKING_DIR: " + this.cwd +
165 "\nENV: " + ((this.env == null) ? this.env : Arrays.asList(this.env).toString()) +
166 "\nOUTPUT: " + this.output +
167 "\nERROR: " + this.error +
168 "\nEXIT_CODE: " + this.exitCode);
171 throw new RuntimeException("TIMEOUT:: cmd:" + Arrays.asList(this.cmd).toString());
175 public String streamToString(InputStream stream) throws IOException {
176 StringBuilder sb = new StringBuilder();
177 try (BufferedReader br = new BufferedReader(new InputStreamReader(stream))) {
179 while ((line = br.readLine()) != null) {
180 sb.append(line + System.getProperty("line.separator"));
183 return sb.toString();
186 public int getExitCode() {
187 return this.exitCode;
190 public String getOutput() {
194 public String getError() {
198 public OutputStream getStdout() {
202 public void setStdout(OutputStream stdout) {
203 this.stdout = stdout;
206 public OutputStream getStderr() {
210 public void setStderr(OutputStream stderr) {
211 this.stderr = stderr;
214 public String toString() {
215 StringBuilder sb = new StringBuilder();
217 sb.append("COMMAND: " + this.shell + " " + Arrays.asList(this.cmd));
218 sb.append("\nCWD: " + new File(this.cwd).getAbsolutePath());
219 sb.append("\nTIMEOUT: " + this.timeout);
220 sb.append("\nEXIT-CODE: " + this.getExitCode());
221 sb.append("\nENVIRONMENTS: " + Arrays.asList(this.env));
223 return sb.toString();