Browse Source

YARN-3583. Support of NodeLabel object instead of plain String in YarnClient side. (Sunil G via wangda)

(cherry picked from commit 563eb1ad2ae848a23bbbf32ebfaf107e8fa14e87)
(cherry picked from commit b0d22b0c606fad6b4ab5443c0aed07c829b46726)
Wangda Tan 10 năm trước cách đây
mục cha
commit
b5ba6979b7
15 tập tin đã thay đổi với 226 bổ sung120 xóa
  1. 3 3
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ResourceMgrDelegate.java
  2. 3 0
      hadoop-yarn-project/CHANGES.txt
  3. 4 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/GetLabelsToNodesResponse.java
  4. 4 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/GetNodesToLabelsResponse.java
  5. 6 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/server/yarn_server_resourcemanager_service_protos.proto
  6. 3 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto
  7. 1 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto
  8. 4 4
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/YarnClient.java
  9. 3 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java
  10. 62 12
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java
  11. 18 10
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/GetLabelsToNodesResponsePBImpl.java
  12. 36 22
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/GetNodesToLabelsResponsePBImpl.java
  13. 9 9
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/server/api/protocolrecords/impl/pb/ReplaceLabelsOnNodeRequestPBImpl.java
  14. 3 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java
  15. 67 43
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java

+ 3 - 3
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ResourceMgrDelegate.java

@@ -444,19 +444,19 @@ public class ResourceMgrDelegate extends YarnClient {
   }
 
   @Override
-  public Map<NodeId, Set<String>> getNodeToLabels() throws YarnException,
+  public Map<NodeId, Set<NodeLabel>> getNodeToLabels() throws YarnException,
       IOException {
     return client.getNodeToLabels();
   }
 
   @Override
-  public Map<String, Set<NodeId>> getLabelsToNodes() throws YarnException,
+  public Map<NodeLabel, Set<NodeId>> getLabelsToNodes() throws YarnException,
       IOException {
     return client.getLabelsToNodes();
   }
 
   @Override
-  public Map<String, Set<NodeId>> getLabelsToNodes(Set<String> labels)
+  public Map<NodeLabel, Set<NodeId>> getLabelsToNodes(Set<String> labels)
       throws YarnException, IOException {
     return client.getLabelsToNodes(labels);
   }

+ 3 - 0
hadoop-yarn-project/CHANGES.txt

@@ -205,6 +205,9 @@ Release 2.8.0 - UNRELEASED
     YARN-3565. NodeHeartbeatRequest/RegisterNodeManagerRequest should use 
     NodeLabel object instead of String. (Naganarasimha G R via wangda)
 
+    YARN-3583. Support of NodeLabel object instead of plain String 
+    in YarnClient side. (Sunil G via wangda)
+
   OPTIMIZATIONS
 
     YARN-3339. TestDockerContainerExecutor should pull a single image and not

+ 4 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/GetLabelsToNodesResponse.java

