You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2010/05/15 17:06:21 UTC
svn commit: r944656 - in /camel/trunk/components/camel-exec/src:
main/java/org/apache/camel/component/exec/
main/java/org/apache/camel/component/exec/impl/
test/java/org/apache/camel/component/exec/
Author: davsclaus
Date: Sat May 15 15:06:21 2010
New Revision: 944656
URL: http://svn.apache.org/viewvc?rev=944656&view=rev
Log:
CAMEL-2706: Added option useStderrOnEmptyStdout
Modified:
camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecBinding.java
camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecCommand.java
camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecCommandExecutor.java
camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java
camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecResultConverter.java
camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecBinding.java
camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
camel/trunk/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessTest.java
Modified: camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecBinding.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecBinding.java?rev=944656&r1=944655&r2=944656&view=diff
==============================================================================
--- camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecBinding.java (original)
+++ camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecBinding.java Sat May 15 15:06:21 2010
@@ -26,6 +26,7 @@ import org.apache.camel.Exchange;
* is an {@link ExecCommand} and the output is an {@link ExecResult}.
*/
public interface ExecBinding {
+
/**
* The header value overrides the executable of the command, configured in
* the exec endpoint URI. As executable is considered the remaining of the
@@ -35,6 +36,7 @@ public interface ExecBinding {
* <code>C:/Program Files/jdk/java.exe<code> is the executable.
*/
String EXEC_COMMAND_EXECUTABLE = "CamelExecCommandExecutable";
+
/**
* The header value overrides the existing command arguments in the
* {@link ExecEndpoint} URI. The arguments may be a
@@ -60,6 +62,7 @@ public interface ExecBinding {
* used.
*/
String EXEC_COMMAND_WORKING_DIR = "CamelExecCommandWorkingDir";
+
/**
* Specifies the amount of time, in milliseconds, after which the process of
* the executable should be terminated. The default value is
@@ -82,6 +85,12 @@ public interface ExecBinding {
String EXEC_EXIT_VALUE = "CamelExecExitValue";
/**
+ * The value of this header is a boolean which indicates whether or not
+ * to fallback and use stderr when stdout is empty.
+ */
+ String EXEC_USE_STDERR_ON_EMPTY_STDOUT = "CamelExecUseStderrOnEmptyStdout";
+
+ /**
* Creates a {@link ExecCommand} from the headers in the
* <code>exchange</code> and the settings of the <code>endpoint</code>.
*
Modified: camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecCommand.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecCommand.java?rev=944656&r1=944655&r2=944656&view=diff
==============================================================================
--- camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecCommand.java (original)
+++ camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecCommand.java Sat May 15 15:06:21 2010
@@ -35,33 +35,37 @@ public class ExecCommand implements Seri
/**
* @see ExecBinding#EXEC_COMMAND_EXECUTABLE
*/
- private String executable;
+ private final String executable;
/**
* @see ExecBinding#EXEC_COMMAND_ARGS
*/
- private List<String> args;
+ private final List<String> args;
/**
* @see ExecBinding#EXEC_COMMAND_WORKING_DIR
*/
- private String workingDir;
+ private final String workingDir;
/**
* @see ExecBinding#EXEC_COMMAND_TIMEOUT
*/
- private long timeout;
+ private final long timeout;
/**
* @see ExecBinding#EXEC_COMMAND_OUT_FILE
*/
- private File outFile;
+ private final File outFile;
+
/**
* The input of the executable
*/
- private InputStream input;
+ private final InputStream input;
+
+ private final boolean useStderrOnEmptyStdout;
- public ExecCommand(String executable, List<String> args, String workingDir, Long timeout, InputStream input, File outFile) {
+ public ExecCommand(String executable, List<String> args, String workingDir, Long timeout,
+ InputStream input, File outFile, boolean useStderrOnEmptyStdout) {
notNull(executable, "command executable");
this.executable = executable;
this.args = unmodifiableOrEmptyList(args);
@@ -69,6 +73,7 @@ public class ExecCommand implements Seri
this.timeout = timeout;
this.input = input;
this.outFile = outFile;
+ this.useStderrOnEmptyStdout = useStderrOnEmptyStdout;
}
public List<String> getArgs() {
@@ -95,11 +100,16 @@ public class ExecCommand implements Seri
return workingDir;
}
+ public boolean isUseStderrOnEmptyStdout() {
+ return useStderrOnEmptyStdout;
+ }
+
@Override
public String toString() {
String dirToPrint = workingDir == null ? "null" : workingDir;
String outFileToPrint = outFile == null ? "null" : outFile.getPath();
- return "ExecCommand [args=" + args + ", executable=" + executable + ", timeout=" + timeout + ", outFile=" + outFileToPrint + ", workingDir=" + dirToPrint + "]";
+ return "ExecCommand [args=" + args + ", executable=" + executable + ", timeout=" + timeout + ", outFile="
+ + outFileToPrint + ", workingDir=" + dirToPrint + ", useStderrOnEmptyStdout=" + useStderrOnEmptyStdout + "]";
}
private <T> List<T> unmodifiableOrEmptyList(List<T> list) {
Modified: camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecCommandExecutor.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecCommandExecutor.java?rev=944656&r1=944655&r2=944656&view=diff
==============================================================================
--- camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecCommandExecutor.java (original)
+++ camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecCommandExecutor.java Sat May 15 15:06:21 2010
@@ -18,8 +18,6 @@ package org.apache.camel.component.exec;
import java.io.IOException;
-import org.apache.commons.exec.ExecuteException;
-
/**
* Executes {@link ExecCommand} instances.
*/
@@ -29,9 +27,9 @@ public interface ExecCommandExecutor {
* Executes the <code>command</code> and returns a not-<code>null</code>
* {@link ExecResult} instance.
*
- * @param execCommand The command object, that describes the executable
- * application
- * @throws ExecuteException if the execution failed
+ * @param execCommand The command object, that describes the executable application
+ * @return the result
+ * @throws ExecException if the execution failed
* @throws IOException if there is an invalid path in the working directory,
* or if the absolute path of the command executable is invalid,
* or if the executable does not exist
Modified: camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java?rev=944656&r1=944655&r2=944656&view=diff
==============================================================================
--- camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java (original)
+++ camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecEndpoint.java Sat May 15 15:06:21 2010
@@ -17,7 +17,6 @@
package org.apache.camel.component.exec;
import org.apache.camel.Consumer;
-import org.apache.camel.Endpoint;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.component.exec.impl.DefaultExecBinding;
@@ -29,8 +28,7 @@ import org.apache.camel.util.ObjectHelpe
/**
* The endpoint utilizes an {@link ExecCommandExecutor} to execute a system
* command when it receives message exchanges.
- *
- * @see Endpoint
+ *
* @see ExecBinding
* @see ExecCommandExecutor
* @see ExecCommand
@@ -57,6 +55,8 @@ public class ExecEndpoint extends Defaul
private ExecBinding binding;
+ private boolean useStderrOnEmptyStdout;
+
public ExecEndpoint(String uri, ExecComponent component) {
super(uri, component);
this.timeout = NO_TIMEOUT;
@@ -187,7 +187,7 @@ public class ExecEndpoint extends Defaul
/**
* @return The command executor used to execute commands. Defaults to
- * {@link DefaultExecCommandExecutror}
+ * {@link org.apache.camel.component.exec.impl.DefaultExecCommandExecutor}
*/
public ExecCommandExecutor getCommandExecutor() {
return commandExecutor;
@@ -211,4 +211,12 @@ public class ExecEndpoint extends Defaul
ObjectHelper.notNull(binding, "binding");
this.binding = binding;
}
+
+ public boolean isUseStderrOnEmptyStdout() {
+ return useStderrOnEmptyStdout;
+ }
+
+ public void setUseStderrOnEmptyStdout(boolean useStderrOnEmptyStdout) {
+ this.useStderrOnEmptyStdout = useStderrOnEmptyStdout;
+ }
}
Modified: camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecResultConverter.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecResultConverter.java?rev=944656&r1=944655&r2=944656&view=diff
==============================================================================
--- camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecResultConverter.java (original)
+++ camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/ExecResultConverter.java Sat May 15 15:06:21 2010
@@ -82,7 +82,14 @@ public final class ExecResultConverter {
* the file can not be found
*/
public static <T> T convertTo(Class<T> type, Exchange exchange, ExecResult result) throws FileNotFoundException {
- return exchange.getContext().getTypeConverter().convertTo(type, exchange, toInputStream(result));
+ InputStream is = toInputStream(result);
+ if (is != null) {
+ return exchange.getContext().getTypeConverter().convertTo(type, exchange, is);
+ } else {
+ // use Void to indicate we cannot convert it
+ // (prevents Camel from using a fallback converter which may convert a String from the instance name)
+ return (T) Void.TYPE;
+ }
}
/**
@@ -114,11 +121,11 @@ public final class ExecResultConverter {
result = new FileInputStream(execResult.getCommand().getOutFile());
} else {
// if the stdout is null, return the stderr.
- if (execResult.getStdout() == null) {
+ if (execResult.getStdout() == null && execResult.getCommand().isUseStderrOnEmptyStdout()) {
LOG.warn("ExecResult has no stdout, will fallback to use stderr.");
result = execResult.getStderr();
} else {
- result = execResult.getStdout();
+ result = execResult.getStdout() != null ? execResult.getStdout() : null;
}
}
// reset the stream if it was already read.
Modified: camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecBinding.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecBinding.java?rev=944656&r1=944655&r2=944656&view=diff
==============================================================================
--- camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecBinding.java (original)
+++ camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecBinding.java Sat May 15 15:06:21 2010
@@ -47,6 +47,7 @@ public class DefaultExecBinding implemen
String dir = getAndRemoveHeader(exchange.getIn(), EXEC_COMMAND_WORKING_DIR, endpoint.getWorkingDir(), String.class);
long timeout = getAndRemoveHeader(exchange.getIn(), EXEC_COMMAND_TIMEOUT, endpoint.getTimeout(), Long.class);
String outFilePath = getAndRemoveHeader(exchange.getIn(), EXEC_COMMAND_OUT_FILE, endpoint.getOutFile(), String.class);
+ boolean useStderrOnEmptyStdout = getAndRemoveHeader(exchange.getIn(), EXEC_USE_STDERR_ON_EMPTY_STDOUT, endpoint.isUseStderrOnEmptyStdout(), Boolean.class);
InputStream input = exchange.getIn().getBody(InputStream.class);
if (argsList == null) {
@@ -55,7 +56,7 @@ public class DefaultExecBinding implemen
}
File outFile = outFilePath == null ? null : new File(outFilePath);
- return new ExecCommand(cmd, argsList, dir, timeout, input, outFile);
+ return new ExecCommand(cmd, argsList, dir, timeout, input, outFile, useStderrOnEmptyStdout);
}
public void writeOutput(Exchange exchange, ExecResult result) {
Modified: camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java?rev=944656&r1=944655&r2=944656&view=diff
==============================================================================
--- camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java (original)
+++ camel/trunk/components/camel-exec/src/main/java/org/apache/camel/component/exec/impl/DefaultExecCommandExecutor.java Sat May 15 15:06:21 2010
@@ -73,11 +73,11 @@ public class DefaultExecCommandExecutor
return result;
} catch (ExecuteException ee) {
- LOG.error("ExecuteExeption while executing " + command.toString());
+ LOG.error("ExecException while executing command: " + command.toString() + " - " + ee.getMessage());
throw new ExecException("Failed to execute command " + command, ee);
} catch (IOException ioe) {
// invalid working dir
- LOG.error("IOException while executing " + command.toString());
+ LOG.error("IOException while executing command: " + command.toString() + " - " + ioe.getMessage());
throw new ExecException("Unable to execute command " + command, ioe);
} finally {
// the inputStream must be closed after the execution
Modified: camel/trunk/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessTest.java?rev=944656&r1=944655&r2=944656&view=diff
==============================================================================
--- camel/trunk/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessTest.java (original)
+++ camel/trunk/components/camel-exec/src/test/java/org/apache/camel/component/exec/ExecJavaProcessTest.java Sat May 15 15:06:21 2010
@@ -38,6 +38,7 @@ import static org.apache.camel.component
import static org.apache.camel.component.exec.ExecBinding.EXEC_COMMAND_WORKING_DIR;
import static org.apache.camel.component.exec.ExecBinding.EXEC_EXIT_VALUE;
import static org.apache.camel.component.exec.ExecBinding.EXEC_STDERR;
+import static org.apache.camel.component.exec.ExecBinding.EXEC_USE_STDERR_ON_EMPTY_STDOUT;
import static org.apache.camel.component.exec.ExecEndpoint.NO_TIMEOUT;
import static org.apache.camel.component.exec.ExecTestUtils.buildJavaExecutablePath;
import static org.apache.camel.component.exec.ExecutableJavaProgram.EXIT_WITH_VALUE_0;
@@ -133,7 +134,7 @@ public class ExecJavaProcessTest extends
String commandArgument = PRINT_IN_STDERR;
output.setExpectedMessageCount(1);
- Exchange e = sendExchange(commandArgument, NO_TIMEOUT);
+ Exchange e = sendExchange(commandArgument, NO_TIMEOUT, null, true);
ExecResult body = e.getIn().getBody(ExecResult.class);
output.assertIsSatisfied();
@@ -145,6 +146,23 @@ public class ExecJavaProcessTest extends
}
@Test
+ public void testStdoutIsNull() throws Exception {
+ // this will be printed
+ String commandArgument = PRINT_IN_STDERR;
+ output.setExpectedMessageCount(1);
+
+ Exchange e = sendExchange(commandArgument, NO_TIMEOUT, null, false);
+ ExecResult body = e.getIn().getBody(ExecResult.class);
+
+ output.assertIsSatisfied();
+ assertNull("the test executable must not print anything in stdout", body.getStdout());
+ assertNotNull("the test executable must print in stderr", body.getStderr());
+ // the converter must fall back to the stderr, because stdout is null
+ String out = e.getIn().getBody(String.class);
+ assertNull("Should be null", out);
+ }
+
+ @Test
public void testConvertResultToInputStream() throws Exception {
String commandArgument = PRINT_IN_STDOUT;
output.setExpectedMessageCount(1);
@@ -240,17 +258,17 @@ public class ExecJavaProcessTest extends
String whiteSpaceSeparatedLines = builder.toString();
String expected = builder.toString();
- Exchange e = sendExchange(READ_INPUT_LINES_AND_PRINT_THEM, 20000, whiteSpaceSeparatedLines);
+ Exchange e = sendExchange(READ_INPUT_LINES_AND_PRINT_THEM, 20000, whiteSpaceSeparatedLines, false);
ExecResult inBody = e.getIn().getBody(ExecResult.class);
assertEquals(expected, IOUtils.toString(inBody.getStdout()));
}
protected Exchange sendExchange(final Object commandArgument, final long timeout) {
- return sendExchange(commandArgument, timeout, "testBody");
+ return sendExchange(commandArgument, timeout, "testBody", false);
}
- protected Exchange sendExchange(final Object commandArgument, final long timeout, final String body) {
+ protected Exchange sendExchange(final Object commandArgument, final long timeout, final String body, final boolean useStderrOnEmptyStdout) {
final List<String> args = buildArgs(commandArgument);
final String javaAbsolutePath = buildJavaExecutablePath();
@@ -260,6 +278,9 @@ public class ExecJavaProcessTest extends
exchange.getIn().setHeader(EXEC_COMMAND_EXECUTABLE, javaAbsolutePath);
exchange.getIn().setHeader(EXEC_COMMAND_TIMEOUT, timeout);
exchange.getIn().setHeader(EXEC_COMMAND_ARGS, args);
+ if (useStderrOnEmptyStdout) {
+ exchange.getIn().setHeader(EXEC_USE_STDERR_ON_EMPTY_STDOUT, true);
+ }
}
});
}