提交 93eadca7 编写于 作者: A Alexander Alexandrov 提交者: Stephan Ewen

[FLINK-1027] [cli] Added support for '--' and '-' prefixed tokens in CLI program arguments.

This closes #278
上级 0190dd24
...@@ -278,7 +278,7 @@ public class CliFrontend { ...@@ -278,7 +278,7 @@ public class CliFrontend {
// Parse command line options // Parse command line options
CommandLine line; CommandLine line;
try { try {
line = parser.parse(RUN_OPTIONS, args, false); line = parser.parse(RUN_OPTIONS, args, true);
evaluateGeneralOptions(line); evaluateGeneralOptions(line);
} }
catch (MissingOptionException e) { catch (MissingOptionException e) {
......
...@@ -32,7 +32,6 @@ import static org.mockito.Mockito.when; ...@@ -32,7 +32,6 @@ import static org.mockito.Mockito.when;
import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options; import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser; import org.apache.commons.cli.PosixParser;
import org.apache.flink.client.CliFrontend;
import org.apache.flink.client.program.Client; import org.apache.flink.client.program.Client;
import org.apache.flink.client.program.PackagedProgram; import org.apache.flink.client.program.PackagedProgram;
import org.apache.flink.client.program.ProgramInvocationException; import org.apache.flink.client.program.ProgramInvocationException;
...@@ -54,8 +53,8 @@ public class CliFrontendPackageProgramTest { ...@@ -54,8 +53,8 @@ public class CliFrontendPackageProgramTest {
@Test @Test
public void testNonExistingJarFile() { public void testNonExistingJarFile() {
try { try {
String[] arguments = {"-j", "/some/none/existing/path", "-a", "plenty", "of", "arguments"}; String[] arguments = {"-j", "/some/none/existing/path", "-a", "--verbose", "true", "arg1", "arg2"};
CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), arguments, false); CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), arguments, true);
CliFrontend frontend = new CliFrontend(); CliFrontend frontend = new CliFrontend();
Object result = frontend.buildProgram(line); Object result = frontend.buildProgram(line);
...@@ -71,8 +70,8 @@ public class CliFrontendPackageProgramTest { ...@@ -71,8 +70,8 @@ public class CliFrontendPackageProgramTest {
@Test @Test
public void testFileNotJarFile() { public void testFileNotJarFile() {
try { try {
String[] arguments = {"-j", getNonJarFilePath(), "-a", "plenty", "of", "arguments"}; String[] arguments = {"-j", getNonJarFilePath(), "-a", "--verbose", "true", "arg1", "arg2"};
CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), arguments, false); CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), arguments, true);
CliFrontend frontend = new CliFrontend(); CliFrontend frontend = new CliFrontend();
Object result = frontend.buildProgram(line); Object result = frontend.buildProgram(line);
...@@ -88,16 +87,16 @@ public class CliFrontendPackageProgramTest { ...@@ -88,16 +87,16 @@ public class CliFrontendPackageProgramTest {
@Test @Test
public void testVariantWithExplicitJarAndArgumentsOption() { public void testVariantWithExplicitJarAndArgumentsOption() {
try { try {
String[] parameters = {"-j", getTestJarPath(), "-a", "some", "program", "arguments"}; String[] arguments = {"-j", getTestJarPath(), "-a", "--verbose", "true", "arg1", "arg2"};
CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), parameters, false); CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), arguments, true);
CliFrontend frontend = new CliFrontend(); CliFrontend frontend = new CliFrontend();
Object result = frontend.buildProgram(line); Object result = frontend.buildProgram(line);
assertTrue(result instanceof PackagedProgram); assertTrue(result instanceof PackagedProgram);
PackagedProgram prog = (PackagedProgram) result; PackagedProgram prog = (PackagedProgram) result;
Assert.assertArrayEquals(new String[] {"some", "program", "arguments"}, prog.getArguments()); Assert.assertArrayEquals(new String[] {"--verbose", "true", "arg1", "arg2"}, prog.getArguments());
Assert.assertEquals(TEST_JAR_MAIN_CLASS, prog.getMainClassName()); Assert.assertEquals(TEST_JAR_MAIN_CLASS, prog.getMainClassName());
} }
catch (Exception e) { catch (Exception e) {
...@@ -110,16 +109,16 @@ public class CliFrontendPackageProgramTest { ...@@ -110,16 +109,16 @@ public class CliFrontendPackageProgramTest {
@Test @Test
public void testVariantWithExplicitJarAndNoArgumentsOption() { public void testVariantWithExplicitJarAndNoArgumentsOption() {
try { try {
String[] parameters = {"-j", getTestJarPath(), "some", "program", "arguments"}; String[] arguments = {"-j", getTestJarPath(), "--verbose", "true", "arg1", "arg2"};
CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), parameters, false); CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), arguments, true);
CliFrontend frontend = new CliFrontend(); CliFrontend frontend = new CliFrontend();
Object result = frontend.buildProgram(line); Object result = frontend.buildProgram(line);
assertTrue(result instanceof PackagedProgram); assertTrue(result instanceof PackagedProgram);
PackagedProgram prog = (PackagedProgram) result; PackagedProgram prog = (PackagedProgram) result;
Assert.assertArrayEquals(new String[] {"some", "program", "arguments"}, prog.getArguments()); Assert.assertArrayEquals(new String[] {"--verbose", "true", "arg1", "arg2"}, prog.getArguments());
Assert.assertEquals(TEST_JAR_MAIN_CLASS, prog.getMainClassName()); Assert.assertEquals(TEST_JAR_MAIN_CLASS, prog.getMainClassName());
} }
catch (Exception e) { catch (Exception e) {
...@@ -132,16 +131,16 @@ public class CliFrontendPackageProgramTest { ...@@ -132,16 +131,16 @@ public class CliFrontendPackageProgramTest {
@Test @Test
public void testValidVariantWithNoJarAndNoArgumentsOption() { public void testValidVariantWithNoJarAndNoArgumentsOption() {
try { try {
String[] parameters = {getTestJarPath(), "some", "program", "arguments"}; String[] arguments = {getTestJarPath(), "--verbose", "true", "arg1", "arg2"};
CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), parameters, false); CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), arguments, true);
CliFrontend frontend = new CliFrontend(); CliFrontend frontend = new CliFrontend();
Object result = frontend.buildProgram(line); Object result = frontend.buildProgram(line);
assertTrue(result instanceof PackagedProgram); assertTrue(result instanceof PackagedProgram);
PackagedProgram prog = (PackagedProgram) result; PackagedProgram prog = (PackagedProgram) result;
Assert.assertArrayEquals(new String[] {"some", "program", "arguments"}, prog.getArguments()); Assert.assertArrayEquals(new String[] {"--verbose", "true", "arg1", "arg2"}, prog.getArguments());
Assert.assertEquals(TEST_JAR_MAIN_CLASS, prog.getMainClassName()); Assert.assertEquals(TEST_JAR_MAIN_CLASS, prog.getMainClassName());
} }
catch (Exception e) { catch (Exception e) {
...@@ -154,8 +153,8 @@ public class CliFrontendPackageProgramTest { ...@@ -154,8 +153,8 @@ public class CliFrontendPackageProgramTest {
@Test @Test
public void testNoJarNoArgumentsAtAll() { public void testNoJarNoArgumentsAtAll() {
try { try {
String[] parameters = {}; String[] arguments = {};
CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), parameters, false); CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), arguments, true);
CliFrontend frontend = new CliFrontend(); CliFrontend frontend = new CliFrontend();
Object result = frontend.buildProgram(line); Object result = frontend.buildProgram(line);
...@@ -171,8 +170,8 @@ public class CliFrontendPackageProgramTest { ...@@ -171,8 +170,8 @@ public class CliFrontendPackageProgramTest {
@Test @Test
public void testNonExistingFileWithArguments() { public void testNonExistingFileWithArguments() {
try { try {
String[] parameters = {"/some/none/existing/path", "some", "program", "arguments"}; String[] arguments = {"/some/none/existing/path", "--verbose", "true", "arg1", "arg2"};
CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), parameters, false); CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), arguments, true);
CliFrontend frontend = new CliFrontend(); CliFrontend frontend = new CliFrontend();
Object result = frontend.buildProgram(line); Object result = frontend.buildProgram(line);
...@@ -188,8 +187,8 @@ public class CliFrontendPackageProgramTest { ...@@ -188,8 +187,8 @@ public class CliFrontendPackageProgramTest {
@Test @Test
public void testNonExistingFileWithoutArguments() { public void testNonExistingFileWithoutArguments() {
try { try {
String[] parameters = {"/some/none/existing/path"}; String[] arguments = {"/some/none/existing/path"};
CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), parameters, false); CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), arguments, true);
CliFrontend frontend = new CliFrontend(); CliFrontend frontend = new CliFrontend();
Object result = frontend.buildProgram(line); Object result = frontend.buildProgram(line);
...@@ -204,43 +203,48 @@ public class CliFrontendPackageProgramTest { ...@@ -204,43 +203,48 @@ public class CliFrontendPackageProgramTest {
/** /**
* Ensure that we will never have the following error. * Ensure that we will never have the following error.
* *
* The test works as follows: * <pre>
* - Use the CliFrontend to invoke a jar file that loads a class which is only available
* in the jarfile itself (via a custom classloader)
* - Change the Usercode classloader of the PackagedProgram to a special classloader for this test
* - the classloader will accept the special class (and return a String.class)
*
* org.apache.flink.client.program.ProgramInvocationException: The main method caused an error. * org.apache.flink.client.program.ProgramInvocationException: The main method caused an error.
at org.apache.flink.client.program.PackagedProgram.callMainMethod(PackagedProgram.java:398) * at org.apache.flink.client.program.PackagedProgram.callMainMethod(PackagedProgram.java:398)
at org.apache.flink.client.program.PackagedProgram.invokeInteractiveModeForExecution(PackagedProgram.java:301) * at org.apache.flink.client.program.PackagedProgram.invokeInteractiveModeForExecution(PackagedProgram.java:301)
at org.apache.flink.client.program.Client.getOptimizedPlan(Client.java:140) * at org.apache.flink.client.program.Client.getOptimizedPlan(Client.java:140)
at org.apache.flink.client.program.Client.getOptimizedPlanAsJson(Client.java:125) * at org.apache.flink.client.program.Client.getOptimizedPlanAsJson(Client.java:125)
at org.apache.flink.client.CliFrontend.info(CliFrontend.java:439) * at org.apache.flink.client.CliFrontend.info(CliFrontend.java:439)
at org.apache.flink.client.CliFrontend.parseParameters(CliFrontend.java:931) * at org.apache.flink.client.CliFrontend.parseParameters(CliFrontend.java:931)
at org.apache.flink.client.CliFrontend.main(CliFrontend.java:951) * at org.apache.flink.client.CliFrontend.main(CliFrontend.java:951)
Caused by: java.io.IOException: java.lang.RuntimeException: java.lang.ClassNotFoundException: org.apache.hadoop.hive.ql.io.RCFileInputFormat * Caused by: java.io.IOException: java.lang.RuntimeException: java.lang.ClassNotFoundException: org.apache.hadoop.hive.ql.io.RCFileInputFormat
at org.apache.hcatalog.mapreduce.HCatInputFormat.setInput(HCatInputFormat.java:102) * at org.apache.hcatalog.mapreduce.HCatInputFormat.setInput(HCatInputFormat.java:102)
at org.apache.hcatalog.mapreduce.HCatInputFormat.setInput(HCatInputFormat.java:54) * at org.apache.hcatalog.mapreduce.HCatInputFormat.setInput(HCatInputFormat.java:54)
at tlabs.CDR_In_Report.createHCatInputFormat(CDR_In_Report.java:322) * at tlabs.CDR_In_Report.createHCatInputFormat(CDR_In_Report.java:322)
at tlabs.CDR_Out_Report.main(CDR_Out_Report.java:380) * at tlabs.CDR_Out_Report.main(CDR_Out_Report.java:380)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) * at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) * at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) * at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:622) * at java.lang.reflect.Method.invoke(Method.java:622)
at org.apache.flink.client.program.PackagedProgram.callMainMethod(PackagedProgram.java:383) * at org.apache.flink.client.program.PackagedProgram.callMainMethod(PackagedProgram.java:383)
* </pre>
*
* The test works as follows:
*
* <ul>
* <li> Use the CliFrontend to invoke a jar file that loads a class which is only available
* in the jarfile itself (via a custom classloader)
* <li> Change the Usercode classloader of the PackagedProgram to a special classloader for this test
* <li> the classloader will accept the special class (and return a String.class)
* </ul>
*/ */
@Test @Test
public void testPlanWithExternalClass() throws CompilerException, ProgramInvocationException { public void testPlanWithExternalClass() throws CompilerException, ProgramInvocationException {
final boolean[] callme = { false }; // create a final object reference, to be able to change its val later final boolean[] callme = { false }; // create a final object reference, to be able to change its val later
try { try {
String[] parameters = {getTestJarPath(), "-c", TEST_JAR_CLASSLOADERTEST_CLASS , "some", "program"}; String[] arguments = {"-j", getTestJarPath(), "-c", TEST_JAR_CLASSLOADERTEST_CLASS , "--verbose", "true", "arg1", "arg2"};
CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), parameters, false); CommandLine line = new PosixParser().parse(CliFrontend.getProgramSpecificOptions(new Options()), arguments, true);
CliFrontend frontend = new CliFrontend(); CliFrontend frontend = new CliFrontend();
Object result = frontend.buildProgram(line); Object result = frontend.buildProgram(line);
assertTrue(result instanceof PackagedProgram); assertTrue(result instanceof PackagedProgram);
PackagedProgram prog = spy((PackagedProgram) result); PackagedProgram prog = spy((PackagedProgram) result);
ClassLoader testClassLoader = new ClassLoader(prog.getUserCodeClassLoader()) { ClassLoader testClassLoader = new ClassLoader(prog.getUserCodeClassLoader()) {
...@@ -256,7 +260,7 @@ public class CliFrontendPackageProgramTest { ...@@ -256,7 +260,7 @@ public class CliFrontendPackageProgramTest {
}; };
when(prog.getUserCodeClassLoader()).thenReturn(testClassLoader); when(prog.getUserCodeClassLoader()).thenReturn(testClassLoader);
Assert.assertArrayEquals(new String[]{"some", "program"}, prog.getArguments()); Assert.assertArrayEquals(new String[]{"--verbose", "true", "arg1", "arg2"}, prog.getArguments());
Assert.assertEquals(TEST_JAR_CLASSLOADERTEST_CLASS, prog.getMainClassName()); Assert.assertEquals(TEST_JAR_CLASSLOADERTEST_CLASS, prog.getMainClassName());
Configuration c = new Configuration(); Configuration c = new Configuration();
...@@ -275,9 +279,9 @@ public class CliFrontendPackageProgramTest { ...@@ -275,9 +279,9 @@ public class CliFrontendPackageProgramTest {
} }
} }
catch (Exception e) { catch (Exception e) {
assertTrue("Classloader was not called", callme[0]);
System.err.println(e.getMessage()); System.err.println(e.getMessage());
e.printStackTrace(); e.printStackTrace();
assertTrue("Classloader was not called", callme[0]);
fail("Program caused an exception: " + e.getMessage()); fail("Program caused an exception: " + e.getMessage());
} }
......
...@@ -98,6 +98,7 @@ public class WordCount { ...@@ -98,6 +98,7 @@ public class WordCount {
// ************************************************************************* // *************************************************************************
private static boolean fileOutput = false; private static boolean fileOutput = false;
private static boolean verbose = false;
private static String textPath; private static String textPath;
private static String outputPath; private static String outputPath;
...@@ -106,9 +107,13 @@ public class WordCount { ...@@ -106,9 +107,13 @@ public class WordCount {
if(args.length > 0) { if(args.length > 0) {
// parse input arguments // parse input arguments
fileOutput = true; fileOutput = true;
if(args.length == 2) { if(args.length == 2) { // cli line: program {textPath} {outputPath}
textPath = args[0]; textPath = args[0];
outputPath = args[1]; outputPath = args[1];
} else if(args.length == 4 && (args[0].startsWith("-v") || args[0].startsWith("--verbose"))) { // cli line: program {optArg} {optVal} {textPath} {outputPath}
verbose = Boolean.valueOf(args[1]);
textPath = args[2];
outputPath = args[3];
} else { } else {
System.err.println("Usage: WordCount <text path> <result path>"); System.err.println("Usage: WordCount <text path> <result path>");
return false; return false;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册