diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java index efe5921ce3d..893348ac246 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/cli/ApplicationCLI.java @@ -88,6 +88,7 @@ public class ApplicationCLI extends YarnCLI { public static final String APP_ID = "appId"; public static final String UPDATE_PRIORITY = "updatePriority"; public static final String UPDATE_LIFETIME = "updateLifetime"; + public static final String CHANGE_APPLICATION_QUEUE = "changeQueue"; private boolean allAppStates; @@ -114,7 +115,7 @@ public class ApplicationCLI extends YarnCLI { + "based on application state and -appTags to filter applications " + "based on application tag."); opts.addOption(MOVE_TO_QUEUE_CMD, true, "Moves the application to a " - + "different queue."); + + "different queue. Deprecated command. Use 'changeQueue' instead."); opts.addOption(QUEUE_CMD, true, "Works with the movetoqueue command to" + " specify which queue to move an application to."); opts.addOption(HELP_CMD, false, "Displays help for all commands."); @@ -146,6 +147,11 @@ public class ApplicationCLI extends YarnCLI { opts.addOption(UPDATE_LIFETIME, true, "update timeout of an application from NOW. ApplicationId can be" + " passed using 'appId' option. Timeout value is in seconds."); + opts.addOption(CHANGE_APPLICATION_QUEUE, true, + "Moves application to a new queue. ApplicationId can be" + + " passed using 'appId' option. 'movetoqueue' command is" + + " deprecated, this new command 'changeQueue' performs same" + + " functionality."); Option killOpt = new Option(KILL_CMD, true, "Kills the application. " + "Set of applications can be provided separated with space"); killOpt.setValueSeparator(' '); @@ -158,6 +164,7 @@ public class ApplicationCLI extends YarnCLI { opts.getOption(APP_ID).setArgName("Application ID"); opts.getOption(UPDATE_PRIORITY).setArgName("Priority"); opts.getOption(UPDATE_LIFETIME).setArgName("Timeout"); + opts.getOption(CHANGE_APPLICATION_QUEUE).setArgName("Queue Name"); } else if (args.length > 0 && args[0].equalsIgnoreCase(APPLICATION_ATTEMPT)) { title = APPLICATION_ATTEMPT; opts.addOption(STATUS_CMD, true, @@ -315,6 +322,13 @@ public class ApplicationCLI extends YarnCLI { updateApplicationTimeout(cliParser.getOptionValue(APP_ID), ApplicationTimeoutType.LIFETIME, timeoutInSec); + } else if (cliParser.hasOption(CHANGE_APPLICATION_QUEUE)) { + if (!cliParser.hasOption(APP_ID)) { + printUsage(title, opts); + return exitCode; + } + moveApplicationAcrossQueues(cliParser.getOptionValue(APP_ID), + cliParser.getOptionValue(CHANGE_APPLICATION_QUEUE)); } else if (cliParser.hasOption(SIGNAL_CMD)) { if (args.length < 3 || args.length > 4) { printUsage(title, opts); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java index 2e90581b094..7cf9788193d 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java @@ -1211,6 +1211,59 @@ public class TestYarnCLI { } } + @Test + public void testMoveApplicationAcrossQueuesWithNewCommand() throws Exception { + ApplicationCLI cli = createAndGetAppCLI(); + ApplicationId applicationId = ApplicationId.newInstance(1234, 5); + + ApplicationReport newApplicationReport2 = ApplicationReport.newInstance( + applicationId, ApplicationAttemptId.newInstance(applicationId, 1), + "user", "queue", "appname", "host", 124, null, + YarnApplicationState.FINISHED, "diagnostics", "url", 0, 0, + FinalApplicationStatus.SUCCEEDED, null, "N/A", 0.53789f, "YARN", null); + when(client.getApplicationReport(any(ApplicationId.class))) + .thenReturn(newApplicationReport2); + int result = cli.run(new String[]{"application", "-appId", + applicationId.toString(), "-changeQueue", "targetqueue"}); + assertEquals(0, result); + verify(client, times(0)).moveApplicationAcrossQueues( + any(ApplicationId.class), any(String.class)); + verify(sysOut) + .println("Application " + applicationId + " has already finished "); + + ApplicationReport newApplicationReport = ApplicationReport.newInstance( + applicationId, ApplicationAttemptId.newInstance(applicationId, 1), + "user", "queue", "appname", "host", 124, null, + YarnApplicationState.RUNNING, "diagnostics", "url", 0, 0, + FinalApplicationStatus.SUCCEEDED, null, "N/A", 0.53789f, "YARN", null); + when(client.getApplicationReport(any(ApplicationId.class))) + .thenReturn(newApplicationReport); + result = cli.run(new String[]{"application", "-appId", + applicationId.toString(), "-changeQueue", "targetqueue"}); + assertEquals(0, result); + verify(client).moveApplicationAcrossQueues(any(ApplicationId.class), + any(String.class)); + verify(sysOut).println( + "Moving application application_1234_0005 to queue targetqueue"); + verify(sysOut).println("Successfully completed move."); + + doThrow(new ApplicationNotFoundException( + "Application with id '" + applicationId + "' doesn't exist in RM.")) + .when(client) + .moveApplicationAcrossQueues(applicationId, "targetqueue"); + cli = createAndGetAppCLI(); + try { + result = cli.run(new String[]{"application", "-appId", + applicationId.toString(), "-changeQueue", "targetqueue"}); + Assert.fail(); + } catch (Exception ex) { + Assert.assertTrue(ex instanceof ApplicationNotFoundException); + Assert.assertEquals( + "Application with id '" + applicationId + "' doesn't exist in RM.", + ex.getMessage()); + } + } + @Test public void testListClusterNodes() throws Exception { List nodeReports = new ArrayList(); @@ -1972,6 +2025,12 @@ public class TestYarnCLI { pw.println(" -appTypes Works with -list to filter applications"); pw.println(" based on input comma-separated list of"); pw.println(" application types."); + pw.println(" -changeQueue Moves application to a new queue."); + pw.println(" ApplicationId can be passed using 'appId'"); + pw.println(" option. 'movetoqueue' command is"); + pw.println(" deprecated, this new command"); + pw.println(" 'changeQueue' performs same"); + pw.println(" functionality."); pw.println(" -help Displays help for all commands."); pw.println(" -kill Kills the application. Set of"); pw.println(" applications can be provided separated"); @@ -1983,7 +2042,8 @@ public class TestYarnCLI { pw.println(" and -appTags to filter applications based"); pw.println(" on application tag."); pw.println(" -movetoqueue Moves the application to a different"); - pw.println(" queue."); + pw.println(" queue. Deprecated command. Use"); + pw.println(" 'changeQueue' instead."); pw.println(" -queue Works with the movetoqueue command to"); pw.println(" specify which queue to move an"); pw.println(" application to.");