YARN-3521. Support return structured NodeLabel objects in REST API (Sunil G via wangda)

(cherry picked from commit 7f19e7a254)
This commit is contained in:
Wangda Tan 2015-05-13 13:43:17 -07:00
parent 8555a5146d
commit d49262a172
10 changed files with 428 additions and 135 deletions

View File

@ -188,6 +188,11 @@ Release 2.8.0 - UNRELEASED
YARN-3613. TestContainerManagerSecurity should init and start Yarn cluster in
setup instead of individual methods. (nijel via kasha)
YARN-3579. CommonNodeLabelsManager should support NodeLabel instead of string
label name when getting node-to-label/label-to-label mappings. (Sunil G via wangda)
YARN-3521. Support return structured NodeLabel objects in REST API (Sunil G via wangda)
OPTIMIZATIONS
YARN-3339. TestDockerContainerExecutor should pull a single image and not
@ -375,9 +380,6 @@ Release 2.7.1 - UNRELEASED
YARN-3539. Updated timeline server documentation and marked REST APIs evolving.
(Steve Loughran via zjshen)
YARN-3579. CommonNodeLabelsManager should support NodeLabel instead of string
label name when getting node-to-label/label-to-label mappings. (Sunil G via wangda)
OPTIMIZATIONS
BUG FIXES

View File

