/**
* Create and execute subprocess
*/
public Subprocess executeSubprocess(String command, String commandParameters, HashMap environment) throws Exception {
Subprocess subprocess = null;
boolean terminated = true;
try {
subprocess = spooler_task.create_subprocess();
// execute subprocesses as a process group to have all child processes being killed if the timeout is exceeded
subprocess.set_own_process_group(true);
subprocess.set_ignore_error(this.isIgnoreError());
subprocess.set_ignore_signal(this.isIgnoreSignal());
subprocess.set_priority_class(this.getPriorityClass());
if (this.getTimeout() > 0) subprocess.set_timeout(this.getTimeout());
// execute the command and parameters in background
String commandLine = command + " " + commandParameters;
// hand all order parameters that start with "env_" or "environment_" as environment variables to the subprocess
String[] parameterNames = this.getParameters().names().split(";");
for(int i=0; i<parameterNames.length; i++) {
/*if (parameterNames[i].startsWith("env_")) {
subprocess.set_environment(parameterNames[i].substring(4).toUpperCase(), this.getParameters().value(parameterNames[i]));
} else if (parameterNames[i].startsWith("environment_")) {
subprocess.set_environment(parameterNames[i].substring(12).toUpperCase(), this.getParameters().value(parameterNames[i]));
}*/
commandLine = myReplaceAll(commandLine,"\\$\\{" + parameterNames[i] + "\\}", this.getParameters().value(parameterNames[i]).replaceAll("[\\\\]", "\\\\\\\\"));
}
// set specific environment variables
subprocess.set_environment("SCHEDULER_TRIGGER_FILE", this.getTriggerFilename());
if (environment != null) {
Iterator envIterator = environment.keySet().iterator();
while(envIterator.hasNext()) {
Object envName = envIterator.next();
Object envValue = environment.get(envName.toString());
commandLine = myReplaceAll(commandLine,"\\$\\{" + envName.toString() + "\\}", envValue.toString().replaceAll("[\\\\]", "\\\\\\\\"));
}
}
// operating system environment variables
if (this.envvars != null) {
Iterator envIterator = this.envvars.keySet().iterator();
while(envIterator.hasNext()) {
Object envName = envIterator.next();
Object envValue = this.envvars.get(envName.toString());
commandLine = myReplaceAll(commandLine,"\\$\\{" + envName.toString() + "\\}", envValue.toString().replaceAll("[\\\\]", "\\\\\\\\"));
}
}
// adding environment variables from parameters with attribute env=yes
if (this.additional_envvars != null) {
Iterator envIterator = this.additional_envvars.keySet().iterator();
while(envIterator.hasNext()) {
String envName = (String) envIterator.next();
String envValue = (String) this.additional_envvars.get(envName);
if (envName == null) continue;
int varBegin = envValue.indexOf("${");
while (varBegin > -1) {
int varEnd = envValue.indexOf("}", varBegin+2);
if (varEnd > 0) {
String varName = envValue.substring(varBegin+2, varEnd);
boolean hasBasename = varName.startsWith("basename:");
if (hasBasename) varName = varName.substring(9);
if (this.getParameters().value(varName) != null) {
if (hasBasename) {
envValue = myReplaceAll(envValue, "\\$\\{basename:" + varName + "\\}", new File(this.getParameters().value(varName)).getName().replaceAll("[\\\\]", "\\\\\\\\"));
} else {
envValue = myReplaceAll(envValue, "\\$\\{" + varName + "\\}", this.getParameters().value(varName).replaceAll("[\\\\]", "\\\\\\\\"));
}
this.getLogger().debug9("environment variable substituted: " + varName);
} else {
this.getLogger().info("unsubstitutable variable found for environment: " + varName);
}
}
varBegin = envValue.indexOf("${", varEnd+1);
}
this.getLogger().debug1(".. setting environment variable: " + envName + "=" + envValue);
subprocess.set_environment(envName, envValue);
}
}
// execute the command
this.getLogger().info("executing command: " + commandLine);
subprocess.start(commandLine);
// wait for the specified timeout for termination of the subprocess
if (this.getTimeout() > 0) {
terminated = subprocess.wait_for_termination(this.getTimeout());
} else {
subprocess.wait_for_termination();
}
if (!terminated){
this.getLogger().warn("timeout reached for subprocess, process will be terminated");
subprocess.kill();
subprocess.wait_for_termination();
} else {
}
boolean stdErrEmpty = true;
String stdErrString = "";
String stdOutString = "";
this.getLogger().info("output reported to stdout for " + commandLine + ":");
while(this.stdoutStream != null && this.stdoutStream.ready()) {
String stdOutLine = stdoutStream.readLine();
this.getLogger().info(stdOutLine);
stdOutString += stdOutLine + "\n";
}
this.getLogger().info("output reported to stderr for " + commandLine + ":");
while(this.stderrStream != null && this.stderrStream.ready()) {
String stdErrLine = stderrStream.readLine();
this.getLogger().info(stdErrLine);
if (stdErrLine.trim().length()>0) stdErrEmpty = false;
stdErrString += stdErrLine + "\n";
}
if (spooler_job.order_queue() != null){
spooler_task.order().params().set_var("scheduler_order_stderr_output", stdErrString);
spooler_task.order().params().set_var("scheduler_order_stdout_output", stdOutString);
spooler_task.order().params().set_var("scheduler_order_exit_code", String.valueOf(subprocess.exit_code()));
spooler_task.order().params().set_var("scheduler_order_terminated", (terminated ? "true" : "false"));
}
if((subprocess.exit_code() != 0)){
if (this.isIgnoreError()) this.getLogger().info("command terminated with exit code: " + subprocess.exit_code());
else throw new Exception("command terminated with exit code: " + subprocess.exit_code());
}
if((subprocess.termination_signal() != 0)){
if (this.isIgnoreSignal()) this.getLogger().info("command terminated with signal: " + subprocess.termination_signal());
else throw new Exception("command terminated with signal: " + subprocess.termination_signal());
}
if(!this.isIgnoreStderr() && !stdErrEmpty) {
throw new Exception("command terminated with output to stderr:\n" + stdErrString);
}