@@ -24,11 +24,12 @@ import java.util.Set;
 import org.apache.hadoop.classification.InterfaceAudience.Public;
 import org.apache.hadoop.classification.InterfaceStability.Evolving;
 import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.api.records.NodeLabel;
 import org.apache.hadoop.yarn.util.Records;
 
 public abstract class GetLabelsToNodesResponse {
   public static GetLabelsToNodesResponse newInstance(
-      Map<String, Set<NodeId>> map) {
+      Map<NodeLabel, Set<NodeId>> map) {
 	GetLabelsToNodesResponse response =
         Records.newRecord(GetLabelsToNodesResponse.class);
     response.setLabelsToNodes(map);
@@ -37,9 +38,9 @@ public abstract class GetLabelsToNodesResponse {
 
   @Public
   @Evolving
-  public abstract void setLabelsToNodes(Map<String, Set<NodeId>> map);
+  public abstract void setLabelsToNodes(Map<NodeLabel, Set<NodeId>> map);
 
   @Public
   @Evolving
-  public abstract Map<String, Set<NodeId>> getLabelsToNodes();
+  public abstract Map<NodeLabel, Set<NodeId>> getLabelsToNodes();
 }

+ 4 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/GetNodesToLabelsResponse.java

@@ -24,11 +24,12 @@ import java.util.Set;
 import org.apache.hadoop.classification.InterfaceAudience.Public;
 import org.apache.hadoop.classification.InterfaceStability.Evolving;
 import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.api.records.NodeLabel;
 import org.apache.hadoop.yarn.util.Records;
 
 public abstract class GetNodesToLabelsResponse {
   public static GetNodesToLabelsResponse newInstance(
-      Map<NodeId, Set<String>> map) {
+      Map<NodeId, Set<NodeLabel>> map) {
     GetNodesToLabelsResponse response =
         Records.newRecord(GetNodesToLabelsResponse.class);
     response.setNodeToLabels(map);
@@ -37,9 +38,9 @@ public abstract class GetNodesToLabelsResponse {
 
   @Public
   @Evolving
-  public abstract void setNodeToLabels(Map<NodeId, Set<String>> map);
+  public abstract void setNodeToLabels(Map<NodeId, Set<NodeLabel>> map);
 
   @Public
   @Evolving
-  public abstract Map<NodeId, Set<String>> getNodeToLabels();
+  public abstract Map<NodeId, Set<NodeLabel>> getNodeToLabels();
 }

+ 6 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/server/yarn_server_resourcemanager_service_protos.proto

@@ -91,7 +91,7 @@ message RemoveFromClusterNodeLabelsResponseProto {
 }
 
 message ReplaceLabelsOnNodeRequestProto {
-  repeated NodeIdToLabelsProto nodeToLabels = 1;
+  repeated NodeIdToLabelsNameProto nodeToLabels = 1;
 }
 
 message ReplaceLabelsOnNodeResponseProto {
@@ -107,6 +107,11 @@ message CheckForDecommissioningNodesResponseProto {
   repeated NodeIdProto decommissioningNodes = 1;
 }
 
+message NodeIdToLabelsNameProto {
+  optional NodeIdProto nodeId = 1;
+  repeated string nodeLabels = 2;
+}
+
 enum DecommissionTypeProto {
   NORMAL = 1;
   GRACEFUL = 2;

+ 3 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto

@@ -248,13 +248,13 @@ message NodeReportProto {
   repeated string node_labels = 10;
 }
 
-message NodeIdToLabelsProto {
+message NodeIdToLabelsInfoProto {
   optional NodeIdProto nodeId = 1;
-  repeated string nodeLabels = 2;
+  repeated NodeLabelProto nodeLabels = 2;
 }
 
 message LabelsToNodeIdsProto {
-  optional string nodeLabels = 1;
+  optional NodeLabelProto nodeLabels = 1;
   repeated NodeIdProto nodeId = 2;
 }
 

+ 1 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto

@@ -198,7 +198,7 @@ message GetNodesToLabelsRequestProto {
 }
 
 message GetNodesToLabelsResponseProto {
-  repeated NodeIdToLabelsProto nodeToLabels = 1;
+  repeated NodeIdToLabelsInfoProto nodeToLabels = 1;
 }
 
 message GetLabelsToNodesRequestProto {

+ 4 - 4
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/YarnClient.java

@@ -619,7 +619,7 @@ public abstract class YarnClient extends AbstractService {
    */
   @Public
   @Unstable
-  public abstract Map<NodeId, Set<String>> getNodeToLabels()
+  public abstract Map<NodeId, Set<NodeLabel>> getNodeToLabels()
       throws YarnException, IOException;
 
   /**
@@ -634,7 +634,7 @@ public abstract class YarnClient extends AbstractService {
    */
   @Public
   @Unstable
-  public abstract Map<String, Set<NodeId>> getLabelsToNodes()
+  public abstract Map<NodeLabel, Set<NodeId>> getLabelsToNodes()
       throws YarnException, IOException;
 
   /**
@@ -650,8 +650,8 @@ public abstract class YarnClient extends AbstractService {
    */
   @Public
   @Unstable
-  public abstract Map<String, Set<NodeId>> getLabelsToNodes(Set<String> labels)
-      throws YarnException, IOException;
+  public abstract Map<NodeLabel, Set<NodeId>> getLabelsToNodes(
+      Set<String> labels) throws YarnException, IOException;
 
   /**
    * <p>

+ 3 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java

@@ -795,21 +795,21 @@ public class YarnClientImpl extends YarnClient {
   }
   
   @Override
-  public Map<NodeId, Set<String>> getNodeToLabels() throws YarnException,
+  public Map<NodeId, Set<NodeLabel>> getNodeToLabels() throws YarnException,
       IOException {
     return rmClient.getNodeToLabels(GetNodesToLabelsRequest.newInstance())
         .getNodeToLabels();
   }
 
   @Override
-  public Map<String, Set<NodeId>> getLabelsToNodes() throws YarnException,
+  public Map<NodeLabel, Set<NodeId>> getLabelsToNodes() throws YarnException,
       IOException {
     return rmClient.getLabelsToNodes(GetLabelsToNodesRequest.newInstance())
         .getLabelsToNodes();
   }
 
   @Override
-  public Map<String, Set<NodeId>> getLabelsToNodes(Set<String> labels)
+  public Map<NodeLabel, Set<NodeId>> getLabelsToNodes(Set<String> labels)
       throws YarnException, IOException {
     return rmClient.getLabelsToNodes(
         GetLabelsToNodesRequest.newInstance(labels)).getLabelsToNodes();

+ 62 - 12
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java

@@ -67,6 +67,8 @@ import org.apache.hadoop.yarn.api.protocolrecords.GetContainersRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.GetContainersResponse;
 import org.apache.hadoop.yarn.api.protocolrecords.GetLabelsToNodesRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.GetLabelsToNodesResponse;
+import org.apache.hadoop.yarn.api.protocolrecords.GetNodesToLabelsRequest;
+import org.apache.hadoop.yarn.api.protocolrecords.GetNodesToLabelsResponse;
 import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationResponse;
 import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest;
@@ -87,6 +89,7 @@ import org.apache.hadoop.yarn.api.records.ContainerReport;
 import org.apache.hadoop.yarn.api.records.ContainerState;
 import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
 import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.api.records.NodeLabel;
 import org.apache.hadoop.yarn.api.records.Priority;
 import org.apache.hadoop.yarn.api.records.ReservationDefinition;
 import org.apache.hadoop.yarn.api.records.ReservationId;
@@ -458,9 +461,9 @@ public class TestYarnClient {
     client.start();
 
     // Get labels to nodes mapping
-    Map<String, Set<NodeId>> expectedLabelsToNodes =
+    Map<NodeLabel, Set<NodeId>> expectedLabelsToNodes =
         ((MockYarnClient)client).getLabelsToNodesMap();
-    Map<String, Set<NodeId>> labelsToNodes = client.getLabelsToNodes();
+    Map<NodeLabel, Set<NodeId>> labelsToNodes = client.getLabelsToNodes();
     Assert.assertEquals(labelsToNodes, expectedLabelsToNodes);
     Assert.assertEquals(labelsToNodes.size(), 3);
 
@@ -476,7 +479,32 @@ public class TestYarnClient {
     client.close();
   }
 
+  @Test (timeout = 10000)
+  public void testGetNodesToLabels() throws YarnException, IOException {
+    Configuration conf = new Configuration();
+    final YarnClient client = new MockYarnClient();
+    client.init(conf);
+    client.start();
+
+    // Get labels to nodes mapping
+    Map<NodeId, Set<NodeLabel>> expectedNodesToLabels = ((MockYarnClient) client)
+        .getNodeToLabelsMap();
+    Map<NodeId, Set<NodeLabel>> nodesToLabels = client.getNodeToLabels();
+    Assert.assertEquals(nodesToLabels, expectedNodesToLabels);
+    Assert.assertEquals(nodesToLabels.size(), 1);
+
+    // Verify exclusivity
+    Set<NodeLabel> labels = nodesToLabels.get(NodeId.newInstance("host", 0));
+    for (NodeLabel label : labels) {
+      Assert.assertFalse(label.isExclusive());
+    }
+
+    client.stop();
+    client.close();
+  }
+
   private static class MockYarnClient extends YarnClientImpl {
+
     private ApplicationReport mockReport;
     private List<ApplicationReport> reports;
     private HashMap<ApplicationId, List<ApplicationAttemptReport>> attempts = 
@@ -498,6 +526,8 @@ public class TestYarnClient {
       mock(GetContainerReportResponse.class);
     GetLabelsToNodesResponse mockLabelsToNodesResponse =
       mock(GetLabelsToNodesResponse.class);
+    GetNodesToLabelsResponse mockNodeToLabelsResponse =
+        mock(GetNodesToLabelsResponse.class);
 
     public MockYarnClient() {
       super();
@@ -537,6 +567,9 @@ public class TestYarnClient {
         when(rmClient.getLabelsToNodes(any(GetLabelsToNodesRequest.class)))
             .thenReturn(mockLabelsToNodesResponse);
         
+        when(rmClient.getNodeToLabels(any(GetNodesToLabelsRequest.class)))
+            .thenReturn(mockNodeToLabelsResponse);
+
         historyClient = mock(AHSClient.class);
         
       } catch (YarnException e) {
@@ -704,7 +737,7 @@ public class TestYarnClient {
     }
 
     @Override
-    public Map<String, Set<NodeId>> getLabelsToNodes()
+    public Map<NodeLabel, Set<NodeId>> getLabelsToNodes()
         throws YarnException, IOException {
       when(mockLabelsToNodesResponse.getLabelsToNodes()).thenReturn(
           getLabelsToNodesMap());
@@ -712,35 +745,52 @@ public class TestYarnClient {
     }
 
     @Override
-    public Map<String, Set<NodeId>> getLabelsToNodes(Set<String> labels)
+    public Map<NodeLabel, Set<NodeId>> getLabelsToNodes(Set<String> labels)
         throws YarnException, IOException {
       when(mockLabelsToNodesResponse.getLabelsToNodes()).thenReturn(
           getLabelsToNodesMap(labels));
       return super.getLabelsToNodes(labels);
     }
 
-    public Map<String, Set<NodeId>> getLabelsToNodesMap() {
-      Map<String, Set<NodeId>> map = new HashMap<String, Set<NodeId>>();
+    public Map<NodeLabel, Set<NodeId>> getLabelsToNodesMap() {
+      Map<NodeLabel, Set<NodeId>> map = new HashMap<NodeLabel, Set<NodeId>>();
       Set<NodeId> setNodeIds =
           new HashSet<NodeId>(Arrays.asList(
           NodeId.newInstance("host1", 0), NodeId.newInstance("host2", 0)));
-      map.put("x", setNodeIds);
-      map.put("y", setNodeIds);
-      map.put("z", setNodeIds);
+      map.put(NodeLabel.newInstance("x"), setNodeIds);
+      map.put(NodeLabel.newInstance("y"), setNodeIds);
+      map.put(NodeLabel.newInstance("z"), setNodeIds);
       return map;
     }
 
-    public Map<String, Set<NodeId>> getLabelsToNodesMap(Set<String> labels) {
-      Map<String, Set<NodeId>> map = new HashMap<String, Set<NodeId>>();
+    public Map<NodeLabel, Set<NodeId>> getLabelsToNodesMap(Set<String> labels) {
+      Map<NodeLabel, Set<NodeId>> map = new HashMap<NodeLabel, Set<NodeId>>();
       Set<NodeId> setNodeIds =
           new HashSet<NodeId>(Arrays.asList(
           NodeId.newInstance("host1", 0), NodeId.newInstance("host2", 0)));
       for(String label : labels) {
-        map.put(label, setNodeIds);
+        map.put(NodeLabel.newInstance(label), setNodeIds);
       }
       return map;
     }
 
+    @Override
+    public Map<NodeId, Set<NodeLabel>> getNodeToLabels() throws YarnException,
+        IOException {
+      when(mockNodeToLabelsResponse.getNodeToLabels()).thenReturn(
+          getNodeToLabelsMap());
+      return super.getNodeToLabels();
+    }
+
+    public Map<NodeId, Set<NodeLabel>> getNodeToLabelsMap() {
+      Map<NodeId, Set<NodeLabel>> map = new HashMap<NodeId, Set<NodeLabel>>();
+      Set<NodeLabel> setNodeLabels = new HashSet<NodeLabel>(Arrays.asList(
+          NodeLabel.newInstance("x", false),
+          NodeLabel.newInstance("y", false)));
+      map.put(NodeId.newInstance("host", 0), setNodeLabels);
+      return map;
+    }
+
     @Override
     public List<ApplicationAttemptReport> getApplicationAttempts(
         ApplicationId appId) throws YarnException, IOException {

+ 18 - 10
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/GetLabelsToNodesResponsePBImpl.java

@@ -29,11 +29,13 @@ import java.util.Set;
 import org.apache.hadoop.classification.InterfaceAudience.Public;
 import org.apache.hadoop.classification.InterfaceStability.Evolving;
 import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.api.records.NodeLabel;
 import org.apache.hadoop.yarn.api.records.impl.pb.NodeIdPBImpl;
+import org.apache.hadoop.yarn.api.records.impl.pb.NodeLabelPBImpl;
 import org.apache.hadoop.yarn.proto.YarnProtos.NodeIdProto;
 import org.apache.hadoop.yarn.api.protocolrecords.GetLabelsToNodesResponse;
-
 import org.apache.hadoop.yarn.proto.YarnProtos.LabelsToNodeIdsProto;
+import org.apache.hadoop.yarn.proto.YarnProtos.NodeLabelProto;
 import org.apache.hadoop.yarn.proto.YarnServiceProtos.GetLabelsToNodesResponseProto;
 import org.apache.hadoop.yarn.proto.YarnServiceProtos.GetLabelsToNodesResponseProtoOrBuilder;
 
@@ -44,7 +46,7 @@ public class GetLabelsToNodesResponsePBImpl extends
   GetLabelsToNodesResponseProto.Builder builder = null;
   boolean viaProto = false;
 
-  private Map<String, Set<NodeId>> labelsToNodes;
+  private Map<NodeLabel, Set<NodeId>> labelsToNodes;
 
   public GetLabelsToNodesResponsePBImpl() {
     this.builder = GetLabelsToNodesResponseProto.newBuilder();
@@ -61,7 +63,7 @@ public class GetLabelsToNodesResponsePBImpl extends
     }
     GetLabelsToNodesResponseProtoOrBuilder p = viaProto ? proto : builder;
     List<LabelsToNodeIdsProto> list = p.getLabelsToNodesList();
-    this.labelsToNodes = new HashMap<String, Set<NodeId>>();
+    this.labelsToNodes = new HashMap<NodeLabel, Set<NodeId>>();
 
     for (LabelsToNodeIdsProto c : list) {
       Set<NodeId> setNodes = new HashSet<NodeId>();
@@ -69,8 +71,9 @@ public class GetLabelsToNodesResponsePBImpl extends
         NodeId node = new NodeIdPBImpl(n);
         setNodes.add(node);
       }
-      if(!setNodes.isEmpty()) {
-        this.labelsToNodes.put(c.getNodeLabels(), setNodes);
+      if (!setNodes.isEmpty()) {
+        this.labelsToNodes
+            .put(new NodeLabelPBImpl(c.getNodeLabels()), setNodes);
       }
     }
   }
@@ -94,7 +97,7 @@ public class GetLabelsToNodesResponsePBImpl extends
           public Iterator<LabelsToNodeIdsProto> iterator() {
             return new Iterator<LabelsToNodeIdsProto>() {
 
-              Iterator<Entry<String, Set<NodeId>>> iter =
+              Iterator<Entry<NodeLabel, Set<NodeId>>> iter =
                   labelsToNodes.entrySet().iterator();
 
               @Override
@@ -104,13 +107,14 @@ public class GetLabelsToNodesResponsePBImpl extends
 
               @Override
               public LabelsToNodeIdsProto next() {
-                Entry<String, Set<NodeId>> now = iter.next();
+                Entry<NodeLabel, Set<NodeId>> now = iter.next();
                 Set<NodeIdProto> nodeProtoSet = new HashSet<NodeIdProto>();
                 for(NodeId n : now.getValue()) {
                   nodeProtoSet.add(convertToProtoFormat(n));
                 }
                 return LabelsToNodeIdsProto.newBuilder()
-                    .setNodeLabels(now.getKey()).addAllNodeId(nodeProtoSet)
+                    .setNodeLabels(convertToProtoFormat(now.getKey()))
+                    .addAllNodeId(nodeProtoSet)
                     .build();
               }
 
@@ -149,6 +153,10 @@ public class GetLabelsToNodesResponsePBImpl extends
     return ((NodeIdPBImpl)t).getProto();
   }
 
+  private NodeLabelProto convertToProtoFormat(NodeLabel l) {
+    return ((NodeLabelPBImpl)l).getProto();
+  }
+
   @Override
   public int hashCode() {
     assert false : "hashCode not designed";
@@ -168,7 +176,7 @@ public class GetLabelsToNodesResponsePBImpl extends
   @Override
   @Public
   @Evolving
-  public void setLabelsToNodes(Map<String, Set<NodeId>> map) {
+  public void setLabelsToNodes(Map<NodeLabel, Set<NodeId>> map) {
     initLabelsToNodes();
     labelsToNodes.clear();
     labelsToNodes.putAll(map);
@@ -177,7 +185,7 @@ public class GetLabelsToNodesResponsePBImpl extends
   @Override
   @Public
   @Evolving
-  public Map<String, Set<NodeId>> getLabelsToNodes() {
+  public Map<NodeLabel, Set<NodeId>> getLabelsToNodes() {
     initLabelsToNodes();
     return this.labelsToNodes;
   }

+ 36 - 22
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/GetNodesToLabelsResponsePBImpl.java

@@ -19,6 +19,7 @@
 package org.apache.hadoop.yarn.api.protocolrecords.impl.pb;
 
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -26,12 +27,13 @@ import java.util.Map.Entry;
 import java.util.Set;
 
 import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.api.records.NodeLabel;
 import org.apache.hadoop.yarn.api.records.impl.pb.NodeIdPBImpl;
+import org.apache.hadoop.yarn.api.records.impl.pb.NodeLabelPBImpl;
 import org.apache.hadoop.yarn.proto.YarnProtos.NodeIdProto;
 import org.apache.hadoop.yarn.api.protocolrecords.GetNodesToLabelsResponse;
-
-import com.google.common.collect.Sets;
-import org.apache.hadoop.yarn.proto.YarnProtos.NodeIdToLabelsProto;
+import org.apache.hadoop.yarn.proto.YarnProtos.NodeIdToLabelsInfoProto;
+import org.apache.hadoop.yarn.proto.YarnProtos.NodeLabelProto;
 import org.apache.hadoop.yarn.proto.YarnServiceProtos.GetNodesToLabelsResponseProto;
 import org.apache.hadoop.yarn.proto.YarnServiceProtos.GetNodesToLabelsResponseProtoOrBuilder;
 
@@ -42,8 +44,8 @@ public class GetNodesToLabelsResponsePBImpl extends
   GetNodesToLabelsResponseProto.Builder builder = null;
   boolean viaProto = false;
 
-  private Map<NodeId, Set<String>> nodeToLabels;
-  
+  private Map<NodeId, Set<NodeLabel>> nodeToLabels;
+
   public GetNodesToLabelsResponsePBImpl() {
     this.builder = GetNodesToLabelsResponseProto.newBuilder();
   }
@@ -58,12 +60,15 @@ public class GetNodesToLabelsResponsePBImpl extends
       return;
     }
     GetNodesToLabelsResponseProtoOrBuilder p = viaProto ? proto : builder;
-    List<NodeIdToLabelsProto> list = p.getNodeToLabelsList();
-    this.nodeToLabels = new HashMap<NodeId, Set<String>>();
-
-    for (NodeIdToLabelsProto c : list) {
-      this.nodeToLabels.put(new NodeIdPBImpl(c.getNodeId()),
-          Sets.newHashSet(c.getNodeLabelsList()));
+    List<NodeIdToLabelsInfoProto> list = p.getNodeToLabelsList();
+    this.nodeToLabels = new HashMap<NodeId, Set<NodeLabel>>();
+
+    for (NodeIdToLabelsInfoProto c : list) {
+      Set<NodeLabel> labels = new HashSet<NodeLabel>();
+      for (NodeLabelProto l : c.getNodeLabelsList()) {
+        labels.add(new NodeLabelPBImpl(l));
+      }
+      this.nodeToLabels.put(new NodeIdPBImpl(c.getNodeId()), labels);
     }
   }
 
@@ -80,13 +85,13 @@ public class GetNodesToLabelsResponsePBImpl extends
     if (nodeToLabels == null) {
       return;
     }
-    Iterable<NodeIdToLabelsProto> iterable =
-        new Iterable<NodeIdToLabelsProto>() {
+    Iterable<NodeIdToLabelsInfoProto> iterable =
+        new Iterable<NodeIdToLabelsInfoProto>() {
           @Override
-          public Iterator<NodeIdToLabelsProto> iterator() {
-            return new Iterator<NodeIdToLabelsProto>() {
+          public Iterator<NodeIdToLabelsInfoProto> iterator() {
+            return new Iterator<NodeIdToLabelsInfoProto>() {
 
-              Iterator<Entry<NodeId, Set<String>>> iter = nodeToLabels
+              Iterator<Entry<NodeId, Set<NodeLabel>>> iter = nodeToLabels
                   .entrySet().iterator();
 
               @Override
@@ -95,11 +100,16 @@ public class GetNodesToLabelsResponsePBImpl extends
               }
 
               @Override
-              public NodeIdToLabelsProto next() {
-                Entry<NodeId, Set<String>> now = iter.next();
-                return NodeIdToLabelsProto.newBuilder()
+              public NodeIdToLabelsInfoProto next() {
+                Entry<NodeId, Set<NodeLabel>> now = iter.next();
+                Set<NodeLabelProto> labelProtoList =
+                    new HashSet<NodeLabelProto>();
+                for (NodeLabel l : now.getValue()) {
+                  labelProtoList.add(convertToProtoFormat(l));
+                }
+                return NodeIdToLabelsInfoProto.newBuilder()
                     .setNodeId(convertToProtoFormat(now.getKey()))
-                    .addAllNodeLabels(now.getValue()).build();
+                    .addAllNodeLabels(labelProtoList).build();
               }
 
               @Override
@@ -134,13 +144,13 @@ public class GetNodesToLabelsResponsePBImpl extends
   }
 
   @Override
-  public Map<NodeId, Set<String>> getNodeToLabels() {
+  public Map<NodeId, Set<NodeLabel>> getNodeToLabels() {
     initNodeToLabels();
     return this.nodeToLabels;
   }
 
   @Override
-  public void setNodeToLabels(Map<NodeId, Set<String>> map) {
+  public void setNodeToLabels(Map<NodeId, Set<NodeLabel>> map) {
     initNodeToLabels();
     nodeToLabels.clear();
     nodeToLabels.putAll(map);
@@ -150,6 +160,10 @@ public class GetNodesToLabelsResponsePBImpl extends
     return ((NodeIdPBImpl)t).getProto();
   }
   
+  private NodeLabelProto convertToProtoFormat(NodeLabel t) {
+    return ((NodeLabelPBImpl)t).getProto();
+  }
+
   @Override
   public int hashCode() {
     assert false : "hashCode not designed";

+ 9 - 9
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/server/api/protocolrecords/impl/pb/ReplaceLabelsOnNodeRequestPBImpl.java

@@ -28,7 +28,7 @@ import java.util.Set;
 import org.apache.hadoop.yarn.api.records.NodeId;
 import org.apache.hadoop.yarn.api.records.impl.pb.NodeIdPBImpl;
 import org.apache.hadoop.yarn.proto.YarnProtos.NodeIdProto;
-import org.apache.hadoop.yarn.proto.YarnProtos.NodeIdToLabelsProto;
+import org.apache.hadoop.yarn.proto.YarnServerResourceManagerServiceProtos.NodeIdToLabelsNameProto;
 import org.apache.hadoop.yarn.proto.YarnServerResourceManagerServiceProtos.ReplaceLabelsOnNodeRequestProto;
 import org.apache.hadoop.yarn.proto.YarnServerResourceManagerServiceProtos.ReplaceLabelsOnNodeRequestProtoOrBuilder;
 import org.apache.hadoop.yarn.server.api.protocolrecords.ReplaceLabelsOnNodeRequest;
@@ -58,10 +58,10 @@ public class ReplaceLabelsOnNodeRequestPBImpl extends
       return;
     }
     ReplaceLabelsOnNodeRequestProtoOrBuilder p = viaProto ? proto : builder;
-    List<NodeIdToLabelsProto> list = p.getNodeToLabelsList();
+    List<NodeIdToLabelsNameProto> list = p.getNodeToLabelsList();
     this.nodeIdToLabels = new HashMap<NodeId, Set<String>>();
 
-    for (NodeIdToLabelsProto c : list) {
+    for (NodeIdToLabelsNameProto c : list) {
       this.nodeIdToLabels.put(new NodeIdPBImpl(c.getNodeId()),
           Sets.newHashSet(c.getNodeLabelsList()));
     }
@@ -80,11 +80,11 @@ public class ReplaceLabelsOnNodeRequestPBImpl extends
     if (nodeIdToLabels == null) {
       return;
     }
-    Iterable<NodeIdToLabelsProto> iterable =
-        new Iterable<NodeIdToLabelsProto>() {
+    Iterable<NodeIdToLabelsNameProto> iterable =
+        new Iterable<NodeIdToLabelsNameProto>() {
           @Override
-          public Iterator<NodeIdToLabelsProto> iterator() {
-            return new Iterator<NodeIdToLabelsProto>() {
+          public Iterator<NodeIdToLabelsNameProto> iterator() {
+            return new Iterator<NodeIdToLabelsNameProto>() {
 
               Iterator<Entry<NodeId, Set<String>>> iter = nodeIdToLabels
                   .entrySet().iterator();
@@ -95,9 +95,9 @@ public class ReplaceLabelsOnNodeRequestPBImpl extends
               }
 
               @Override
-              public NodeIdToLabelsProto next() {
+              public NodeIdToLabelsNameProto next() {
                 Entry<NodeId, Set<String>> now = iter.next();
-                return NodeIdToLabelsProto.newBuilder()
+                return NodeIdToLabelsNameProto.newBuilder()
                     .setNodeId(convertToProtoFormat(now.getKey())).clearNodeLabels()
                     .addAllNodeLabels(now.getValue()).build();
               }

+ 3 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ClientRMService.java

@@ -1226,7 +1226,7 @@ public class ClientRMService extends AbstractService implements
       GetNodesToLabelsRequest request) throws YarnException, IOException {
     RMNodeLabelsManager labelsMgr = rmContext.getNodeLabelManager();
     GetNodesToLabelsResponse response =
-        GetNodesToLabelsResponse.newInstance(labelsMgr.getNodeLabels());
+        GetNodesToLabelsResponse.newInstance(labelsMgr.getNodeLabelsInfo());
     return response;
   }
 
@@ -1236,10 +1236,10 @@ public class ClientRMService extends AbstractService implements
     RMNodeLabelsManager labelsMgr = rmContext.getNodeLabelManager();
     if (request.getNodeLabels() == null || request.getNodeLabels().isEmpty()) {
       return GetLabelsToNodesResponse.newInstance(
-          labelsMgr.getLabelsToNodes());
+          labelsMgr.getLabelsInfoToNodes());
     } else {
       return GetLabelsToNodesResponse.newInstance(
-          labelsMgr.getLabelsToNodes(request.getNodeLabels()));
+          labelsMgr.getLabelsInfoToNodes(request.getNodeLabels()));
     }
   }
 

+ 67 - 43
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestClientRMService.java

@@ -1407,8 +1407,10 @@ public class TestClientRMService {
       };
     };
     rm.start();
+    NodeLabel labelX = NodeLabel.newInstance("x", false);
+    NodeLabel labelY = NodeLabel.newInstance("y");
     RMNodeLabelsManager labelsMgr = rm.getRMContext().getNodeLabelManager();
-    labelsMgr.addToCluserNodeLabelsWithDefaultExclusivity(ImmutableSet.of("x", "y"));
+    labelsMgr.addToCluserNodeLabels(ImmutableSet.of(labelX, labelY));
 
     NodeId node1 = NodeId.newInstance("host1", 1234);
     NodeId node2 = NodeId.newInstance("host2", 1234);
@@ -1422,25 +1424,37 @@ public class TestClientRMService {
     YarnRPC rpc = YarnRPC.create(conf);
     InetSocketAddress rmAddress = rm.getClientRMService().getBindAddress();
     LOG.info("Connecting to ResourceManager at " + rmAddress);
-    ApplicationClientProtocol client =
-        (ApplicationClientProtocol) rpc.getProxy(
-            ApplicationClientProtocol.class, rmAddress, conf);
+    ApplicationClientProtocol client = (ApplicationClientProtocol) rpc
+        .getProxy(ApplicationClientProtocol.class, rmAddress, conf);
 
     // Get node labels collection
-    GetClusterNodeLabelsResponse response =
-        client.getClusterNodeLabels(GetClusterNodeLabelsRequest.newInstance());
+    GetClusterNodeLabelsResponse response = client
+        .getClusterNodeLabels(GetClusterNodeLabelsRequest.newInstance());
     Assert.assertTrue(response.getNodeLabels().containsAll(
-        Arrays.asList(NodeLabel.newInstance("x"), NodeLabel.newInstance("y"))));
+        Arrays.asList(labelX, labelY)));
 
     // Get node labels mapping
-    GetNodesToLabelsResponse response1 =
-        client.getNodeToLabels(GetNodesToLabelsRequest.newInstance());
-    Map<NodeId, Set<String>> nodeToLabels = response1.getNodeToLabels();
+    GetNodesToLabelsResponse response1 = client
+        .getNodeToLabels(GetNodesToLabelsRequest.newInstance());
+    Map<NodeId, Set<NodeLabel>> nodeToLabels = response1.getNodeToLabels();
     Assert.assertTrue(nodeToLabels.keySet().containsAll(
         Arrays.asList(node1, node2)));
-    Assert.assertTrue(nodeToLabels.get(node1).containsAll(Arrays.asList("x")));
-    Assert.assertTrue(nodeToLabels.get(node2).containsAll(Arrays.asList("y")));
-    
+    Assert.assertTrue(nodeToLabels.get(node1)
+        .containsAll(Arrays.asList(labelX)));
+    Assert.assertTrue(nodeToLabels.get(node2)
+        .containsAll(Arrays.asList(labelY)));
+    // Verify whether labelX's exclusivity is false
+    for (NodeLabel x : nodeToLabels.get(node1)) {
+      Assert.assertFalse(x.isExclusive());
+    }
+    // Verify whether labelY's exclusivity is true
+    for (NodeLabel y : nodeToLabels.get(node2)) {
+      Assert.assertTrue(y.isExclusive());
+    }
+    // Below label "x" is not present in the response as exclusivity is true
+    Assert.assertFalse(nodeToLabels.get(node1).containsAll(
+        Arrays.asList(NodeLabel.newInstance("x"))));
+
     rpc.stopProxy(client, conf);
     rm.close();
   }
@@ -1456,8 +1470,12 @@ public class TestClientRMService {
       };
     };
     rm.start();
+
+    NodeLabel labelX = NodeLabel.newInstance("x", false);
+    NodeLabel labelY = NodeLabel.newInstance("y", false);
+    NodeLabel labelZ = NodeLabel.newInstance("z", false);
     RMNodeLabelsManager labelsMgr = rm.getRMContext().getNodeLabelManager();
-    labelsMgr.addToCluserNodeLabelsWithDefaultExclusivity(ImmutableSet.of("x", "y", "z"));
+    labelsMgr.addToCluserNodeLabels(ImmutableSet.of(labelX, labelY, labelZ));
 
     NodeId node1A = NodeId.newInstance("host1", 1234);
     NodeId node1B = NodeId.newInstance("host1", 5678);
@@ -1477,43 +1495,49 @@ public class TestClientRMService {
     YarnRPC rpc = YarnRPC.create(conf);
     InetSocketAddress rmAddress = rm.getClientRMService().getBindAddress();
     LOG.info("Connecting to ResourceManager at " + rmAddress);
-    ApplicationClientProtocol client =
-        (ApplicationClientProtocol) rpc.getProxy(
-            ApplicationClientProtocol.class, rmAddress, conf);
+    ApplicationClientProtocol client = (ApplicationClientProtocol) rpc
+        .getProxy(ApplicationClientProtocol.class, rmAddress, conf);
 
     // Get node labels collection
-    GetClusterNodeLabelsResponse response =
-        client.getClusterNodeLabels(GetClusterNodeLabelsRequest.newInstance());
+    GetClusterNodeLabelsResponse response = client
+        .getClusterNodeLabels(GetClusterNodeLabelsRequest.newInstance());
     Assert.assertTrue(response.getNodeLabels().containsAll(
-        Arrays.asList(NodeLabel.newInstance("x"), NodeLabel.newInstance("y"),
-            NodeLabel.newInstance("z"))));
+        Arrays.asList(labelX, labelY, labelZ)));
 
     // Get labels to nodes mapping
-    GetLabelsToNodesResponse response1 =
-        client.getLabelsToNodes(GetLabelsToNodesRequest.newInstance());
-    Map<String, Set<NodeId>> labelsToNodes = response1.getLabelsToNodes();
-    Assert.assertTrue(
-        labelsToNodes.keySet().containsAll(Arrays.asList("x", "y", "z")));
-    Assert.assertTrue(
-        labelsToNodes.get("x").containsAll(Arrays.asList(node1A)));
-    Assert.assertTrue(
-        labelsToNodes.get("y").containsAll(Arrays.asList(node2A, node3A)));
-    Assert.assertTrue(
-        labelsToNodes.get("z").containsAll(Arrays.asList(node1B, node3B)));
+    GetLabelsToNodesResponse response1 = client
+        .getLabelsToNodes(GetLabelsToNodesRequest.newInstance());
+    Map<NodeLabel, Set<NodeId>> labelsToNodes = response1.getLabelsToNodes();
+    // Verify whether all NodeLabel's exclusivity are false
+    for (Map.Entry<NodeLabel, Set<NodeId>> nltn : labelsToNodes.entrySet()) {
+      Assert.assertFalse(nltn.getKey().isExclusive());
+    }
+    Assert.assertTrue(labelsToNodes.keySet().containsAll(
+        Arrays.asList(labelX, labelY, labelZ)));
+    Assert.assertTrue(labelsToNodes.get(labelX).containsAll(
+        Arrays.asList(node1A)));
+    Assert.assertTrue(labelsToNodes.get(labelY).containsAll(
+        Arrays.asList(node2A, node3A)));
+    Assert.assertTrue(labelsToNodes.get(labelZ).containsAll(
+        Arrays.asList(node1B, node3B)));
 
     // Get labels to nodes mapping for specific labels
-    Set<String> setlabels =
-        new HashSet<String>(Arrays.asList(new String[]{"x", "z"}));
-    GetLabelsToNodesResponse response2 =
-        client.getLabelsToNodes(GetLabelsToNodesRequest.newInstance(setlabels));
+    Set<String> setlabels = new HashSet<String>(Arrays.asList(new String[]{"x",
+        "z"}));
+    GetLabelsToNodesResponse response2 = client
+        .getLabelsToNodes(GetLabelsToNodesRequest.newInstance(setlabels));
     labelsToNodes = response2.getLabelsToNodes();
-    Assert.assertTrue(
-        labelsToNodes.keySet().containsAll(Arrays.asList("x", "z")));
-    Assert.assertTrue(
-        labelsToNodes.get("x").containsAll(Arrays.asList(node1A)));
-    Assert.assertTrue(
-        labelsToNodes.get("z").containsAll(Arrays.asList(node1B, node3B)));
-    Assert.assertEquals(labelsToNodes.get("y"), null);
+    // Verify whether all NodeLabel's exclusivity are false
+    for (Map.Entry<NodeLabel, Set<NodeId>> nltn : labelsToNodes.entrySet()) {
+      Assert.assertFalse(nltn.getKey().isExclusive());
+    }
+    Assert.assertTrue(labelsToNodes.keySet().containsAll(
+        Arrays.asList(labelX, labelZ)));
+    Assert.assertTrue(labelsToNodes.get(labelX).containsAll(
+        Arrays.asList(node1A)));
+    Assert.assertTrue(labelsToNodes.get(labelZ).containsAll(
+        Arrays.asList(node1B, node3B)));
+    Assert.assertEquals(labelsToNodes.get(labelY), null);
 
     rpc.stopProxy(client, conf);
     rm.close();