@ -23,6 +23,7 @@ import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "labelsToNodesInfo")
@ -32,6 +33,7 @@ public class NodeIDsInfo {
/**
* Set doesn't support default no arg constructor which is req by JAXB
*/
@XmlElement(name="nodes")
protected ArrayList<String> nodeIDsList = new ArrayList<String>();
public NodeIDsInfo() {

View File

@ -93,6 +93,7 @@ import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
import org.apache.hadoop.yarn.api.records.LocalResource;
import org.apache.hadoop.yarn.api.records.NodeId;
import org.apache.hadoop.yarn.api.records.NodeLabel;
import org.apache.hadoop.yarn.api.records.NodeState;
import org.apache.hadoop.yarn.api.records.Priority;
import org.apache.hadoop.yarn.api.records.QueueACL;
@ -135,8 +136,11 @@ import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.LabelsToNodesInf
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.LocalResourceInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NewApplication;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeLabelInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeLabelsInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeToLabelsEntry;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeToLabelsInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeToLabelsEntryList;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodesInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ResourceInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.SchedulerInfo;
@ -796,18 +800,18 @@ public class RMWebServices {
@GET
@Path("/get-node-to-labels")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public NodeToLabelsInfo getNodeToLabels(@Context HttpServletRequest hsr)
throws IOException {
public NodeToLabelsInfo getNodeToLabels(@Context HttpServletRequest hsr)
throws IOException {
init();
NodeToLabelsInfo ntl = new NodeToLabelsInfo();
HashMap<String, NodeLabelsInfo> ntlMap = ntl.getNodeToLabels();
Map<NodeId, Set<String>> nodeIdToLabels =
rm.getRMContext().getNodeLabelManager().getNodeLabels();
Map<NodeId, Set<String>> nodeIdToLabels = rm.getRMContext()
.getNodeLabelManager().getNodeLabels();
for (Map.Entry<NodeId, Set<String>> nitle : nodeIdToLabels.entrySet()) {
ntlMap.put(nitle.getKey().toString(),
new NodeLabelsInfo(nitle.getValue()));
ntlMap.put(nitle.getKey().toString(),
new NodeLabelsInfo(nitle.getValue()));
}
return ntl;
@ -821,7 +825,7 @@ public class RMWebServices {
init();
LabelsToNodesInfo lts = new LabelsToNodesInfo();
Map<String, NodeIDsInfo> ltsMap = lts.getLabelsToNodes();
Map<NodeLabelInfo, NodeIDsInfo> ltsMap = lts.getLabelsToNodes();
Map<String, Set<NodeId>> labelsToNodeId = null;
if (labels == null || labels.size() == 0) {
labelsToNodeId =
@ -836,7 +840,8 @@ public class RMWebServices {
for (NodeId nodeId : entry.getValue()) {
nodeIdStrList.add(nodeId.toString());
}
ltsMap.put(entry.getKey(), new NodeIDsInfo(nodeIdStrList));
ltsMap.put(new NodeLabelInfo(entry.getKey()), new NodeIDsInfo(
nodeIdStrList));
}
return lts;
}
@ -844,16 +849,15 @@ public class RMWebServices {
@POST
@Path("/replace-node-to-labels")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response replaceLabelsOnNodes(final NodeToLabelsInfo newNodeToLabels,
public Response replaceLabelsOnNodes(final NodeToLabelsEntryList newNodeToLabels,
@Context HttpServletRequest hsr) throws IOException {
Map<NodeId, Set<String>> nodeIdToLabels =
new HashMap<NodeId, Set<String>>();
for (Map.Entry<String, NodeLabelsInfo> nitle : newNodeToLabels
.getNodeToLabels().entrySet()) {
for (NodeToLabelsEntry nitle : newNodeToLabels.getNodeToLabels()) {
nodeIdToLabels.put(
ConverterUtils.toNodeIdWithDefaultPort(nitle.getKey()),
new HashSet<String>(nitle.getValue().getNodeLabels()));
ConverterUtils.toNodeIdWithDefaultPort(nitle.getNodeId()),
new HashSet<String>(nitle.getNodeLabels()));
}
return replaceLabelsOnNode(nodeIdToLabels, hsr, "/replace-node-to-labels");
@ -862,16 +866,18 @@ public class RMWebServices {
@POST
@Path("/nodes/{nodeId}/replace-labels")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response replaceLabelsOnNode(NodeLabelsInfo newNodeLabelsInfo,
public Response replaceLabelsOnNode(
@QueryParam("labels") Set<String> newNodeLabelsName,
@Context HttpServletRequest hsr, @PathParam("nodeId") String nodeId)
throws Exception {
NodeId nid = ConverterUtils.toNodeIdWithDefaultPort(nodeId);
Map<NodeId, Set<String>> newLabelsForNode =
new HashMap<NodeId, Set<String>>();
newLabelsForNode.put(nid,
new HashSet<String>(newNodeLabelsInfo.getNodeLabels()));
new HashSet<String>(newNodeLabelsName));
return replaceLabelsOnNode(newLabelsForNode, hsr, "/nodes/nodeid/replace-labels");
return replaceLabelsOnNode(newLabelsForNode, hsr,
"/nodes/nodeid/replace-labels");
}
private Response replaceLabelsOnNode(
@ -909,9 +915,9 @@ public class RMWebServices {
throws IOException {
init();
NodeLabelsInfo ret =
new NodeLabelsInfo(rm.getRMContext().getNodeLabelManager()
.getClusterNodeLabelNames());
List<NodeLabel> nodeLabels = rm.getRMContext().getNodeLabelManager()
.getClusterNodeLabels();
NodeLabelsInfo ret = new NodeLabelsInfo(nodeLabels);
return ret;
}
@ -937,8 +943,7 @@ public class RMWebServices {
}
rm.getRMContext().getNodeLabelManager()
.addToCluserNodeLabelsWithDefaultExclusivity(new HashSet<String>(
newNodeLabels.getNodeLabels()));
.addToCluserNodeLabels(newNodeLabels.getNodeLabels());
return Response.status(Status.OK).build();
@ -947,29 +952,29 @@ public class RMWebServices {
@POST
@Path("/remove-node-labels")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response removeFromCluserNodeLabels(final NodeLabelsInfo oldNodeLabels,
@Context HttpServletRequest hsr)
throws Exception {
public Response removeFromCluserNodeLabels(
@QueryParam("labels") Set<String> oldNodeLabels,
@Context HttpServletRequest hsr) throws Exception {
init();
UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true);
if (callerUGI == null) {
String msg = "Unable to obtain user name, user not authenticated for"
+ " post to .../remove-node-labels";
+ " post to .../remove-node-labels";
throw new AuthorizationException(msg);
}
if (!rm.getRMContext().getNodeLabelManager().checkAccess(callerUGI)) {
String msg = "User " + callerUGI.getShortUserName() + " not authorized"
+ " for post to .../remove-node-labels ";
+ " for post to .../remove-node-labels ";
throw new AuthorizationException(msg);
}
rm.getRMContext().getNodeLabelManager()
.removeFromClusterNodeLabels(new HashSet<String>(
oldNodeLabels.getNodeLabels()));
return Response.status(Status.OK).build();
rm.getRMContext()
.getNodeLabelManager()
.removeFromClusterNodeLabels(
new HashSet<String>(oldNodeLabels));
return Response.status(Status.OK).build();
}
@GET

View File

@ -31,13 +31,13 @@ import org.apache.hadoop.yarn.server.resourcemanager.webapp.NodeIDsInfo;
@XmlAccessorType(XmlAccessType.FIELD)
public class LabelsToNodesInfo {
protected Map<String, NodeIDsInfo> labelsToNodes =
new HashMap<String, NodeIDsInfo>();
protected Map<NodeLabelInfo, NodeIDsInfo> labelsToNodes =
new HashMap<NodeLabelInfo, NodeIDsInfo>();
public LabelsToNodesInfo() {
} // JAXB needs this
public Map<String, NodeIDsInfo> getLabelsToNodes() {
public Map<NodeLabelInfo, NodeIDsInfo> getLabelsToNodes() {
return labelsToNodes;
}
}

View File

@ -0,0 +1,86 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* 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
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.yarn.server.resourcemanager.webapp.dao;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.hadoop.yarn.api.records.NodeLabel;
@XmlRootElement(name = "nodeLabelInfo")
@XmlAccessorType(XmlAccessType.FIELD)
public class NodeLabelInfo {
private String name;
private boolean exclusivity;
public NodeLabelInfo() {
// JAXB needs this
}
public NodeLabelInfo(String name) {
this.name = name;
this.exclusivity = true;
}
public NodeLabelInfo(String name, boolean exclusivity) {
this.name = name;
this.exclusivity = exclusivity;
}
public NodeLabelInfo(NodeLabel label) {
this.name = label.getName();
this.exclusivity = label.isExclusive();
}
public String getName() {
return name;
}
public boolean getExclusivity() {
return exclusivity;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
NodeLabelInfo other = (NodeLabelInfo) obj;
if (!getName().equals(other.getName())) {
return false;
}
if (getExclusivity() != other.getExclusivity()) {
return false;
}
return true;
}
@Override
public int hashCode() {
return (getName().hashCode() << 16) + (getExclusivity() ? 1 : 0);
}
}

View File

@ -22,31 +22,63 @@ import java.util.*;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.hadoop.yarn.api.records.NodeLabel;
@XmlRootElement(name = "nodeLabelsInfo")
@XmlAccessorType(XmlAccessType.FIELD)
public class NodeLabelsInfo {
protected ArrayList<String> nodeLabels = new ArrayList<String>();
@XmlElement(name = "nodeLabelInfo")
private ArrayList<NodeLabelInfo> nodeLabelsInfo =
new ArrayList<NodeLabelInfo>();
public NodeLabelsInfo() {
} // JAXB needs this
public NodeLabelsInfo(ArrayList<String> nodeLabels) {
this.nodeLabels = nodeLabels;
// JAXB needs this
}
public NodeLabelsInfo(ArrayList<NodeLabelInfo> nodeLabels) {
this.nodeLabelsInfo = nodeLabels;
}
public NodeLabelsInfo(List<NodeLabel> nodeLabels) {
this.nodeLabelsInfo = new ArrayList<NodeLabelInfo>();
for (NodeLabel label : nodeLabels) {
this.nodeLabelsInfo.add(new NodeLabelInfo(label));
}
}
public NodeLabelsInfo(Set<String> nodeLabelsSet) {
this.nodeLabels = new ArrayList<String>(nodeLabelsSet);
public NodeLabelsInfo(Set<String> nodeLabelsName) {
this.nodeLabelsInfo = new ArrayList<NodeLabelInfo>();
for (String labelName : nodeLabelsName) {
this.nodeLabelsInfo.add(new NodeLabelInfo(labelName));
}
}
public ArrayList<String> getNodeLabels() {
public ArrayList<NodeLabelInfo> getNodeLabelsInfo() {
return nodeLabelsInfo;
}
public Set<NodeLabel> getNodeLabels() {
Set<NodeLabel> nodeLabels = new HashSet<NodeLabel>();
for (NodeLabelInfo label : nodeLabelsInfo) {
nodeLabels.add(NodeLabel.newInstance(label.getName(),
label.getExclusivity()));
}
return nodeLabels;
}
public void setNodeLabels(ArrayList<String> nodeLabels) {
this.nodeLabels = nodeLabels;
public List<String> getNodeLabelsName() {
ArrayList<String> nodeLabelsName = new ArrayList<String>();
for (NodeLabelInfo label : nodeLabelsInfo) {
nodeLabelsName.add(label.getName());
}
return nodeLabelsName;
}
public void setNodeLabelsInfo(ArrayList<NodeLabelInfo> nodeLabelInfo) {
this.nodeLabelsInfo = nodeLabelInfo;
}
}

View File

@ -0,0 +1,54 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* 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
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.yarn.server.resourcemanager.webapp.dao;
import java.util.*;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;
@XmlRootElement(name = "nodeToLabelsEntry")
@XmlAccessorType(XmlAccessType.FIELD)
public class NodeToLabelsEntry {
@XmlElement(name = "nodeId")
private String nodeId;
@XmlElement(name = "labels")
private ArrayList<String> labels = new ArrayList<String>();
public NodeToLabelsEntry() {
// JAXB needs this
}
public NodeToLabelsEntry(String nodeId, ArrayList<String> labels) {
this.nodeId = nodeId;
this.labels = labels;
}
public String getNodeId() {
return nodeId;
}
public ArrayList<String> getNodeLabels() {
return labels;
}
}

View File

@ -0,0 +1,41 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* 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
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.yarn.server.resourcemanager.webapp.dao;
import java.util.*;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "nodeToLabelsName")
@XmlAccessorType(XmlAccessType.FIELD)
public class NodeToLabelsEntryList {
protected ArrayList<NodeToLabelsEntry> nodeToLabels =
new ArrayList<NodeToLabelsEntry>();
public NodeToLabelsEntryList() {
// JAXB needs this
}
public ArrayList<NodeToLabelsEntry> getNodeToLabels() {
return nodeToLabels;
}
}

View File

@ -28,14 +28,14 @@ import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
public class NodeToLabelsInfo {
protected HashMap<String, NodeLabelsInfo> nodeToLabels =
new HashMap<String, NodeLabelsInfo>();
private HashMap<String, NodeLabelsInfo> nodeToLabels =
new HashMap<String, NodeLabelsInfo>();
public NodeToLabelsInfo() {
} // JAXB needs this
public HashMap<String, NodeLabelsInfo> getNodeToLabels() {
return nodeToLabels;
// JAXB needs this
}
public HashMap<String, NodeLabelsInfo> getNodeToLabels() {
return nodeToLabels;
}
}

View File

@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import javax.ws.rs.core.MediaType;
@ -34,13 +35,14 @@ import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.server.resourcemanager.MockRM;
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.LabelsToNodesInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeLabelInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeLabelsInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeToLabelsEntry;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeToLabelsInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeToLabelsEntryList;
import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
import org.apache.hadoop.yarn.webapp.JerseyTestBase;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.junit.Test;
import com.google.inject.Guice;
@ -113,15 +115,15 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
WebResource r = resource();
ClientResponse response;
JSONObject json;
JSONArray jarr;
// 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("{\"nodeLabels\":\"a\"}", MediaType.APPLICATION_JSON)
.entity(toJson(nlsifo, NodeLabelsInfo.class), MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
// Verify
@ -130,15 +132,18 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("get-node-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
json = response.getEntity(JSONObject.class);
assertEquals("a", json.getString("nodeLabels"));
nlsifo = response.getEntity(NodeLabelsInfo.class);
assertEquals("a", nlsifo.getNodeLabelsInfo().get(0).getName());
assertEquals(1, nlsifo.getNodeLabels().size());
// Add another
nlsifo = new NodeLabelsInfo();
nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("b"));
response =
r.path("ws").path("v1").path("cluster")
.path("add-node-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON)
.entity("{\"nodeLabels\":\"b\"}", MediaType.APPLICATION_JSON)
.entity(toJson(nlsifo, NodeLabelsInfo.class), MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
// Verify
@ -147,43 +152,45 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("get-node-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
json = response.getEntity(JSONObject.class);
jarr = json.getJSONArray("nodeLabels");
assertEquals(2, jarr.length());
nlsifo = response.getEntity(NodeLabelsInfo.class);
assertEquals(2, nlsifo.getNodeLabels().size());
// 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)
.entity("{\"nodeLabels\": [\"a\"]}",
MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
LOG.info("posted node nodelabel");
// 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)
.entity("{\"nodeLabels\": [\"b\"]}",
MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
LOG.info("posted node nodelabel");
// 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)
.entity("{\"nodeLabels\": [\"b\"]}",
MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
LOG.info("posted node nodelabel");
@ -195,14 +202,14 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
LabelsToNodesInfo ltni = response.getEntity(LabelsToNodesInfo.class);
assertEquals(2, ltni.getLabelsToNodes().size());
NodeIDsInfo nodes = ltni.getLabelsToNodes().get("b");
NodeIDsInfo nodes = ltni.getLabelsToNodes().get(new NodeLabelInfo("b"));
assertTrue(nodes.getNodeIDs().contains("nid2:0"));
assertTrue(nodes.getNodeIDs().contains("nid1:0"));
nodes = ltni.getLabelsToNodes().get("a");
nodes = ltni.getLabelsToNodes().get(new NodeLabelInfo("a"));
assertTrue(nodes.getNodeIDs().contains("nid:0"));
// Verify, using get-labels-to-Nodes for specifiedset of labels
MultivaluedMapImpl params = new MultivaluedMapImpl();
// 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")
@ -213,7 +220,7 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
ltni = response.getEntity(LabelsToNodesInfo.class);
assertEquals(1, ltni.getLabelsToNodes().size());
nodes = ltni.getLabelsToNodes().get("a");
nodes = ltni.getLabelsToNodes().get(new NodeLabelInfo("a"));
assertTrue(nodes.getNodeIDs().contains("nid:0"));
// Verify
@ -223,18 +230,20 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("get-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
json = response.getEntity(JSONObject.class);
assertEquals("a", json.getString("nodeLabels"));
nlsifo = response.getEntity(NodeLabelsInfo.class);
assertTrue(nlsifo.getNodeLabelsName().contains("a"));
// 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)
.entity("{\"nodeLabels\":\"b\"}", MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
LOG.info("posted node nodelabel");
@ -245,20 +254,21 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("get-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
json = response.getEntity(JSONObject.class);
assertEquals("b", json.getString("nodeLabels"));
nlsifo = response.getEntity(NodeLabelsInfo.class);
assertTrue(nlsifo.getNodeLabelsName().contains("b"));
// Replace labels using node-to-labels
NodeToLabelsInfo ntli = new NodeToLabelsInfo();
NodeLabelsInfo nli = new NodeLabelsInfo();
nli.getNodeLabels().add("a");
ntli.getNodeToLabels().put("nid:0", nli);
NodeToLabelsEntryList ntli = new NodeToLabelsEntryList();
ArrayList<String> labels = new ArrayList<String>();
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, NodeToLabelsInfo.class),
.entity(toJson(ntli, NodeToLabelsEntryList.class),
MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
@ -268,19 +278,21 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("get-node-to-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
ntli = response.getEntity(NodeToLabelsInfo.class);
nli = ntli.getNodeToLabels().get("nid:0");
assertEquals(1, nli.getNodeLabels().size());
assertTrue(nli.getNodeLabels().contains("a"));
NodeToLabelsInfo ntlinfo = response.getEntity(NodeToLabelsInfo.class);
NodeLabelsInfo nlinfo = ntlinfo.getNodeToLabels().get("nid:0");
assertEquals(1, nlinfo.getNodeLabels().size());
assertTrue(nlinfo.getNodeLabelsName().contains("a"));
// 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)
.entity("{\"nodeLabels\"}", MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
LOG.info("posted node nodelabel");
// Verify
@ -290,18 +302,19 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("get-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
json = response.getEntity(JSONObject.class);
assertEquals("", json.getString("nodeLabels"));
nlsifo = response.getEntity(NodeLabelsInfo.class);
assertTrue(nlsifo.getNodeLabelsName().contains(""));
// 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)
.entity("{\"nodeLabels\": \"a\"}",
MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
LOG.info("posted node nodelabel");
@ -312,18 +325,19 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("get-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
json = response.getEntity(JSONObject.class);
assertEquals("a", json.getString("nodeLabels"));
nlsifo = response.getEntity(NodeLabelsInfo.class);
assertTrue(nlsifo.getNodeLabelsName().contains("a"));
// 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)
.entity("{\"nodeLabels\": [\"b\"]}",
MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
// Verify
response =
@ -332,8 +346,8 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("get-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
json = response.getEntity(JSONObject.class);
assertEquals("a", json.getString("nodeLabels"));
nlsifo = response.getEntity(NodeLabelsInfo.class);
assertTrue(nlsifo.getNodeLabelsName().contains("a"));
// Fail to add a label with post
response =
@ -349,17 +363,18 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("get-node-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
json = response.getEntity(JSONObject.class);
jarr = json.getJSONArray("nodeLabels");
assertEquals(2, jarr.length());
nlsifo = response.getEntity(NodeLabelsInfo.class);
assertEquals(2, nlsifo.getNodeLabels().size());
// 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)
.entity("{\"nodeLabels\":\"b\"}", MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
// Verify
response =
@ -367,17 +382,19 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("get-node-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
json = response.getEntity(JSONObject.class);
assertEquals("a", json.getString("nodeLabels"));
nlsifo = response.getEntity(NodeLabelsInfo.class);
assertEquals("a", nlsifo.getNodeLabelsInfo().get(0).getName());
assertEquals(1, nlsifo.getNodeLabels().size());
// 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)
.entity("{\"nodeLabels\":\"a\"}", MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
// Verify
response =
@ -385,12 +402,15 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("get-node-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
String res = response.getEntity(String.class);
assertTrue(res.equals("null"));
nlsifo = response.getEntity(NodeLabelsInfo.class);
assertEquals(0, nlsifo.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"));
nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("y"));
response =
r.path("ws")
.path("v1")
@ -398,14 +418,18 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("add-node-labels")
.queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON)
.entity("{\"nodeLabels\":[\"x\",\"y\"]}",
.entity(toJson(nlsifo, NodeLabelsInfo.class),
MediaType.APPLICATION_JSON).post(ClientResponse.class);
// Reset for testing : Add labels to a node
nlsifo = new NodeLabelsInfo();
nlsifo.getNodeLabelsInfo().add(new NodeLabelInfo("y"));
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)
.entity("{\"nodeLabels\": [\"y\"]}", MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
LOG.info("posted node nodelabel");
@ -413,10 +437,11 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
rmWebService.isDistributedNodeLabelConfiguration = true;
// Case1 : Replace labels using node-to-labels
ntli = new NodeToLabelsInfo();
nli = new NodeLabelsInfo();
nli.getNodeLabels().add("x");
ntli.getNodeToLabels().put("nid:0", nli);
ntli = new NodeToLabelsEntryList();
labels = new ArrayList<String>();
labels.add("x");
nli = new NodeToLabelsEntry("nid:0", labels);
ntli.getNodeToLabels().add(nli);
response =
r.path("ws")
.path("v1")
@ -424,7 +449,7 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("replace-node-to-labels")
.queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON)
.entity(toJson(ntli, NodeToLabelsInfo.class),
.entity(toJson(ntli, NodeToLabelsEntryList.class),
MediaType.APPLICATION_JSON).post(ClientResponse.class);
// Verify, using node-to-labels that previous operation has failed
@ -433,17 +458,17 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
ntli = response.getEntity(NodeToLabelsInfo.class);
nli = ntli.getNodeToLabels().get("nid:0");
assertEquals(1, nli.getNodeLabels().size());
assertFalse(nli.getNodeLabels().contains("x"));
ntlinfo = response.getEntity(NodeToLabelsInfo.class);
nlinfo = ntlinfo.getNodeToLabels().get("nid:0");
assertEquals(1, nlinfo.getNodeLabels().size());
assertFalse(nlinfo.getNodeLabels().contains("x"));
// 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("{\"nodeLabels\": [\"x\"]}", MediaType.APPLICATION_JSON)
.entity("{\"nodeLabelName\": [\"x\"]}", MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
LOG.info("posted node nodelabel");
@ -453,18 +478,20 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
ntli = response.getEntity(NodeToLabelsInfo.class);
nli = ntli.getNodeToLabels().get("nid:0");
assertEquals(1, nli.getNodeLabels().size());
assertFalse(nli.getNodeLabels().contains("x"));
ntlinfo = response.getEntity(NodeToLabelsInfo.class);
nlinfo = ntlinfo.getNodeToLabels().get("nid:0");
assertEquals(1, nlinfo.getNodeLabels().size());
assertFalse(nlinfo.getNodeLabels().contains("x"));
// Case3 : Remove cluster label should be successfull
// 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)
.entity("{\"nodeLabels\":\"x\"}", MediaType.APPLICATION_JSON)
.post(ClientResponse.class);
// Verify
response =
@ -472,8 +499,52 @@ public class TestRMWebServicesNodeLabels extends JerseyTestBase {
.path("get-node-labels").queryParam("user.name", userName)
.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
json = response.getEntity(JSONObject.class);
assertEquals("y", json.getString("nodeLabels"));
nlsifo = response.getEntity(NodeLabelsInfo.class);
assertEquals("y", nlsifo.getNodeLabelsInfo().get(0).getName());
// 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);
// 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, response.getType());
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);
// 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, response.getType());
nlsifo = response.getEntity(NodeLabelsInfo.class);
assertEquals("z", nlsifo.getNodeLabelsInfo().get(0).getName());
assertEquals(false, nlsifo.getNodeLabelsInfo().get(0).getExclusivity());
assertEquals(1, nlsifo.getNodeLabels().size());
}
@SuppressWarnings("rawtypes")