diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/conf/MutableCSConfigurationProvider.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/conf/MutableCSConfigurationProvider.java index 9c3bf9d..c21a6ef 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/conf/MutableCSConfigurationProvider.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/conf/MutableCSConfigurationProvider.java @@ -243,6 +243,20 @@ private void addQueue( } String parentQueue = queuePath.substring(0, queuePath.lastIndexOf('.')); String[] siblings = proposedConf.getQueues(parentQueue); + // validate if parent queue is existing + if (siblings == null && !parentQueue + .equals(CapacitySchedulerConfiguration.ROOT)) { + if (parentQueue.lastIndexOf('.') == -1) { + throw new IOException("Can't find parent queue " + parentQueue); + } + String parentQueueName = + parentQueue.substring(parentQueue.lastIndexOf('.') + 1); + List parentSiblings = + getSiblingQueues(parentQueue, proposedConf); + if (!parentSiblings.contains(parentQueueName)) { + throw new IOException("Can't find parent queue " + parentQueue); + } + } List siblingQueues = siblings == null ? new ArrayList<>() : new ArrayList<>(Arrays.asList(siblings)); siblingQueues.add(queuePath.substring(queuePath.lastIndexOf('.') + 1)); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesConfigurationMutation.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesConfigurationMutation.java index 3d28f12..c27da75 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesConfigurationMutation.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesConfigurationMutation.java @@ -54,6 +54,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; /** * Test scheduler configuration mutation via REST API. @@ -153,6 +154,44 @@ public TestRMWebServicesConfigurationMutation() { .contextPath("jersey-guice-filter").servletPath("/").build()); } + + @Test + public void testAddQueueWithNonExistentParentQueue() throws Exception { + WebResource r = resource(); + ClientResponse response; + SchedConfUpdateInfo updateInfo = new SchedConfUpdateInfo(); + Map leafCapacity = new HashMap<>(); + leafCapacity.put(CapacitySchedulerConfiguration.CAPACITY, "0"); + leafCapacity.put(CapacitySchedulerConfiguration.MAXIMUM_CAPACITY, "100"); + + // Add non-existent queue : root.e.test + QueueConfigInfo testQueue = + new QueueConfigInfo("root.e.test", leafCapacity); + updateInfo.getAddQueueInfo().add(testQueue); + response = r.path("ws").path("v1").path("cluster").path("scheduler-conf") + .queryParam("user.name", userName).accept(MediaType.APPLICATION_JSON) + .entity( + YarnWebServiceUtils.toJson(updateInfo, SchedConfUpdateInfo.class), + MediaType.APPLICATION_JSON).put(ClientResponse.class); + assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + assertTrue( + response.getEntity(String.class).contains("Can't find parent queue")); + + // Add non-existent queue : xxx.test + updateInfo = new SchedConfUpdateInfo(); + testQueue = + new QueueConfigInfo("xxx.test", leafCapacity); + updateInfo.getAddQueueInfo().add(testQueue); + response = r.path("ws").path("v1").path("cluster").path("scheduler-conf") + .queryParam("user.name", userName).accept(MediaType.APPLICATION_JSON) + .entity( + YarnWebServiceUtils.toJson(updateInfo, SchedConfUpdateInfo.class), + MediaType.APPLICATION_JSON).put(ClientResponse.class); + assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + assertTrue( + response.getEntity(String.class).contains("Can't find parent queue")); + } + @Test public void testAddNestedQueue() throws Exception { WebResource r = resource(); @@ -174,9 +213,9 @@ public void testAddNestedQueue() throws Exception { QueueConfigInfo d1 = new QueueConfigInfo("root.d.d1", d1Capacity); QueueConfigInfo d2 = new QueueConfigInfo("root.d.d2", d2Capacity); QueueConfigInfo d = new QueueConfigInfo("root.d", nearEmptyCapacity); + updateInfo.getAddQueueInfo().add(d); updateInfo.getAddQueueInfo().add(d1); updateInfo.getAddQueueInfo().add(d2); - updateInfo.getAddQueueInfo().add(d); response = r.path("ws").path("v1").path("cluster") .path("scheduler-conf").queryParam("user.name", userName)