From 9539ff108aaa420168935a3dbc73c43c1686e252 Mon Sep 17 00:00:00 2001 From: 9uapaw Date: Thu, 10 Mar 2022 08:02:18 +0100 Subject: [PATCH] YARN-11052. Improve code quality in TestRMWebServicesNodeLabels. Contributed by Szilard Nemeth --- .../webapp/TestRMWebServicesNodeLabels.java | 934 ++++++++---------- 1 file changed, 422 insertions(+), 512 deletions(-) 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 f1ea0fba033..503b4a8b2bb 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 @@ -6,9 +6,9 @@ * 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 - * + *

+ * 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. @@ -26,9 +26,15 @@ import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; +import java.util.List; +import java.util.Map; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.hadoop.util.Lists; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.hadoop.http.JettyUtils; @@ -55,7 +61,6 @@ import com.google.inject.Guice; import com.google.inject.servlet.ServletModule; import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.json.JSONJAXBContext; import com.sun.jersey.api.json.JSONMarshaller; @@ -69,6 +74,28 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase { private static final Logger LOG = LoggerFactory .getLogger(TestRMWebServicesNodeLabels.class); + private static final String NODE_0 = "nid:0"; + private static final String NODE_1 = "nid1:0"; + private static final String NODE_2 = "nid2:0"; + private static final String LABEL_A = "a"; + private static final String LABEL_B = "b"; + private static final String LABEL_X = "x"; + private static final String LABEL_Y = "y"; + private static final String LABEL_Z = "z"; + public static final boolean DEFAULT_NL_EXCLUSIVITY = true; + private static final String PATH_WS = "ws"; + private static final String PATH_V1 = "v1"; + private static final String PATH_NODES = "nodes"; + private static final String PATH_CLUSTER = "cluster"; + private static final String PATH_REPLACE_NODE_TO_LABELS = "replace-node-to-labels"; + private static final String PATH_LABEL_MAPPINGS = "label-mappings"; + private static final String PATH_GET_LABELS = "get-labels"; + private static final String PATH_REPLACE_LABELS = "replace-labels"; + private static final String PATH_REMOVE_LABELS = "remove-node-labels"; + private static final String PATH_GET_NODE_LABELS = "get-node-labels"; + private static final String PATH_GET_NODE_TO_LABELS = "get-node-to-labels"; + private static final String QUERY_USER_NAME = "user.name"; + private static final String PATH_ADD_NODE_LABELS = "add-node-labels"; private static MockRM rm; private static YarnConfiguration conf; @@ -76,6 +103,8 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase { private static String userName; private static String notUserName; private static RMWebServices rmWebService; + private WebResource resource; + private static class WebServletModule extends ServletModule { @@ -92,7 +121,7 @@ protected void configureServlets() { conf = new YarnConfiguration(); conf.set(YarnConfiguration.YARN_ADMIN_ACL, userName); rm = new MockRM(conf); - rmWebService = new RMWebServices(rm,conf); + rmWebService = new RMWebServices(rm, conf); bind(RMWebServices.class).toInstance(rmWebService); bind(GenericExceptionHandler.class); bind(ResourceManager.class).toInstance(rm); @@ -100,7 +129,7 @@ protected void configureServlets() { TestRMWebServicesAppsModification.TestRMCustomAuthFilter.class); serve("/*").with(GuiceContainer.class); } - }; + } @Override @Before @@ -108,6 +137,7 @@ public void setUp() throws Exception { super.setUp(); GuiceServletConfig.setInjector( Guice.createInjector(new WebServletModule())); + resource = resource(); } public TestRMWebServicesNodeLabels() { @@ -118,528 +148,444 @@ public TestRMWebServicesNodeLabels() { .contextPath("jersey-guice-filter").servletPath("/").build()); } - @Test - public void testNodeLabels() throws JSONException, Exception { - WebResource r = resource(); + private WebResource getClusterWebResource() { + return resource.path(PATH_WS).path(PATH_V1).path(PATH_CLUSTER); + } + private ClientResponse get(String path) { + return getClusterWebResource() + .path(path) + .queryParam(QUERY_USER_NAME, userName) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + } + + private ClientResponse get(String path, MultivaluedMapImpl queryParams) { + return getClusterWebResource() + .path(path) + .queryParam(QUERY_USER_NAME, userName) + .queryParams(queryParams) + .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + } + + private ClientResponse post(String path, String userName, Object payload, + Class payloadClass) throws Exception { + return getClusterWebResource() + .path(path) + .queryParam(QUERY_USER_NAME, userName) + .accept(MediaType.APPLICATION_JSON) + .entity(toJson(payload, payloadClass), + MediaType.APPLICATION_JSON) + .post(ClientResponse.class); + } + + private ClientResponse post(String path, String userName, Object payload, + Class payloadClass, MultivaluedMapImpl queryParams) throws Exception { + WebResource.Builder builder = getClusterWebResource() + .path(path) + .queryParam(QUERY_USER_NAME, userName) + .queryParams(queryParams) + .accept(MediaType.APPLICATION_JSON); + + if (payload != null && payloadClass != null) { + builder.entity(toJson(payload, payloadClass), MediaType.APPLICATION_JSON); + } + return builder.post(ClientResponse.class); + } + + @Test + public void testNodeLabels() throws Exception { ClientResponse response; // Add a label - NodeLabelsInfo nlsifo = new NodeLabelsInfo(); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("a")); - 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) - .post(ClientResponse.class); + response = addNodeLabels(Lists.newArrayList(Pair.of(LABEL_A, DEFAULT_NL_EXCLUSIVITY))); + assertHttp200(response); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("get-node-labels").queryParam("user.name", userName) - .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()); - } - + response = getNodeLabels(); + assertApplicationJsonUtf8Response(response); + assertNodeLabelsInfo(response.getEntity(NodeLabelsInfo.class), Lists.newArrayList( + Pair.of(LABEL_A, true))); + // Add another - nlsifo = new NodeLabelsInfo(); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("b", 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) - .post(ClientResponse.class); + response = addNodeLabels(Lists.newArrayList(Pair.of(LABEL_B, false))); + assertHttp200(response); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("get-node-labels").queryParam("user.name", userName) - .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()); - } - } - + response = getNodeLabels(); + assertApplicationJsonUtf8Response(response); + // Verify exclusivity for 'b' as false + assertNodeLabelsInfo(response.getEntity(NodeLabelsInfo.class), + Lists.newArrayList( + Pair.of(LABEL_A, true), + Pair.of(LABEL_B, false))); + // Add labels to a node - MultivaluedMapImpl params = new MultivaluedMapImpl(); - params.add("labels", "a"); - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nid:0") - .path("replace-labels") - .queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); - LOG.info("posted node nodelabel"); + response = replaceLabelsOnNode(NODE_0, LABEL_A); + assertHttp200(response); // Add labels to another node - params = new MultivaluedMapImpl(); - params.add("labels", "b"); - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nid1:0") - .path("replace-labels") - .queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); - LOG.info("posted node nodelabel"); + response = replaceLabelsOnNode(NODE_1, LABEL_B); + assertHttp200(response); // Add labels to another node - params = new MultivaluedMapImpl(); - params.add("labels", "b"); - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nid2:0") - .path("replace-labels") - .queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); - LOG.info("posted node nodelabel"); + response = replaceLabelsOnNode(NODE_2, LABEL_B); + assertHttp200(response); - // Verify, using get-labels-to-Nodes - response = - r.path("ws").path("v1").path("cluster") - .path("label-mappings").queryParam("user.name", userName) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); - assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, - response.getType().toString()); - LabelsToNodesInfo ltni = response.getEntity(LabelsToNodesInfo.class); - assertEquals(2, ltni.getLabelsToNodes().size()); - NodeIDsInfo nodes = ltni.getLabelsToNodes().get( - new NodeLabelInfo("b", false)); - assertTrue(nodes.getNodeIDs().contains("nid2:0")); - assertTrue(nodes.getNodeIDs().contains("nid1:0")); - nodes = ltni.getLabelsToNodes().get(new NodeLabelInfo("a")); - assertTrue(nodes.getNodeIDs().contains("nid:0")); + // Verify all, using get-labels-to-Nodes + response = getNodeLabelMappings(); + assertApplicationJsonUtf8Response(response); + LabelsToNodesInfo labelsToNodesInfo = response.getEntity(LabelsToNodesInfo.class); + assertLabelsToNodesInfo(labelsToNodesInfo, 2, Lists.newArrayList( + Pair.of(Pair.of(LABEL_B, false), Lists.newArrayList(NODE_1, NODE_2)), + Pair.of(Pair.of(LABEL_A, DEFAULT_NL_EXCLUSIVITY), Lists.newArrayList(NODE_0)) + )); // Verify, using get-labels-to-Nodes for specified set of labels - params = new MultivaluedMapImpl(); - params.add("labels", "a"); - response = - r.path("ws").path("v1").path("cluster") - .path("label-mappings").queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .get(ClientResponse.class); - assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, - response.getType().toString()); - ltni = response.getEntity(LabelsToNodesInfo.class); - assertEquals(1, ltni.getLabelsToNodes().size()); - nodes = ltni.getLabelsToNodes().get(new NodeLabelInfo("a")); - assertTrue(nodes.getNodeIDs().contains("nid:0")); + response = getNodeLabelMappingsByLabels(LABEL_A); + assertApplicationJsonUtf8Response(response); + labelsToNodesInfo = response.getEntity(LabelsToNodesInfo.class); + assertLabelsToNodesInfo(labelsToNodesInfo, 1, Lists.newArrayList( + Pair.of(Pair.of(LABEL_A, DEFAULT_NL_EXCLUSIVITY), Lists.newArrayList(NODE_0)) + )); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nid:0") - .path("get-labels").queryParam("user.name", userName) - .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"))); + response = getLabelsOfNode(NODE_0); + assertApplicationJsonUtf8Response(response); + assertNodeLabelsInfoContains(response.getEntity(NodeLabelsInfo.class), + Pair.of(LABEL_A, DEFAULT_NL_EXCLUSIVITY)); - // Replace - params = new MultivaluedMapImpl(); - params.add("labels", "b"); - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nid:0") - .path("replace-labels") - .queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); - LOG.info("posted node nodelabel"); + response = replaceLabelsOnNode(NODE_0, LABEL_B); + assertHttp200(response); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nid:0") - .path("get-labels").queryParam("user.name", userName) - .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))); - + response = getLabelsOfNode(NODE_0); + assertApplicationJsonUtf8Response(response); + assertNodeLabelsInfoContains(response.getEntity(NodeLabelsInfo.class), Pair.of(LABEL_B, false)); + // Replace labels using node-to-labels - NodeToLabelsEntryList ntli = new NodeToLabelsEntryList(); - ArrayList labels = new ArrayList(); - labels.add("a"); - NodeToLabelsEntry nli = new NodeToLabelsEntry("nid:0", labels); - ntli.getNodeToLabels().add(nli); - response = - r.path("ws").path("v1").path("cluster") - .path("replace-node-to-labels") - .queryParam("user.name", userName) - .accept(MediaType.APPLICATION_JSON) - .entity(toJson(ntli, NodeToLabelsEntryList.class), - MediaType.APPLICATION_JSON) - .post(ClientResponse.class); - + response = replaceNodeToLabels(Lists.newArrayList(Pair.of(NODE_0, + Lists.newArrayList(LABEL_A)))); + assertHttp200(response); + // Verify, using node-to-labels - response = - r.path("ws").path("v1").path("cluster") - .path("get-node-to-labels").queryParam("user.name", userName) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); - assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, - response.getType().toString()); - NodeToLabelsInfo ntlinfo = response.getEntity(NodeToLabelsInfo.class); - NodeLabelsInfo nlinfo = ntlinfo.getNodeToLabels().get("nid:0"); - assertEquals(1, nlinfo.getNodeLabels().size()); - assertTrue(nlinfo.getNodeLabelsInfo().contains(new NodeLabelInfo("a"))); - + response = getNodeToLabels(); + assertApplicationJsonUtf8Response(response); + NodeToLabelsInfo nodeToLabelsInfo = response.getEntity(NodeToLabelsInfo.class); + NodeLabelsInfo nodeLabelsInfo = nodeToLabelsInfo.getNodeToLabels().get(NODE_0); + assertNodeLabelsSize(nodeLabelsInfo, 1); + assertNodeLabelsInfoContains(nodeLabelsInfo, Pair.of(LABEL_A, DEFAULT_NL_EXCLUSIVITY)); + // Remove all - params = new MultivaluedMapImpl(); - params.add("labels", ""); - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nid:0") - .path("replace-labels") - .queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); - LOG.info("posted node nodelabel"); + response = replaceLabelsOnNode(NODE_0, ""); + assertHttp200(response); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nid:0") - .path("get-labels").queryParam("user.name", userName) - .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().isEmpty()); - + response = getLabelsOfNode(NODE_0); + assertApplicationJsonUtf8Response(response); + assertNodeLabelsSize(response.getEntity(NodeLabelsInfo.class), 0); + // Add a label back for auth tests - params = new MultivaluedMapImpl(); - params.add("labels", "a"); - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nid:0") - .path("replace-labels") - .queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); - LOG.info("posted node nodelabel"); + response = replaceLabelsOnNode(NODE_0, LABEL_A); + assertHttp200(response); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nid:0") - .path("get-labels").queryParam("user.name", userName) - .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"))); - + response = getLabelsOfNode(NODE_0); + assertApplicationJsonUtf8Response(response); + assertNodeLabelsInfoContains(response.getEntity(NodeLabelsInfo.class), + Pair.of(LABEL_A, DEFAULT_NL_EXCLUSIVITY)); + // Auth fail replace labels on node - params = new MultivaluedMapImpl(); - params.add("labels", "b"); - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nid:0") - .path("replace-labels") - .queryParam("user.name", notUserName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); + response = replaceLabelsOnNodeWithUserName(NODE_0, notUserName, LABEL_B); + assertHttp401(response); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nid:0") - .path("get-labels").queryParam("user.name", userName) - .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"))); - - // Fail to add a label with post - response = - r.path("ws").path("v1").path("cluster") - .path("add-node-labels").queryParam("user.name", notUserName) - .accept(MediaType.APPLICATION_JSON) - .entity("{\"nodeLabels\":\"c\"}", MediaType.APPLICATION_JSON) - .post(ClientResponse.class); + response = getLabelsOfNode(NODE_0); + assertApplicationJsonUtf8Response(response); + assertNodeLabelsInfoContains(response.getEntity(NodeLabelsInfo.class), + Pair.of(LABEL_A, DEFAULT_NL_EXCLUSIVITY)); + + // Fail to add a label with wrong user + response = addNodeLabelsWithUser(Lists.newArrayList(Pair.of("c", DEFAULT_NL_EXCLUSIVITY)), + notUserName); + assertHttp401(response); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("get-node-labels").queryParam("user.name", userName) - .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()); - + response = getNodeLabels(); + assertApplicationJsonUtf8Response(response); + assertNodeLabelsSize(response.getEntity(NodeLabelsInfo.class), 2); + // Remove cluster label (succeed, we no longer need it) - params = new MultivaluedMapImpl(); - params.add("labels", "b"); - response = - r.path("ws").path("v1").path("cluster") - .path("remove-node-labels") - .queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); + response = removeNodeLabel(LABEL_B); + assertHttp200(response); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("get-node-labels").queryParam("user.name", userName) - .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()); - } - + response = getNodeLabels(); + assertApplicationJsonUtf8Response(response); + assertNodeLabelsInfo(response.getEntity(NodeLabelsInfo.class), + Lists.newArrayList(Pair.of(LABEL_A, true))); + // Remove cluster label with post - params = new MultivaluedMapImpl(); - params.add("labels", "a"); - response = - r.path("ws").path("v1").path("cluster") - .path("remove-node-labels") - .queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); + response = removeNodeLabel(LABEL_A); + assertHttp200(response); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("get-node-labels").queryParam("user.name", userName) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); - assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, - response.getType().toString()); - nlsifo = response.getEntity(NodeLabelsInfo.class); - assertEquals(0, nlsifo.getNodeLabels().size()); + response = getNodeLabels(); + assertApplicationJsonUtf8Response(response); + nodeLabelsInfo = response.getEntity(NodeLabelsInfo.class); + assertEquals(0, nodeLabelsInfo.getNodeLabels().size()); // Following test cases are to test replace when distributed node label // configuration is on // Reset for testing : add cluster labels - nlsifo = new NodeLabelsInfo(); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("x", false)); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("y", 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).post(ClientResponse.class); + response = addNodeLabels(Lists.newArrayList( + Pair.of(LABEL_X, false), Pair.of(LABEL_Y, false))); + assertHttp200(response); // Reset for testing : Add labels to a node - params = new MultivaluedMapImpl(); - params.add("labels", "y"); - response = - r.path("ws").path("v1").path("cluster").path("nodes").path("nid:0") - .path("replace-labels").queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); - LOG.info("posted node nodelabel"); + response = replaceLabelsOnNode(NODE_0, LABEL_Y); + assertHttp200(response); - //setting rmWebService for non Centralized NodeLabel Configuration + //setting rmWebService for non-centralized NodeLabel Configuration rmWebService.isCentralizedNodeLabelConfiguration = false; // Case1 : Replace labels using node-to-labels - ntli = new NodeToLabelsEntryList(); - labels = new ArrayList(); - labels.add("x"); - nli = new NodeToLabelsEntry("nid:0", labels); - ntli.getNodeToLabels().add(nli); - response = - r.path("ws") - .path("v1") - .path("cluster") - .path("replace-node-to-labels") - .queryParam("user.name", userName) - .accept(MediaType.APPLICATION_JSON) - .entity(toJson(ntli, NodeToLabelsEntryList.class), - MediaType.APPLICATION_JSON).post(ClientResponse.class); + response = replaceNodeToLabels(Lists.newArrayList(Pair.of(NODE_0, + Lists.newArrayList(LABEL_X)))); + assertHttp404(response); // Verify, using node-to-labels that previous operation has failed - response = - r.path("ws").path("v1").path("cluster").path("get-node-to-labels") - .queryParam("user.name", userName) - .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))); + response = getNodeToLabels(); + assertApplicationJsonUtf8Response(response); + nodeToLabelsInfo = response.getEntity(NodeToLabelsInfo.class); + nodeLabelsInfo = nodeToLabelsInfo.getNodeToLabels().get(NODE_0); + assertNodeLabelsSize(nodeLabelsInfo, 1); + assertNodeLabelsInfoDoesNotContain(nodeLabelsInfo, Pair.of(LABEL_X, false)); // Case2 : failure to Replace labels using replace-labels - response = - r.path("ws").path("v1").path("cluster").path("nodes").path("nid:0") - .path("replace-labels").queryParam("user.name", userName) - .accept(MediaType.APPLICATION_JSON) - .entity("{\"nodeLabelName\": [\"x\"]}", MediaType.APPLICATION_JSON) - .post(ClientResponse.class); - LOG.info("posted node nodelabel"); + response = replaceLabelsOnNode(NODE_0, LABEL_X); + assertHttp404(response); // Verify, using node-to-labels that previous operation has failed - response = - r.path("ws").path("v1").path("cluster").path("get-node-to-labels") - .queryParam("user.name", userName) - .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))); + response = getNodeToLabels(); + assertApplicationJsonUtf8Response(response); + nodeToLabelsInfo = response.getEntity(NodeToLabelsInfo.class); + nodeLabelsInfo = nodeToLabelsInfo.getNodeToLabels().get(NODE_0); + assertNodeLabelsSize(nodeLabelsInfo, 1); + assertNodeLabelsInfoDoesNotContain(nodeLabelsInfo, Pair.of(LABEL_X, false)); // Case3 : Remove cluster label should be successful - params = new MultivaluedMapImpl(); - params.add("labels", "x"); - response = - r.path("ws").path("v1").path("cluster") - .path("remove-node-labels") - .queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); + response = removeNodeLabel(LABEL_X); + assertHttp200(response); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("get-node-labels").queryParam("user.name", userName) - .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()); + response = getNodeLabels(); + assertApplicationJsonUtf8Response(response); + assertNodeLabelsInfoAtPosition(response.getEntity(NodeLabelsInfo.class), Pair.of(LABEL_Y, + false), 0); // Remove y - params = new MultivaluedMapImpl(); - params.add("labels", "y"); - response = - r.path("ws").path("v1").path("cluster") - .path("remove-node-labels") - .queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); + response = removeNodeLabel(LABEL_Y); + assertHttp200(response); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("get-node-labels").queryParam("user.name", userName) - .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().isEmpty()); - - // add a new nodelabel with exclusity - nlsifo = new NodeLabelsInfo(); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("z", 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).post(ClientResponse.class); + response = getNodeLabels(); + assertApplicationJsonUtf8Response(response); + assertNodeLabelsSize(response.getEntity(NodeLabelsInfo.class), 0); + // add a new nodelabel with exclusivity=false + response = addNodeLabels(Lists.newArrayList(Pair.of(LABEL_Z, false))); + assertHttp200(response); // Verify - response = - r.path("ws").path("v1").path("cluster") - .path("get-node-labels").queryParam("user.name", userName) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); + response = getNodeLabels(); + assertApplicationJsonUtf8Response(response); + assertNodeLabelsInfoAtPosition(response.getEntity(NodeLabelsInfo.class), + Pair.of(LABEL_Z, false), 0); + assertNodeLabelsSize(nodeLabelsInfo, 1); + } + + private void assertLabelsToNodesInfo(LabelsToNodesInfo labelsToNodesInfo, int size, + List, List>> nodeLabelsToNodesList) { + Map labelsToNodes = labelsToNodesInfo.getLabelsToNodes(); + assertNotNull("Labels to nodes mapping should not be null.", labelsToNodes); + assertEquals("Size of label to nodes mapping is not the expected.", size, labelsToNodes.size()); + + for (Pair, List> nodeLabelToNodes : nodeLabelsToNodesList) { + Pair expectedNLData = nodeLabelToNodes.getLeft(); + List expectedNodes = nodeLabelToNodes.getRight(); + NodeLabelInfo expectedNLInfo = new NodeLabelInfo(expectedNLData.getLeft(), + expectedNLData.getRight()); + NodeIDsInfo actualNodes = labelsToNodes.get(expectedNLInfo); + assertNotNull(String.format("Node info not found. Expected NodeLabel data: %s", + expectedNLData), actualNodes); + for (String expectedNode : expectedNodes) { + assertTrue(String.format("Can't find node ID in actual Node IDs list: %s", + actualNodes.getNodeIDs()), actualNodes.getNodeIDs().contains(expectedNode)); + } + } + } + + private void assertNodeLabelsInfo(NodeLabelsInfo nodeLabelsInfo, + List> nlInfos) { + assertEquals(nlInfos.size(), nodeLabelsInfo.getNodeLabels().size()); + + for (int i = 0; i < nodeLabelsInfo.getNodeLabelsInfo().size(); i++) { + Pair expected = nlInfos.get(i); + NodeLabelInfo actual = nodeLabelsInfo.getNodeLabelsInfo().get(i); + LOG.debug("Checking NodeLabelInfo: {}", actual); + assertEquals(expected.getLeft(), actual.getName()); + assertEquals(expected.getRight(), actual.getExclusivity()); + } + } + + private void assertNodeLabelsInfoAtPosition(NodeLabelsInfo nodeLabelsInfo, Pair nlInfo, int pos) { + NodeLabelInfo actual = nodeLabelsInfo.getNodeLabelsInfo().get(pos); + LOG.debug("Checking NodeLabelInfo: {}", actual); + assertEquals(nlInfo.getLeft(), actual.getName()); + assertEquals(nlInfo.getRight(), actual.getExclusivity()); + } + + private void assertNodeLabelsInfoContains(NodeLabelsInfo nodeLabelsInfo, + Pair nlInfo) { + NodeLabelInfo nodeLabelInfo = new NodeLabelInfo(nlInfo.getLeft(), nlInfo.getRight()); + assertTrue(String.format("Cannot find nodeLabelInfo '%s' among items of node label info list:" + + " %s", nodeLabelInfo, nodeLabelsInfo.getNodeLabelsInfo()), + nodeLabelsInfo.getNodeLabelsInfo().contains(nodeLabelInfo)); + } + + private void assertNodeLabelsInfoDoesNotContain(NodeLabelsInfo nodeLabelsInfo, Pair nlInfo) { + NodeLabelInfo nodeLabelInfo = new NodeLabelInfo(nlInfo.getLeft(), nlInfo.getRight()); + assertFalse(String.format("Should have not found nodeLabelInfo '%s' among " + + "items of node label info list: %s", nodeLabelInfo, nodeLabelsInfo.getNodeLabelsInfo()), + nodeLabelsInfo.getNodeLabelsInfo().contains(nodeLabelInfo)); + } + + private void assertNodeLabelsSize(NodeLabelsInfo nodeLabelsInfo, int expectedSize) { + assertEquals(expectedSize, nodeLabelsInfo.getNodeLabelsInfo().size()); + } + + private ClientResponse replaceNodeToLabels(List>> nodeToLabelInfos) throws Exception { + NodeToLabelsEntryList nodeToLabelsEntries = new NodeToLabelsEntryList(); + + for (Pair> nodeToLabelInfo : nodeToLabelInfos) { + ArrayList labelList = new ArrayList<>(nodeToLabelInfo.getRight()); + String nodeId = nodeToLabelInfo.getLeft(); + NodeToLabelsEntry nli = new NodeToLabelsEntry(nodeId, labelList); + nodeToLabelsEntries.getNodeToLabels().add(nli); + } + return post(PATH_REPLACE_NODE_TO_LABELS, userName, nodeToLabelsEntries, NodeToLabelsEntryList.class); + } + + private ClientResponse getNodeLabelMappings() { + return get(PATH_LABEL_MAPPINGS); + } + + private ClientResponse getNodeLabelMappingsByLabels(String... labelNames) { + MultivaluedMapImpl params = createMultiValuedMap(labelNames); + return get(PATH_LABEL_MAPPINGS, params); + } + + private ClientResponse replaceLabelsOnNode(String node, String... labelNames) throws Exception { + return replaceLabelsOnNodeWithUserName(node, userName, labelNames); + } + + private ClientResponse replaceLabelsOnNodeWithUserName(String node, + String userName, String... labelNames) throws Exception { + LOG.info("Replacing labels on node '{}', label(s): {}", node, labelNames); + MultivaluedMapImpl params = createMultiValuedMap(labelNames); + String path = UriBuilder.fromPath(PATH_NODES).path(node) + .path(PATH_REPLACE_LABELS).build().toString(); + return post(path, userName, null, null, params); + } + + private static MultivaluedMapImpl createMultiValuedMap(String[] labelNames) { + MultivaluedMapImpl params = new MultivaluedMapImpl(); + for (String labelName : labelNames) { + params.add("labels", labelName); + } + return params; + } + + private ClientResponse removeNodeLabel(String... labelNames) throws Exception { + MultivaluedMapImpl params = createMultiValuedMap(labelNames); + return post(PATH_REMOVE_LABELS, userName, null, null, params); + } + + private ClientResponse getLabelsOfNode(String node) { + String path = UriBuilder.fromPath(PATH_NODES).path(node) + .path(PATH_GET_LABELS).build().toString(); + return get(path); + } + + private ClientResponse getNodeLabels() { + return get(PATH_GET_NODE_LABELS); + } + + private ClientResponse getNodeToLabels() { + return get(PATH_GET_NODE_TO_LABELS); + } + + private ClientResponse addNodeLabels(List> nlInfos) throws Exception { + return addNodeLabelsInternal(nlInfos, userName); + } + + private ClientResponse addNodeLabelsWithUser(List> nlInfos, + String userName) throws Exception { + return addNodeLabelsInternal(nlInfos, userName); + } + + private ClientResponse addNodeLabelsInternal(List> nlInfos, + String userName) throws Exception { + NodeLabelsInfo nodeLabelsInfo = new NodeLabelsInfo(); + for (Pair nlInfo : nlInfos) { + NodeLabelInfo nodeLabelInfo = new NodeLabelInfo(nlInfo.getLeft(), nlInfo.getRight()); + nodeLabelsInfo.getNodeLabelsInfo().add(nodeLabelInfo); + } + return post(PATH_ADD_NODE_LABELS, userName, nodeLabelsInfo, NodeLabelsInfo.class); + } + + private void assertApplicationJsonUtf8Response(ClientResponse response) { 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()); + } + + private void assertHttp200(ClientResponse response) { + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + } + + private void assertHttp401(ClientResponse response) { + assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), response.getStatus()); + } + + private void assertHttp404(ClientResponse response) { + assertEquals(Response.Status.NOT_FOUND.getStatusCode(), response.getStatus()); } @Test public void testLabelInvalidAddition() - throws UniformInterfaceException, Exception { - WebResource r = resource(); - ClientResponse response; + throws Exception { // Add a invalid label - NodeLabelsInfo nlsifo = new NodeLabelsInfo(); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("a&")); - 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) - .post(ClientResponse.class); - String expectedmessage = + ClientResponse response = addNodeLabels(Lists.newArrayList(Pair.of("a&", + DEFAULT_NL_EXCLUSIVITY))); + String expectedMessage = "java.io.IOException: label name should only contains" + " {0-9, a-z, A-Z, -, _} and should not started with" + " {-,_}, now it is= a&"; - validateJsonExceptionContent(response, expectedmessage); + validateJsonExceptionContent(response, expectedMessage); } @Test public void testLabelChangeExclusivity() - throws Exception, JSONException { - WebResource r = resource(); + throws Exception { ClientResponse response; - NodeLabelsInfo nlsifo = new NodeLabelsInfo(); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("newlabel", 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) - .post(ClientResponse.class); + response = addNodeLabels(Lists.newArrayList(Pair.of("newLabel", DEFAULT_NL_EXCLUSIVITY))); + assertHttp200(response); // new info and change exclusivity - NodeLabelsInfo nlsinfo2 = new NodeLabelsInfo(); - nlsinfo2.getNodeLabelsInfo().add(new NodeLabelInfo("newlabel", 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) - .post(ClientResponse.class); - String expectedmessage = + response = addNodeLabels(Lists.newArrayList(Pair.of("newLabel", false))); + String expectedMessage = "java.io.IOException: Exclusivity cannot be modified for an existing" - + " label with : "; - validateJsonExceptionContent(response, expectedmessage); + + " label with : "; + validateJsonExceptionContent(response, expectedMessage); } private void validateJsonExceptionContent(ClientResponse response, - String expectedmessage) + String expectedMessage) throws JSONException { Assert.assertEquals(BAD_REQUEST_CODE, response.getStatus()); JSONObject msg = response.getEntity(JSONObject.class); @@ -653,112 +599,76 @@ private void validateJsonExceptionContent(ClientResponse response, WebServicesTestUtils.checkStringMatch("exception classname", "org.apache.hadoop.yarn.webapp.BadRequestException", classname); WebServicesTestUtils.checkStringContains("exception message", - expectedmessage, message); + expectedMessage, message); } @Test public void testLabelInvalidReplace() - throws UniformInterfaceException, Exception { - WebResource r = resource(); + throws Exception { ClientResponse response; - // replace label which doesnt exist - MultivaluedMapImpl params = new MultivaluedMapImpl(); - params.add("labels", "idontexist"); - response = r.path("ws").path("v1").path("cluster").path("nodes") - .path("nid:0").path("replace-labels").queryParam("user.name", userName) - .queryParams(params).accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); + // replace label which doesn't exist + response = replaceLabelsOnNode(NODE_0, "idontexist"); - String expectedmessage = + String expectedMessage = "Not all labels being replaced contained by known label" + " collections, please check, new labels=[idontexist]"; - validateJsonExceptionContent(response, expectedmessage); + validateJsonExceptionContent(response, expectedMessage); } @Test public void testLabelInvalidRemove() - throws UniformInterfaceException, Exception { - WebResource r = resource(); + throws Exception { ClientResponse response; - MultivaluedMapImpl params = new MultivaluedMapImpl(); - params.add("labels", "irealldontexist"); - response = - r.path("ws").path("v1").path("cluster").path("remove-node-labels") - .queryParam("user.name", userName).queryParams(params) - .accept(MediaType.APPLICATION_JSON).post(ClientResponse.class); - String expectedmessage = - "java.io.IOException: Node label=irealldontexist to be" + response = removeNodeLabel("ireallydontexist"); + String expectedMessage = + "java.io.IOException: Node label=ireallydontexist to be" + " removed doesn't existed in cluster node labels" + " collection."; - validateJsonExceptionContent(response, expectedmessage); + validateJsonExceptionContent(response, expectedMessage); } @Test public void testNodeLabelPartitionInfo() throws Exception { - WebResource r = resource(); - ClientResponse response; // Add a node label - NodeLabelsInfo nlsifo = new NodeLabelsInfo(); - nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("a")); - 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) - .post(ClientResponse.class); + response = addNodeLabels(Lists.newArrayList(Pair.of(LABEL_A, DEFAULT_NL_EXCLUSIVITY))); + assertHttp200(response); // Verify partition info in get-node-labels - response = - r.path("ws").path("v1").path("cluster") - .path("get-node-labels").queryParam("user.name", userName) - .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()); + response = getNodeLabels(); + assertApplicationJsonUtf8Response(response); + NodeLabelsInfo nodeLabelsInfo = response.getEntity(NodeLabelsInfo.class); + assertNodeLabelsSize(nodeLabelsInfo, 1); + for (NodeLabelInfo nl : nodeLabelsInfo.getNodeLabelsInfo()) { + assertEquals(LABEL_A, nl.getName()); assertTrue(nl.getExclusivity()); assertNotNull(nl.getPartitionInfo()); assertNotNull(nl.getPartitionInfo().getResourceAvailable()); } // Add node label to a node - MultivaluedMapImpl params = new MultivaluedMapImpl(); - params.add("labels", "a"); - response = - r.path("ws").path("v1").path("cluster") - .path("nodes").path("nodeId:0") - .path("replace-labels") - .queryParam("user.name", userName) - .queryParams(params) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); + response = replaceLabelsOnNode("nodeId:0", LABEL_A); + assertHttp200(response); // Verify partition info in label-mappings - response = - r.path("ws").path("v1").path("cluster") - .path("label-mappings").queryParam("user.name", userName) - .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class); - assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8, - response.getType().toString()); - LabelsToNodesInfo ltni = response.getEntity(LabelsToNodesInfo.class); - assertEquals(1, ltni.getLabelsToNodes().size()); - NodeIDsInfo nodes = ltni.getLabelsToNodes().get( - new NodeLabelInfo("a")); - assertTrue(nodes.getNodeIDs().contains("nodeId:0")); + response = getNodeLabelMappings(); + assertApplicationJsonUtf8Response(response); + LabelsToNodesInfo labelsToNodesInfo = response.getEntity(LabelsToNodesInfo.class); + assertLabelsToNodesInfo(labelsToNodesInfo, 1, Lists.newArrayList( + Pair.of(Pair.of(LABEL_A, DEFAULT_NL_EXCLUSIVITY), Lists.newArrayList("nodeId:0")) + )); + NodeIDsInfo nodes = labelsToNodesInfo.getLabelsToNodes().get(new NodeLabelInfo(LABEL_A)); assertNotNull(nodes.getPartitionInfo()); assertNotNull(nodes.getPartitionInfo().getResourceAvailable()); } @SuppressWarnings("rawtypes") - private String toJson(Object nsli, Class klass) throws Exception { + private String toJson(Object obj, Class klass) throws Exception { StringWriter sw = new StringWriter(); JSONJAXBContext ctx = new JSONJAXBContext(klass); JSONMarshaller jm = ctx.createJSONMarshaller(); - jm.marshallToJSON(nsli, sw); + jm.marshallToJSON(obj, sw); return sw.toString(); } }