From 66d58ff469ab06db8728c5f243d8e84b63b1c8bc Mon Sep 17 00:00:00 2001 From: Prabhu Joseph Date: Thu, 24 Oct 2019 16:14:28 +0530 Subject: [PATCH] YARN-9933. Fix RMWebServices get-node-labels json response. --- .../webapp/JAXBContextResolver.java | 3 +- .../webapp/TestRMWebServicesNodeLabels.java | 166 ++++++++++++--------- 2 files changed, 96 insertions(+), 73 deletions(-) diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/JAXBContextResolver.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/JAXBContextResolver.java index e0c6647..82872ca 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/JAXBContextResolver.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/JAXBContextResolver.java @@ -56,7 +56,8 @@ public JAXBContextResolver() throws Exception { StatisticsItemInfo.class, CapacitySchedulerHealthInfo.class, FairSchedulerQueueInfoList.class, AppTimeoutsInfo.class, AppTimeoutInfo.class, ResourceInformationsInfo.class, - ActivitiesInfo.class, AppActivitiesInfo.class}; + ActivitiesInfo.class, AppActivitiesInfo.class, + NodeLabelsInfo.class}; // these dao classes need root unwrapping final Class[] rootUnwrappedTypes = { NewApplication.class, ApplicationSubmissionContextInfo.class, 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/TestRMWebServicesNodeLabels.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesNodeLabels.java index 0b2c6fe..b074498 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesNodeLabels.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesNodeLabels.java @@ -45,6 +45,7 @@ import org.apache.hadoop.yarn.webapp.GuiceServletConfig; import org.apache.hadoop.yarn.webapp.JerseyTestBase; import org.apache.hadoop.yarn.webapp.WebServicesTestUtils; +import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.junit.Assert; @@ -124,13 +125,13 @@ public void testNodeLabels() throws JSONException, Exception { ClientResponse response; // Add a label - NodeLabelsInfo nlsifo = new NodeLabelsInfo(); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("a")); + String input = "{\"nodeLabelsInfo\":{\"nodeLabelInfo\":[{\"name\":\"a\"," + + "\"exclusivity\":true}]}}"; response = r.path("ws").path("v1").path("cluster") .path("add-node-labels").queryParam("user.name", userName) .accept(MediaType.APPLICATION_JSON) - .entity(toJson(nlsifo, NodeLabelsInfo.class), MediaType.APPLICATION_JSON) + .entity(input, MediaType.APPLICATION_JSON) .post(ClientResponse.class); // Verify @@ -140,21 +141,24 @@ public void testNodeLabels() throws JSONException, Exception { .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, response.getType().toString()); - nlsifo = response.getEntity(NodeLabelsInfo.class); - assertEquals(1, nlsifo.getNodeLabels().size()); - for (NodeLabelInfo nl : nlsifo.getNodeLabelsInfo()) { - assertEquals("a", nl.getName()); - assertTrue(nl.getExclusivity()); - } - + + JSONObject json = response.getEntity(JSONObject.class); + JSONObject info = json.getJSONObject("nodeLabelsInfo"); + assertEquals("incorrect number of elements", 1, info.length()); + JSONArray array = info.getJSONArray("nodeLabelInfo"); + assertEquals("incorrect number of node labels", 1, array.length()); + + assertEquals("a", array.getJSONObject(0).getString("name")); + assertEquals("true", array.getJSONObject(0).getString("exclusivity")); + // Add another - nlsifo = new NodeLabelsInfo(); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("b", false)); + input = "{\"nodeLabelsInfo\":{\"nodeLabelInfo\":[{\"name\":\"b\"," + + "\"exclusivity\":false}]}}"; response = r.path("ws").path("v1").path("cluster") .path("add-node-labels").queryParam("user.name", userName) .accept(MediaType.APPLICATION_JSON) - .entity(toJson(nlsifo, NodeLabelsInfo.class), MediaType.APPLICATION_JSON) + .entity(input, MediaType.APPLICATION_JSON) .post(ClientResponse.class); // Verify @@ -164,14 +168,14 @@ public void testNodeLabels() throws JSONException, Exception { .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, response.getType().toString()); - nlsifo = response.getEntity(NodeLabelsInfo.class); - assertEquals(2, nlsifo.getNodeLabels().size()); - // Verify exclusivity for 'y' as false - for (NodeLabelInfo nl : nlsifo.getNodeLabelsInfo()) { - if (nl.getName().equals("b")) { - assertFalse(nl.getExclusivity()); - } - } + + json = response.getEntity(JSONObject.class); + info = json.getJSONObject("nodeLabelsInfo"); + assertEquals("incorrect number of elements", 1, info.length()); + array = info.getJSONArray("nodeLabelInfo"); + assertEquals("incorrect number of node labels", 2, array.length()); + assertEquals("b", array.getJSONObject(1).getString("name")); + assertEquals("false", array.getJSONObject(1).getString("exclusivity")); // Add labels to a node MultivaluedMapImpl params = new MultivaluedMapImpl(); @@ -252,8 +256,10 @@ public void testNodeLabels() throws JSONException, Exception { .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, response.getType().toString()); - nlsifo = response.getEntity(NodeLabelsInfo.class); - assertTrue(nlsifo.getNodeLabelsInfo().contains(new NodeLabelInfo("a"))); + json = response.getEntity(JSONObject.class); + info = json.getJSONObject("nodeLabelsInfo"); + array = info.getJSONArray("nodeLabelInfo"); + assertEquals("a", array.getJSONObject(0).getString("name")); // Replace @@ -277,9 +283,11 @@ public void testNodeLabels() throws JSONException, Exception { .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, response.getType().toString()); - nlsifo = response.getEntity(NodeLabelsInfo.class); - assertTrue(nlsifo.getNodeLabelsInfo().contains( - new NodeLabelInfo("b", false))); + json = response.getEntity(JSONObject.class); + info = json.getJSONObject("nodeLabelsInfo"); + array = info.getJSONArray("nodeLabelInfo"); + assertEquals("b", array.getJSONObject(0).getString("name")); + assertEquals("false", array.getJSONObject(0).getString("exclusivity")); // Replace labels using node-to-labels NodeToLabelsEntryList ntli = new NodeToLabelsEntryList(); @@ -328,7 +336,7 @@ public void testNodeLabels() throws JSONException, Exception { .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, response.getType().toString()); - nlsifo = response.getEntity(NodeLabelsInfo.class); + NodeLabelsInfo nlsifo = response.getEntity(NodeLabelsInfo.class); assertTrue(nlsifo.getNodeLabelsInfo().isEmpty()); // Add a label back for auth tests @@ -352,9 +360,11 @@ public void testNodeLabels() throws JSONException, Exception { .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, response.getType().toString()); - nlsifo = response.getEntity(NodeLabelsInfo.class); - assertTrue(nlsifo.getNodeLabelsInfo().contains(new NodeLabelInfo("a"))); - + json = response.getEntity(JSONObject.class); + info = json.getJSONObject("nodeLabelsInfo"); + array = info.getJSONArray("nodeLabelInfo"); + assertEquals("a", array.getJSONObject(0).getString("name")); + // Auth fail replace labels on node params = new MultivaluedMapImpl(); params.add("labels", "b"); @@ -374,8 +384,10 @@ public void testNodeLabels() throws JSONException, Exception { .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, response.getType().toString()); - nlsifo = response.getEntity(NodeLabelsInfo.class); - assertTrue(nlsifo.getNodeLabelsInfo().contains(new NodeLabelInfo("a"))); + json = response.getEntity(JSONObject.class); + info = json.getJSONObject("nodeLabelsInfo"); + array = info.getJSONArray("nodeLabelInfo"); + assertEquals("a", array.getJSONObject(0).getString("name")); // Fail to add a label with post response = @@ -392,8 +404,10 @@ public void testNodeLabels() throws JSONException, Exception { .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, response.getType().toString()); - nlsifo = response.getEntity(NodeLabelsInfo.class); - assertEquals(2, nlsifo.getNodeLabels().size()); + json = response.getEntity(JSONObject.class); + info = json.getJSONObject("nodeLabelsInfo"); + array = info.getJSONArray("nodeLabelInfo"); + assertEquals(2, array.length()); // Remove cluster label (succeed, we no longer need it) params = new MultivaluedMapImpl(); @@ -412,12 +426,12 @@ public void testNodeLabels() throws JSONException, Exception { .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, response.getType().toString()); - nlsifo = response.getEntity(NodeLabelsInfo.class); - assertEquals(1, nlsifo.getNodeLabels().size()); - for (NodeLabelInfo nl : nlsifo.getNodeLabelsInfo()) { - assertEquals("a", nl.getName()); - assertTrue(nl.getExclusivity()); - } + json = response.getEntity(JSONObject.class); + info = json.getJSONObject("nodeLabelsInfo"); + array = info.getJSONArray("nodeLabelInfo"); + assertEquals(1, array.length()); + assertEquals("a", array.getJSONObject(0).getString("name")); + assertEquals("true", array.getJSONObject(0).getString("exclusivity")); // Remove cluster label with post params = new MultivaluedMapImpl(); @@ -445,6 +459,10 @@ public void testNodeLabels() throws JSONException, Exception { nlsifo = new NodeLabelsInfo(); nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("x", false)); nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("y", false)); + + input = "{\"nodeLabelsInfo\":{\"nodeLabelInfo\":[{\"name\":\"x\"," + + "\"exclusivity\":true},{\"name\":\"y\",\"exclusivity\":true}]}}"; + response = r.path("ws") .path("v1") @@ -452,8 +470,8 @@ public void testNodeLabels() throws JSONException, Exception { .path("add-node-labels") .queryParam("user.name", userName) .accept(MediaType.APPLICATION_JSON) - .entity(toJson(nlsifo, NodeLabelsInfo.class), - MediaType.APPLICATION_JSON).post(ClientResponse.class); + .entity(input, MediaType.APPLICATION_JSON) + .post(ClientResponse.class); // Reset for testing : Add labels to a node params = new MultivaluedMapImpl(); params.add("labels", "y"); @@ -491,11 +509,14 @@ public void testNodeLabels() throws JSONException, Exception { .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, response.getType().toString()); - ntlinfo = response.getEntity(NodeToLabelsInfo.class); - nlinfo = ntlinfo.getNodeToLabels().get("nid:0"); - assertEquals(1, nlinfo.getNodeLabels().size()); - assertFalse(nlinfo.getNodeLabelsInfo().contains( - new NodeLabelInfo("x", false))); + + json = response.getEntity(JSONObject.class); + info = json.getJSONObject("nodeToLabels").getJSONObject("entry"); + JSONObject entry = info.getJSONObject("value"); + JSONObject nodeLabel = entry.getJSONObject("nodeLabelInfo"); + String expectedOutput = "{\"name\":\"y\",\"exclusivity\":\"true\"}"; + assertEquals(expectedOutput, nodeLabel.toString()); + // Case2 : failure to Replace labels using replace-labels response = @@ -536,11 +557,12 @@ public void testNodeLabels() throws JSONException, Exception { .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, response.getType().toString()); - nlsifo = response.getEntity(NodeLabelsInfo.class); - assertEquals(new NodeLabelInfo("y", false), - nlsifo.getNodeLabelsInfo().get(0)); - assertEquals("y", nlsifo.getNodeLabelsInfo().get(0).getName()); - assertFalse(nlsifo.getNodeLabelsInfo().get(0).getExclusivity()); + json = response.getEntity(JSONObject.class); + info = json.getJSONObject("nodeLabelsInfo"); + array = info.getJSONArray("nodeLabelInfo"); + assertEquals(1, array.length()); + assertEquals("y", array.getJSONObject(0).getString("name")); + assertEquals("true", array.getJSONObject(0).getString("exclusivity")); // Remove y params = new MultivaluedMapImpl(); @@ -564,8 +586,8 @@ public void testNodeLabels() throws JSONException, Exception { assertTrue(nlsifo.getNodeLabelsInfo().isEmpty()); // add a new nodelabel with exclusity - nlsifo = new NodeLabelsInfo(); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("z", false)); + input = "{\"nodeLabelsInfo\":{\"nodeLabelInfo\":[{\"name\":\"z\"," + + "\"exclusivity\":false}]}}"; response = r.path("ws") .path("v1") @@ -573,8 +595,8 @@ public void testNodeLabels() throws JSONException, Exception { .path("add-node-labels") .queryParam("user.name", userName) .accept(MediaType.APPLICATION_JSON) - .entity(toJson(nlsifo, NodeLabelsInfo.class), - MediaType.APPLICATION_JSON).post(ClientResponse.class); + .entity(input, MediaType.APPLICATION_JSON) + .post(ClientResponse.class); // Verify response = @@ -583,10 +605,12 @@ public void testNodeLabels() throws JSONException, Exception { .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, response.getType().toString()); - nlsifo = response.getEntity(NodeLabelsInfo.class); - assertEquals("z", nlsifo.getNodeLabelsInfo().get(0).getName()); - assertFalse(nlsifo.getNodeLabelsInfo().get(0).getExclusivity()); - assertEquals(1, nlsifo.getNodeLabels().size()); + json = response.getEntity(JSONObject.class); + info = json.getJSONObject("nodeLabelsInfo"); + array = info.getJSONArray("nodeLabelInfo"); + assertEquals(1, array.length()); + assertEquals("z", array.getJSONObject(0).getString("name")); + assertEquals("false", array.getJSONObject(0).getString("exclusivity")); } @Test @@ -595,12 +619,12 @@ public void testLabelInvalidAddition() WebResource r = resource(); ClientResponse response; // Add a invalid label - NodeLabelsInfo nlsifo = new NodeLabelsInfo(); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("a&")); + String input = "{\"nodeLabelsInfo\":{\"nodeLabelInfo\":[{\"name\":\"a&\"," + + "\"exclusivity\":false}]}}"; + response = r.path("ws").path("v1").path("cluster").path("add-node-labels") .queryParam("user.name", userName).accept(MediaType.APPLICATION_JSON) - .entity(toJson(nlsifo, NodeLabelsInfo.class), - MediaType.APPLICATION_JSON) + .entity(input, MediaType.APPLICATION_JSON) .post(ClientResponse.class); String expectedmessage = "java.io.IOException: label name should only contains" @@ -614,20 +638,18 @@ public void testLabelChangeExclusivity() throws Exception, JSONException { WebResource r = resource(); ClientResponse response; - NodeLabelsInfo nlsifo = new NodeLabelsInfo(); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("newlabel", true)); + String input = "{\"nodeLabelsInfo\":{\"nodeLabelInfo\":[{\"name\":" + + "\"newlabel\",\"exclusivity\":true}]}}"; response = r.path("ws").path("v1").path("cluster").path("add-node-labels") .queryParam("user.name", userName).accept(MediaType.APPLICATION_JSON) - .entity(toJson(nlsifo, NodeLabelsInfo.class), - MediaType.APPLICATION_JSON) + .entity(input, MediaType.APPLICATION_JSON) .post(ClientResponse.class); // new info and change exclusivity - NodeLabelsInfo nlsinfo2 = new NodeLabelsInfo(); - nlsinfo2.getNodeLabelsInfo().add(new NodeLabelInfo("newlabel", false)); + input = "{\"nodeLabelsInfo\":{\"nodeLabelInfo\":[{\"name\":\"newlabel\"," + + "\"exclusivity\":false}]}}"; response = r.path("ws").path("v1").path("cluster").path("add-node-labels") .queryParam("user.name", userName).accept(MediaType.APPLICATION_JSON) - .entity(toJson(nlsinfo2, NodeLabelsInfo.class), - MediaType.APPLICATION_JSON) + .entity(input, MediaType.APPLICATION_JSON) .post(ClientResponse.class); String expectedmessage = "java.io.IOException: Exclusivity cannot be modified for an existing" -- 2.7.4 (Apple Git-66)