Repository: hadoop
Updated Branches:
  refs/heads/trunk d4f53fc96 -> 7f19e7a25


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


Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/7f19e7a2
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/7f19e7a2
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/7f19e7a2

Branch: refs/heads/trunk
Commit: 7f19e7a2549a098236d06b29b7076bb037533f05
Parents: d4f53fc
Author: Wangda Tan <wan...@apache.org>
Authored: Wed May 13 13:43:17 2015 -0700
Committer: Wangda Tan <wan...@apache.org>
Committed: Wed May 13 13:43:17 2015 -0700

----------------------------------------------------------------------
 hadoop-yarn-project/CHANGES.txt                 |   8 +-
 .../resourcemanager/webapp/NodeIDsInfo.java     |   2 +
 .../resourcemanager/webapp/RMWebServices.java   |  71 +++---
 .../webapp/dao/LabelsToNodesInfo.java           |   6 +-
 .../webapp/dao/NodeLabelInfo.java               |  86 +++++++
 .../webapp/dao/NodeLabelsInfo.java              |  56 ++++-
 .../webapp/dao/NodeToLabelsEntry.java           |  54 +++++
 .../webapp/dao/NodeToLabelsEntryList.java       |  41 ++++
 .../webapp/dao/NodeToLabelsInfo.java            |  12 +-
 .../webapp/TestRMWebServicesNodeLabels.java     | 225 ++++++++++++-------
 10 files changed, 427 insertions(+), 134 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/7f19e7a2/hadoop-yarn-project/CHANGES.txt
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt
index 16c2dd9..38f5e81 100644
--- a/hadoop-yarn-project/CHANGES.txt
+++ b/hadoop-yarn-project/CHANGES.txt
@@ -233,6 +233,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
@@ -420,9 +425,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

http://git-wip-us.apache.org/repos/asf/hadoop/blob/7f19e7a2/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NodeIDsInfo.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NodeIDsInfo.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NodeIDsInfo.java
index 39d636d..c23b02a 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NodeIDsInfo.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/NodeIDsInfo.java
@@ -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() {

http://git-wip-us.apache.org/repos/asf/hadoop/blob/7f19e7a2/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java
index 4ce2b54..a0a3123 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMWebServices.java
@@ -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

http://git-wip-us.apache.org/repos/asf/hadoop/blob/7f19e7a2/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/LabelsToNodesInfo.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/LabelsToNodesInfo.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/LabelsToNodesInfo.java
index 625fedd..41dd410 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/LabelsToNodesInfo.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/LabelsToNodesInfo.java
@@ -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;
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/7f19e7a2/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeLabelInfo.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeLabelInfo.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeLabelInfo.java
new file mode 100644
index 0000000..e507c46
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeLabelInfo.java
@@ -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);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/7f19e7a2/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeLabelsInfo.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeLabelsInfo.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeLabelsInfo.java
index 1cb895a..2c3a8a5 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeLabelsInfo.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeLabelsInfo.java
@@ -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(Set<String> nodeLabelsSet) {
-   this.nodeLabels = new ArrayList<String>(nodeLabelsSet); 
+
+  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 ArrayList<String> getNodeLabels() {
+  public NodeLabelsInfo(Set<String> nodeLabelsName) {
+    this.nodeLabelsInfo = new ArrayList<NodeLabelInfo>();
+    for (String labelName : nodeLabelsName) {
+      this.nodeLabelsInfo.add(new NodeLabelInfo(labelName));
+    }
+  }
+
+  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;
   }
-  
 }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/7f19e7a2/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsEntry.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsEntry.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsEntry.java
new file mode 100644
index 0000000..702d6f0
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsEntry.java
@@ -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;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/7f19e7a2/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsEntryList.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsEntryList.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsEntryList.java
new file mode 100644
index 0000000..dc9543e
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsEntryList.java
@@ -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;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/7f19e7a2/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsInfo.java
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsInfo.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsInfo.java
index f2e6441..0b6e4bc 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsInfo.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/NodeToLabelsInfo.java
@@ -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
-  
+    // JAXB needs this
+  }
+
   public HashMap<String, NodeLabelsInfo> getNodeToLabels() {
-   return nodeToLabels; 
+    return nodeToLabels;
   }
-  
 }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/7f19e7a2/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesNodeLabels.java
----------------------------------------------------------------------
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 2d5518d..54fe00d 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
@@ -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")

Reply via email to