/** | |
* Licensed to the Apache Software Foundation (ASF) under one or more | |
* contributor license agreements. See the NOTICE file distributed with | |
* this work for additional information regarding copyright ownership. | |
* The ASF licenses this file to You under the Apache License, Version 2.0 | |
* (the "License"); you may not use this file except in compliance with | |
* the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package org.apache.camel.component.exec; | |
import java.io.File; | |
import org.apache.camel.Exchange; | |
import org.apache.camel.Processor; | |
import org.apache.camel.Produce; | |
import org.apache.camel.ProducerTemplate; | |
import org.apache.commons.exec.OS; | |
import org.junit.Ignore; | |
import org.junit.Test; | |
import org.springframework.test.annotation.DirtiesContext; | |
import org.springframework.test.context.ContextConfiguration; | |
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; | |
import static org.apache.camel.component.exec.ExecBinding.EXEC_COMMAND_ARGS; | |
import static org.apache.camel.component.exec.ExecBinding.EXEC_COMMAND_EXECUTABLE; | |
import static org.apache.camel.component.exec.ExecBinding.EXEC_COMMAND_TIMEOUT; | |
import static org.apache.camel.component.exec.ExecBinding.EXEC_STDERR; | |
import static org.apache.camel.component.exec.ExecEndpoint.NO_TIMEOUT; | |
import static org.apache.camel.component.exec.ExecTestUtils.getClasspathResourceFileOrNull; | |
import static org.apache.camel.component.exec.ExecutableJavaProgram.PRINT_IN_STDOUT; | |
import static org.junit.Assert.assertNotNull; | |
import static org.junit.Assert.assertNull; | |
import static org.junit.Assert.assertTrue; | |
/** | |
* Test executing a OS script. Use only manually, see the TODO | |
*/ | |
@ContextConfiguration | |
public class ExecScriptTest extends AbstractJUnit4SpringContextTests { | |
@Produce(uri = "direct:input") | |
private ProducerTemplate producerTemplate; | |
/** | |
* TODO <b>the test is ignored for now to prevent accidental build | |
* failures.</b> Java 1.5 does not offer a method to check if a file is | |
* executable there is only a canRead method, which is not enough to | |
* guarantee that the script can be executed. <br> | |
* | |
* @throws Exception | |
*/ | |
@Test | |
@DirtiesContext | |
@Ignore | |
public void testExecuteScript() throws Exception { | |
File scriptFile = getExecScriptFileOrNull("exec-test-script"); | |
if (scriptFile != null) { | |
String classpathArg = getClasspathArg(); | |
Exchange exchange = executeScript(scriptFile, NO_TIMEOUT, classpathArg, PRINT_IN_STDOUT); | |
if (exchange != null) { | |
String out = (String)exchange.getIn().getBody(String.class); | |
String err = (String)exchange.getIn().getHeader(EXEC_STDERR); | |
assertNotNull(out); | |
assertTrue(out.contains(PRINT_IN_STDOUT)); | |
assertNull(err); | |
} | |
} else { | |
String os = System.getProperty("os.name"); | |
logger.warn("Executing batch scripts is not tested on " + os); | |
} | |
} | |
private Exchange executeScript(final File scriptFile, long timeout, String... args) { | |
StringBuilder argsBuilder = new StringBuilder(); | |
for (String arg : args) { | |
argsBuilder.append(arg + " "); | |
} | |
final String whiteSpaceSeparatedArgs = argsBuilder.toString().trim(); | |
return producerTemplate.send(new Processor() { | |
public void process(Exchange exchange) throws Exception { | |
exchange.getIn().setBody(PRINT_IN_STDOUT); | |
exchange.getIn().setHeader(EXEC_COMMAND_TIMEOUT, NO_TIMEOUT); | |
exchange.getIn().setHeader(EXEC_COMMAND_EXECUTABLE, scriptFile.getAbsolutePath()); | |
exchange.getIn().setHeader(EXEC_COMMAND_ARGS, whiteSpaceSeparatedArgs); | |
} | |
}); | |
} | |
private String getClasspathArg() { | |
String classpath = System.getProperty("java.class.path"); | |
if (OS.isFamilyWindows()) { | |
// On windows the ";" character is replaced by a space by the | |
// command interpreter. Thus the classpath is split with the | |
// ;-token. Therefore the classpath should be quoted with double | |
// quotes | |
classpath = "\"\"" + classpath + "\"\""; | |
} else { | |
// quote only once | |
classpath = "\"" + classpath + "\""; | |
} | |
return classpath; | |
} | |
private File getExecScriptFileOrNull(String scriptNameBase) { | |
String resource = null; | |
if (OS.isFamilyWindows()) { | |
resource = scriptNameBase + ".bat"; | |
} else if (OS.isFamilyUnix()) { | |
resource = scriptNameBase + ".sh"; | |
} | |
File resourceFile = getClasspathResourceFileOrNull(resource); | |
// TODO use canExecute here (available since java 1.6) | |
if (resourceFile != null && !resourceFile.canRead()) { | |
logger.warn("The resource " + resourceFile.getAbsolutePath() + " is not readable!"); | |
// it is not readable, do not try to execute it | |
return null; | |
} | |
return resourceFile; | |
} | |
} |