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

This commit is contained in:
Wangda Tan 2015-05-13 13:43:17 -07:00
parent d4f53fc963
commit 7f19e7a254
10 changed files with 428 additions and 135 deletions

View File

@ -233,6 +233,11 @@ Release 2.8.0 - UNRELEASED
YARN-3613. TestContainerManagerSecurity should init and start Yarn cluster in YARN-3613. TestContainerManagerSecurity should init and start Yarn cluster in
setup instead of individual methods. (nijel via kasha) 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 OPTIMIZATIONS
YARN-3339. TestDockerContainerExecutor should pull a single image and not YARN-3339. TestDockerContainerExecutor should pull a single image and not
@ -420,9 +425,6 @@ Release 2.7.1 - UNRELEASED
YARN-3539. Updated timeline server documentation and marked REST APIs evolving. YARN-3539. Updated timeline server documentation and marked REST APIs evolving.
(Steve Loughran via zjshen) (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 OPTIMIZATIONS
BUG FIXES BUG FIXES

View File

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

View File

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

View File

@ -31,13 +31,13 @@
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
public class LabelsToNodesInfo { public class LabelsToNodesInfo {
protected Map<String, NodeIDsInfo> labelsToNodes = protected Map<NodeLabelInfo, NodeIDsInfo> labelsToNodes =
new HashMap<String, NodeIDsInfo>(); new HashMap<NodeLabelInfo, NodeIDsInfo>();
public LabelsToNodesInfo() { public LabelsToNodesInfo() {
} // JAXB needs this } // JAXB needs this
public Map<String, NodeIDsInfo> getLabelsToNodes() { public Map<NodeLabelInfo, NodeIDsInfo> getLabelsToNodes() {
return labelsToNodes; 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 javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import org.apache.hadoop.yarn.api.records.NodeLabel;
@XmlRootElement(name = "nodeLabelsInfo") @XmlRootElement(name = "nodeLabelsInfo")
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
public class NodeLabelsInfo { public class NodeLabelsInfo {
protected ArrayList<String> nodeLabels = new ArrayList<String>(); @XmlElement(name = "nodeLabelInfo")
private ArrayList<NodeLabelInfo> nodeLabelsInfo =
new ArrayList<NodeLabelInfo>();
public NodeLabelsInfo() { public NodeLabelsInfo() {
} // JAXB needs this // JAXB needs this
}
public NodeLabelsInfo(ArrayList<String> nodeLabels) {
this.nodeLabels = nodeLabels; 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) { public NodeLabelsInfo(Set<String> nodeLabelsName) {
this.nodeLabels = new ArrayList<String>(nodeLabelsSet); 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; return nodeLabels;
} }
public void setNodeLabels(ArrayList<String> nodeLabels) { public List<String> getNodeLabelsName() {
this.nodeLabels = nodeLabels; 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 @@
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
public class NodeToLabelsInfo { public class NodeToLabelsInfo {
protected HashMap<String, NodeLabelsInfo> nodeToLabels = private HashMap<String, NodeLabelsInfo> nodeToLabels =
new HashMap<String, NodeLabelsInfo>(); new HashMap<String, NodeLabelsInfo>();
public NodeToLabelsInfo() { public NodeToLabelsInfo() {
} // JAXB needs this // JAXB needs this
}
public HashMap<String, NodeLabelsInfo> getNodeToLabels() {
return nodeToLabels; public HashMap<String, NodeLabelsInfo> getNodeToLabels() {
return nodeToLabels;
} }
} }

View File

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