1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.openr66.context.task;
21
22 import org.apache.commons.exec.CommandLine;
23 import org.apache.commons.exec.DefaultExecutor;
24 import org.apache.commons.exec.ExecuteWatchdog;
25 import org.apache.commons.exec.PumpStreamHandler;
26 import org.waarp.commandexec.utils.LocalExecResult;
27 import org.waarp.common.command.exception.CommandAbstractException;
28 import org.waarp.common.logging.WaarpLogger;
29 import org.waarp.common.logging.WaarpLoggerFactory;
30 import org.waarp.openr66.context.ErrorCode;
31 import org.waarp.openr66.context.R66Result;
32 import org.waarp.openr66.context.R66Session;
33 import org.waarp.openr66.context.task.exception.OpenR66RunnerErrorException;
34 import org.waarp.openr66.context.task.localexec.LocalExecClient;
35 import org.waarp.openr66.protocol.configuration.Configuration;
36
37 import java.io.File;
38 import java.io.PipedInputStream;
39 import java.io.PipedOutputStream;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class ExecOutputTask extends AbstractExecTask {
57
58
59
60 private static final WaarpLogger logger =
61 WaarpLoggerFactory.getLogger(ExecOutputTask.class);
62
63
64
65
66 public static final String DELIMITER = "NEWFINALNAME:";
67
68
69
70
71
72
73
74 public ExecOutputTask(final String argRule, final int delay,
75 final String argTransfer, final R66Session session) {
76 super(TaskType.EXECOUTPUT, delay, argRule, argTransfer, session);
77 }
78
79 @Override
80 public void run() {
81
82
83
84
85
86
87 logger.info("ExecOutput with {}:{} and {}", argRule, argTransfer, session);
88 final String finalname = applyTransferSubstitutions(argRule);
89
90
91 waitForValidation = true;
92 if (Configuration.configuration.isUseLocalExec() && useLocalExec) {
93 final LocalExecClient localExecClient = new LocalExecClient();
94 if (localExecClient.connect()) {
95 localExecClient.runOneCommand(finalname, delay, waitForValidation,
96 futureCompletion);
97 final LocalExecResult result = localExecClient.getLocalExecResult();
98 finalizeExec(result.getStatus(), result.getResult(), finalname);
99 localExecClient.disconnect();
100 return;
101 }
102 }
103
104 final PrepareCommandExec prepareCommandExec =
105 new PrepareCommandExec(this, finalname, false,
106 waitForValidation).invoke();
107 if (prepareCommandExec.isError()) {
108 return;
109 }
110 final CommandLine commandLine = prepareCommandExec.getCommandLine();
111 final DefaultExecutor defaultExecutor =
112 prepareCommandExec.getDefaultExecutor();
113 final PipedInputStream inputStream = prepareCommandExec.getInputStream();
114 final PipedOutputStream outputStream = prepareCommandExec.getOutputStream();
115 final PumpStreamHandler pumpStreamHandler =
116 prepareCommandExec.getPumpStreamHandler();
117 final ExecuteWatchdog watchdog = prepareCommandExec.getWatchdog();
118
119 final AllLineReader allLineReader = new AllLineReader(inputStream);
120 allLineReader.setName(
121 "LastLineReader" + session.getRunner().getSpecialId());
122 allLineReader.setDaemon(true);
123 Configuration.configuration.getExecutorService().execute(allLineReader);
124 final ExecuteCommand executeCommand =
125 new ExecuteCommand(this, commandLine, defaultExecutor, inputStream,
126 outputStream, pumpStreamHandler,
127 allLineReader).invoke();
128 if (executeCommand.isError()) {
129 return;
130 }
131 int status = executeCommand.getStatus();
132 final String newname;
133 if (defaultExecutor.isFailure(status) && watchdog != null &&
134 watchdog.killedProcess()) {
135
136 status = -1;
137 newname = "TimeOut";
138 } else {
139 newname = allLineReader.getLastLine().toString();
140 }
141 finalizeExec(status, newname, commandLine.toString());
142 }
143
144 private void finalizeExec(final int status, final String newName,
145 final String commandLine) {
146 String newname = newName;
147 if (status == 0) {
148 final R66Result result =
149 new R66Result(session, true, ErrorCode.CompleteOk,
150 session.getRunner());
151 result.setOther(newName);
152 futureCompletion.setResult(result);
153 futureCompletion.setSuccess();
154 logger.info("Exec OK with {} returns {}", commandLine, newname);
155 } else if (status == 1) {
156 final R66Result result =
157 new R66Result(session, true, ErrorCode.Warning, session.getRunner());
158 result.setOther(newName);
159 futureCompletion.setResult(result);
160 logger.warn(
161 "Exec in warning with " + commandLine + " returns " + newname);
162 session.getRunner().setErrorExecutionStatus(ErrorCode.Warning);
163 futureCompletion.setSuccess();
164 } else {
165 final int pos = newname.lastIndexOf(DELIMITER);
166 if (pos >= 0) {
167 final String newfilename = newname.substring(pos + DELIMITER.length());
168 newname = newname.substring(0, pos);
169 if (newfilename.indexOf(' ') > 0) {
170 logger.warn(
171 "Exec returns a multiple string in final line: " + newfilename);
172
173
174 }
175
176 final File file = new File(newfilename);
177 if (!file.exists()) {
178 logger.warn(
179 "New file does not exist at the end of the exec: " + newfilename);
180 }
181
182 try {
183 session.getFile().replaceFilename(newfilename, true);
184 } catch (final CommandAbstractException e) {
185 logger.warn("Exec in warning with " + commandLine + " : {}",
186 e.getMessage());
187 }
188 session.getRunner().setFileMoved(newfilename, true);
189 }
190 logger.error("Status: " + status + " Exec in error with " + commandLine +
191 " returns " + newname);
192 final OpenR66RunnerErrorException exc = new OpenR66RunnerErrorException(
193 "<STATUS>" + status + "</STATUS><ERROR>" + newname + "</ERROR>");
194 futureCompletion.setFailure(exc);
195 }
196 }
197
198 @Override
199 final void finalizeFromError(final Runnable threadReader, final int status,
200 final CommandLine commandLine,
201 final Exception e) {
202 final String result =
203 ((AllLineReader) threadReader).getLastLine().toString();
204 logger.error("Status: " + status + " Exec in error with " + commandLine +
205 " returns " + result);
206 final OpenR66RunnerErrorException exc = new OpenR66RunnerErrorException(
207 "<STATUS>" + status + "</STATUS><ERROR>" + result + "</ERROR>");
208 futureCompletion.setFailure(exc);
209 }
210 }