This is an automated email from the ASF dual-hosted git repository.

inigoiri pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git


The following commit(s) were added to refs/heads/trunk by this push:
     new fa723ae8391 YARN-11445. [Federation] Add getClusterInfo, 
getClusterUserInfo REST APIs for Router. (#5472)
fa723ae8391 is described below

commit fa723ae83916af6e814923eca53a5fef046d33aa
Author: slfan1989 <55643692+slfan1...@users.noreply.github.com>
AuthorDate: Sat Mar 18 02:59:45 2023 +0800

    YARN-11445. [Federation] Add getClusterInfo, getClusterUserInfo REST APIs 
for Router. (#5472)
---
 .../resourcemanager/webapp/dao/ClusterInfo.java    | 10 +++
 .../webapp/dao/ClusterUserInfo.java                | 10 +++
 .../hadoop/yarn/server/router/RouterMetrics.java   | 62 +++++++++++++++
 .../router/webapp/FederationInterceptorREST.java   | 76 ++++++++++++++++++-
 .../router/webapp/dao/FederationClusterInfo.java   | 50 ++++++++++++
 .../webapp/dao/FederationClusterUserInfo.java      | 49 ++++++++++++
 .../yarn/server/router/TestRouterMetrics.java      | 64 ++++++++++++++++
 .../webapp/MockDefaultRequestInterceptorREST.java  | 16 +++-
 .../webapp/TestFederationInterceptorREST.java      | 88 ++++++++++++++++++++++
 .../webapp/TestableFederationInterceptorREST.java  |  4 +
 10 files changed, 426 insertions(+), 3 deletions(-)

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/ClusterInfo.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/ClusterInfo.java
index a429215dd5d..4596f37f1e3 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/ClusterInfo.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/ClusterInfo.java
@@ -44,6 +44,8 @@ public class ClusterInfo {
   protected String hadoopVersionBuiltOn;
   protected String haZooKeeperConnectionState;
 
+  private String subClusterId;
+
   public ClusterInfo() {
   } // JAXB needs this
 
@@ -113,4 +115,12 @@ public class ClusterInfo {
   public String getHAZookeeperConnectionState() {
     return this.haZooKeeperConnectionState;
   }
+
+  public String getSubClusterId() {
+    return subClusterId;
+  }
+
+  public void setSubClusterId(String subClusterId) {
+    this.subClusterId = subClusterId;
+  }
 }
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/ClusterUserInfo.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/ClusterUserInfo.java
index 7a6bd40b942..a65fc845563 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/ClusterUserInfo.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/ClusterUserInfo.java
@@ -42,6 +42,8 @@ public class ClusterUserInfo {
     // User who has placed the request
     protected String requestedUser;
 
+  private String subClusterId;
+
     public ClusterUserInfo() {
     }
 
@@ -61,4 +63,12 @@ public class ClusterUserInfo {
     public String getRequestedUser() {
         return requestedUser;
     }
+
+  public String getSubClusterId() {
+    return subClusterId;
+  }
+
+  public void setSubClusterId(String subClusterId) {
+    this.subClusterId = subClusterId;
+  }
 }
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/RouterMetrics.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/RouterMetrics.java
index fdcd890ea6e..3338013ebac 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/RouterMetrics.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/RouterMetrics.java
@@ -159,6 +159,10 @@ public final class RouterMetrics {
   private MutableGaugeInt numAddToClusterNodeLabelsFailedRetrieved;
   @Metric("# of removeFromClusterNodeLabels failed to be retrieved")
   private MutableGaugeInt numRemoveFromClusterNodeLabelsFailedRetrieved;
+  @Metric("# of getClusterInfo failed to be retrieved")
+  private MutableGaugeInt numGetClusterInfoFailedRetrieved;
+  @Metric("# of getClusterUserInfo failed to be retrieved")
+  private MutableGaugeInt numGetClusterUserInfoFailedRetrieved;
 
   // Aggregate metrics are shared, and don't have to be looked up per call
   @Metric("Total number of successful Submitted apps and latency(ms)")
@@ -279,6 +283,10 @@ public final class RouterMetrics {
   private MutableRate totalSucceededAddToClusterNodeLabelsRetrieved;
   @Metric("Total number of successful Retrieved RemoveFromClusterNodeLabels 
and latency(ms)")
   private MutableRate totalSucceededRemoveFromClusterNodeLabelsRetrieved;
+  @Metric("Total number of successful Retrieved GetClusterInfoRetrieved and 
latency(ms)")
+  private MutableRate totalSucceededGetClusterInfoRetrieved;
+  @Metric("Total number of successful Retrieved GetClusterUserInfoRetrieved 
and latency(ms)")
+  private MutableRate totalSucceededGetClusterUserInfoRetrieved;
 
   /**
    * Provide quantile counters for all latencies.
@@ -342,6 +350,8 @@ public final class RouterMetrics {
   private MutableQuantiles replaceLabelsOnNodeLatency;
   private MutableQuantiles addToClusterNodeLabelsLatency;
   private MutableQuantiles removeFromClusterNodeLabelsLatency;
+  private MutableQuantiles getClusterInfoLatency;
+  private MutableQuantiles getClusterUserInfoLatency;
 
   private static volatile RouterMetrics instance = null;
   private static MetricsRegistry registry;
@@ -551,6 +561,12 @@ public final class RouterMetrics {
 
     removeFromClusterNodeLabelsLatency = 
registry.newQuantiles("removeFromClusterNodeLabelsLatency",
         "latency of remove cluster nodelabels timeouts", "ops", "latency", 10);
+
+    getClusterInfoLatency = registry.newQuantiles("getClusterInfoLatency",
+        "latency of get cluster info timeouts", "ops", "latency", 10);
+
+    getClusterUserInfoLatency = 
registry.newQuantiles("getClusterUserInfoLatency",
+        "latency of get cluster user info timeouts", "ops", "latency", 10);
   }
 
   public static RouterMetrics getMetrics() {
@@ -847,6 +863,16 @@ public final class RouterMetrics {
     return 
totalSucceededRemoveFromClusterNodeLabelsRetrieved.lastStat().numSamples();
   }
 
+  @VisibleForTesting
+  public long getNumSucceededGetClusterInfoRetrieved() {
+    return totalSucceededGetClusterInfoRetrieved.lastStat().numSamples();
+  }
+
+  @VisibleForTesting
+  public long getNumSucceededGetClusterUserInfoRetrieved() {
+    return totalSucceededGetClusterUserInfoRetrieved.lastStat().numSamples();
+  }
+
   @VisibleForTesting
   public long getNumSucceededRefreshSuperUserGroupsConfigurationRetrieved() {
     return 
totalSucceededRefreshSuperUserGroupsConfigurationRetrieved.lastStat().numSamples();
@@ -1137,6 +1163,16 @@ public final class RouterMetrics {
     return 
totalSucceededRemoveFromClusterNodeLabelsRetrieved.lastStat().mean();
   }
 
+  @VisibleForTesting
+  public double getLatencySucceededGetClusterInfoRetrieved() {
+    return totalSucceededGetClusterInfoRetrieved.lastStat().mean();
+  }
+
+  @VisibleForTesting
+  public double getLatencySucceededGetClusterUserInfoRetrieved() {
+    return totalSucceededGetClusterUserInfoRetrieved.lastStat().mean();
+  }
+
   @VisibleForTesting
   public double 
getLatencySucceededRefreshSuperUserGroupsConfigurationRetrieved() {
     return 
totalSucceededRefreshSuperUserGroupsConfigurationRetrieved.lastStat().mean();
@@ -1382,6 +1418,14 @@ public final class RouterMetrics {
     return numRemoveFromClusterNodeLabelsFailedRetrieved.value();
   }
 
+  public int getClusterInfoFailedRetrieved() {
+    return numGetClusterInfoFailedRetrieved.value();
+  }
+
+  public int getClusterUserInfoFailedRetrieved() {
+    return numGetClusterUserInfoFailedRetrieved.value();
+  }
+
   public int getDelegationTokenFailedRetrieved() {
     return numGetDelegationTokenFailedRetrieved.value();
   }
@@ -1685,6 +1729,16 @@ public final class RouterMetrics {
     removeFromClusterNodeLabelsLatency.add(duration);
   }
 
+  public void succeededGetClusterInfoRetrieved(long duration) {
+    totalSucceededGetClusterInfoRetrieved.add(duration);
+    getClusterInfoLatency.add(duration);
+  }
+
+  public void succeededGetClusterUserInfoRetrieved(long duration) {
+    totalSucceededGetClusterUserInfoRetrieved.add(duration);
+    getClusterUserInfoLatency.add(duration);
+  }
+
   public void succeededRefreshSuperUserGroupsConfRetrieved(long duration) {
     totalSucceededRefreshSuperUserGroupsConfigurationRetrieved.add(duration);
     refreshSuperUserGroupsConfLatency.add(duration);
@@ -1905,6 +1959,14 @@ public final class RouterMetrics {
     numRemoveFromClusterNodeLabelsFailedRetrieved.incr();
   }
 
+  public void incrGetClusterInfoFailedRetrieved() {
+    numGetClusterInfoFailedRetrieved.incr();
+  }
+
+  public void incrGetClusterUserInfoFailedRetrieved() {
+    numGetClusterUserInfoFailedRetrieved.incr();
+  }
+
   public void incrGetDelegationTokenFailedRetrieved() {
     numGetDelegationTokenFailedRetrieved.incr();
   }
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationInterceptorREST.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationInterceptorREST.java
index 94b4b1ca251..857e4c52c6f 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationInterceptorREST.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationInterceptorREST.java
@@ -129,6 +129,8 @@ import 
org.apache.hadoop.yarn.server.router.webapp.dao.FederationBulkActivitiesI
 import 
org.apache.hadoop.yarn.server.router.webapp.dao.FederationRMQueueAclInfo;
 import org.apache.hadoop.yarn.server.router.webapp.dao.SubClusterResult;
 import 
org.apache.hadoop.yarn.server.router.webapp.dao.FederationSchedulerTypeInfo;
+import 
org.apache.hadoop.yarn.server.router.webapp.dao.FederationClusterUserInfo;
+import org.apache.hadoop.yarn.server.router.webapp.dao.FederationClusterInfo;
 import org.apache.hadoop.yarn.server.utils.BuilderUtils;
 import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptInfo;
 import org.apache.hadoop.yarn.server.webapp.dao.ContainerInfo;
@@ -1137,14 +1139,84 @@ public class FederationInterceptorREST extends 
AbstractRESTRequestInterceptor {
     return getClusterInfo();
   }
 
+  /**
+   * This method retrieves the cluster information, and it is reachable by 
using
+   * {@link RMWSConsts#INFO}.
+   *
+   * In Federation mode, we will return a FederationClusterInfo object,
+   * which contains a set of ClusterInfo.
+   *
+   * @return the cluster information.
+   */
   @Override
   public ClusterInfo getClusterInfo() {
-    throw new NotImplementedException("Code is not implemented");
+    try {
+      long startTime = Time.now();
+      Map<SubClusterId, SubClusterInfo> subClustersActive = 
getActiveSubclusters();
+      Class[] argsClasses = new Class[]{};
+      Object[] args = new Object[]{};
+      ClientMethod remoteMethod = new ClientMethod("getClusterInfo", 
argsClasses, args);
+      Map<SubClusterInfo, ClusterInfo> subClusterInfoMap =
+          invokeConcurrent(subClustersActive.values(), remoteMethod, 
ClusterInfo.class);
+      FederationClusterInfo federationClusterInfo = new 
FederationClusterInfo();
+      subClusterInfoMap.forEach((subClusterInfo, clusterInfo) -> {
+        SubClusterId subClusterId = subClusterInfo.getSubClusterId();
+        clusterInfo.setSubClusterId(subClusterId.getId());
+        federationClusterInfo.getList().add(clusterInfo);
+      });
+      long stopTime = Time.now();
+      routerMetrics.succeededGetClusterInfoRetrieved(stopTime - startTime);
+      return federationClusterInfo;
+    } catch (NotFoundException e) {
+      routerMetrics.incrGetClusterInfoFailedRetrieved();
+      RouterServerUtil.logAndThrowRunTimeException("Get all active sub 
cluster(s) error.", e);
+    } catch (YarnException | IOException e) {
+      routerMetrics.incrGetClusterInfoFailedRetrieved();
+      RouterServerUtil.logAndThrowRunTimeException("getClusterInfo error.", e);
+    }
+    routerMetrics.incrGetClusterInfoFailedRetrieved();
+    throw new RuntimeException("getClusterInfo error.");
   }
 
+  /**
+   * This method retrieves the cluster user information, and it is reachable 
by using
+   * {@link RMWSConsts#CLUSTER_USER_INFO}.
+   *
+   * In Federation mode, we will return a ClusterUserInfo object,
+   * which contains a set of ClusterUserInfo.
+   *
+   * @param hsr the servlet request
+   * @return the cluster user information
+   */
   @Override
   public ClusterUserInfo getClusterUserInfo(HttpServletRequest hsr) {
-    throw new NotImplementedException("Code is not implemented");
+    try {
+      long startTime = Time.now();
+      Map<SubClusterId, SubClusterInfo> subClustersActive = 
getActiveSubclusters();
+      final HttpServletRequest hsrCopy = clone(hsr);
+      Class[] argsClasses = new Class[]{HttpServletRequest.class};
+      Object[] args = new Object[]{hsrCopy};
+      ClientMethod remoteMethod = new ClientMethod("getClusterUserInfo", 
argsClasses, args);
+      Map<SubClusterInfo, ClusterUserInfo> subClusterInfoMap =
+          invokeConcurrent(subClustersActive.values(), remoteMethod, 
ClusterUserInfo.class);
+      FederationClusterUserInfo federationClusterUserInfo = new 
FederationClusterUserInfo();
+      subClusterInfoMap.forEach((subClusterInfo, clusterUserInfo) -> {
+        SubClusterId subClusterId = subClusterInfo.getSubClusterId();
+        clusterUserInfo.setSubClusterId(subClusterId.getId());
+        federationClusterUserInfo.getList().add(clusterUserInfo);
+      });
+      long stopTime = Time.now();
+      routerMetrics.succeededGetClusterUserInfoRetrieved(stopTime - startTime);
+      return federationClusterUserInfo;
+    } catch (NotFoundException e) {
+      routerMetrics.incrGetClusterUserInfoFailedRetrieved();
+      RouterServerUtil.logAndThrowRunTimeException("Get all active sub 
cluster(s) error.", e);
+    } catch (YarnException | IOException e) {
+      routerMetrics.incrGetClusterUserInfoFailedRetrieved();
+      RouterServerUtil.logAndThrowRunTimeException("getClusterUserInfo 
error.", e);
+    }
+    routerMetrics.incrGetClusterUserInfoFailedRetrieved();
+    throw new RuntimeException("getClusterUserInfo error.");
   }
 
   /**
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/dao/FederationClusterInfo.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/dao/FederationClusterInfo.java
new file mode 100644
index 00000000000..9b8d7b5431a
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/dao/FederationClusterInfo.java
@@ -0,0 +1,50 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.router.webapp.dao;
+
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterInfo;
+
+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 java.util.ArrayList;
+import java.util.List;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class FederationClusterInfo extends ClusterInfo {
+
+  @XmlElement(name = "subCluster")
+  private List<ClusterInfo> list = new ArrayList<>();
+
+  public FederationClusterInfo() {
+  } // JAXB needs this
+
+  public FederationClusterInfo(ArrayList<ClusterInfo> list) {
+    this.list = list;
+  }
+
+  public List<ClusterInfo> getList() {
+    return list;
+  }
+
+  public void setList(List<ClusterInfo> list) {
+    this.list = list;
+  }
+}
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/dao/FederationClusterUserInfo.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/dao/FederationClusterUserInfo.java
new file mode 100644
index 00000000000..b4a19b7919d
--- /dev/null
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/dao/FederationClusterUserInfo.java
@@ -0,0 +1,49 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.router.webapp.dao;
+
+import 
org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterUserInfo;
+
+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 java.util.ArrayList;
+import java.util.List;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class FederationClusterUserInfo extends ClusterUserInfo {
+  @XmlElement(name = "subCluster")
+  private List<ClusterUserInfo> list = new ArrayList<>();
+
+  public FederationClusterUserInfo() {
+  } // JAXB needs this
+
+  public FederationClusterUserInfo(ArrayList<ClusterUserInfo> list) {
+    this.list = list;
+  }
+
+  public List<ClusterUserInfo> getList() {
+    return list;
+  }
+
+  public void setList(List<ClusterUserInfo> list) {
+    this.list = list;
+  }
+}
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/TestRouterMetrics.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/TestRouterMetrics.java
index a3756174573..955948c91c8 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/TestRouterMetrics.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/TestRouterMetrics.java
@@ -568,6 +568,16 @@ public class TestRouterMetrics {
       LOG.info("Mocked: failed getBulkActivitie call");
       metrics.incrGetBulkActivitiesFailedRetrieved();
     }
+
+    public void getClusterInfoFailed() {
+      LOG.info("Mocked: failed getClusterInfo call");
+      metrics.incrGetClusterInfoFailedRetrieved();
+    }
+
+    public void getClusterUserInfoFailed() {
+      LOG.info("Mocked: failed getClusterUserInfo call");
+      metrics.incrGetClusterUserInfoFailedRetrieved();
+    }
   }
 
   // Records successes for all calls
@@ -838,6 +848,16 @@ public class TestRouterMetrics {
       LOG.info("Mocked: successful AddToClusterNodeLabels call with duration 
{}", duration);
       metrics.succeededAddToClusterNodeLabelsRetrieved(duration);
     }
+
+    public void getClusterInfoRetrieved(long duration) {
+      LOG.info("Mocked: successful GetClusterInfoRetrieved call with duration 
{}", duration);
+      metrics.succeededGetClusterInfoRetrieved(duration);
+    }
+
+    public void getClusterUserInfoRetrieved(long duration) {
+      LOG.info("Mocked: successful GetClusterUserInfoRetrieved call with 
duration {}", duration);
+      metrics.succeededGetClusterUserInfoRetrieved(duration);
+    }
   }
 
   @Test
@@ -1848,4 +1868,48 @@ public class TestRouterMetrics {
     Assert.assertEquals(225,
         metrics.getLatencySucceededAddToClusterNodeLabelsRetrieved(), 
ASSERT_DOUBLE_DELTA);
   }
+
+  @Test
+  public void testGetClusterInfoRetrievedFailed() {
+    long totalBadBefore = metrics.getClusterInfoFailedRetrieved();
+    badSubCluster.getClusterInfoFailed();
+    Assert.assertEquals(totalBadBefore + 1, 
metrics.getClusterInfoFailedRetrieved());
+  }
+
+  @Test
+  public void testGetClusterInfoRetrieved() {
+    long totalGoodBefore = metrics.getNumSucceededGetClusterInfoRetrieved();
+    goodSubCluster.getClusterInfoRetrieved(150);
+    Assert.assertEquals(totalGoodBefore + 1,
+        metrics.getNumSucceededGetClusterInfoRetrieved());
+    Assert.assertEquals(150,
+        metrics.getLatencySucceededGetClusterInfoRetrieved(), 
ASSERT_DOUBLE_DELTA);
+    goodSubCluster.getClusterInfoRetrieved(300);
+    Assert.assertEquals(totalGoodBefore + 2,
+        metrics.getNumSucceededGetClusterInfoRetrieved());
+    Assert.assertEquals(225,
+        metrics.getLatencySucceededGetClusterInfoRetrieved(), 
ASSERT_DOUBLE_DELTA);
+  }
+
+  @Test
+  public void testGetClusterUserInfoRetrievedFailed() {
+    long totalBadBefore = metrics.getClusterUserInfoFailedRetrieved();
+    badSubCluster.getClusterUserInfoFailed();
+    Assert.assertEquals(totalBadBefore + 1, 
metrics.getClusterUserInfoFailedRetrieved());
+  }
+
+  @Test
+  public void testGetClusterUserInfoRetrieved() {
+    long totalGoodBefore = 
metrics.getNumSucceededGetClusterUserInfoRetrieved();
+    goodSubCluster.getClusterUserInfoRetrieved(150);
+    Assert.assertEquals(totalGoodBefore + 1,
+        metrics.getNumSucceededGetClusterUserInfoRetrieved());
+    Assert.assertEquals(150,
+        metrics.getLatencySucceededGetClusterUserInfoRetrieved(), 
ASSERT_DOUBLE_DELTA);
+    goodSubCluster.getClusterUserInfoRetrieved(300);
+    Assert.assertEquals(totalGoodBefore + 2,
+        metrics.getNumSucceededGetClusterUserInfoRetrieved());
+    Assert.assertEquals(225,
+        metrics.getLatencySucceededGetClusterUserInfoRetrieved(), 
ASSERT_DOUBLE_DELTA);
+  }
 }
\ No newline at end of file
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/MockDefaultRequestInterceptorREST.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/MockDefaultRequestInterceptorREST.java
index 653224a7d37..c34167f9219 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/MockDefaultRequestInterceptorREST.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/MockDefaultRequestInterceptorREST.java
@@ -111,7 +111,9 @@ import 
org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo;
 import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppState;
 import 
org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ApplicationSubmissionContextInfo;
 import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppsInfo;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterInfo;
 import 
org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterMetricsInfo;
+import 
org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterUserInfo;
 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.NodesInfo;
@@ -161,7 +163,6 @@ import org.mockito.Mockito;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 import static 
org.apache.hadoop.yarn.server.router.webapp.BaseRouterWebServicesTest.QUEUE_DEFAULT;
 import static 
org.apache.hadoop.yarn.server.router.webapp.BaseRouterWebServicesTest.QUEUE_DEFAULT_FULL;
 import static 
org.apache.hadoop.yarn.server.router.webapp.BaseRouterWebServicesTest.QUEUE_DEDICATED;
@@ -1363,4 +1364,17 @@ public class MockDefaultRequestInterceptorREST
     }
     throw new YarnException("removeFromClusterNodeLabels Error");
   }
+
+  @Override
+  public ClusterInfo getClusterInfo() {
+    ClusterInfo clusterInfo = new ClusterInfo(mockRM);
+    return clusterInfo;
+  }
+
+  @Override
+  public ClusterUserInfo getClusterUserInfo(HttpServletRequest hsr) {
+    String remoteUser = hsr.getRemoteUser();
+    UserGroupInformation callerUGI = 
UserGroupInformation.createRemoteUser(remoteUser);
+    return new ClusterUserInfo(mockRM, callerUGI);
+  }
 }
\ No newline at end of file
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/TestFederationInterceptorREST.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/TestFederationInterceptorREST.java
index a2831657dc8..784fbd15ce1 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/TestFederationInterceptorREST.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/TestFederationInterceptorREST.java
@@ -73,10 +73,13 @@ import 
org.apache.hadoop.yarn.server.federation.store.records.GetApplicationHome
 import 
org.apache.hadoop.yarn.server.federation.store.records.ApplicationHomeSubCluster;
 import 
org.apache.hadoop.yarn.server.federation.utils.FederationStateStoreFacade;
 import 
org.apache.hadoop.yarn.server.federation.utils.FederationStateStoreTestUtil;
+import org.apache.hadoop.yarn.server.resourcemanager.MockRM;
 import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo;
 import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppState;
 import 
org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ApplicationSubmissionContextInfo;
 import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppsInfo;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterInfo;
+import 
org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterUserInfo;
 import 
org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterMetricsInfo;
 import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NewApplication;
 import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.NodeInfo;
@@ -128,9 +131,12 @@ import 
org.apache.hadoop.yarn.server.webapp.dao.ContainersInfo;
 import 
org.apache.hadoop.yarn.server.router.webapp.dao.FederationRMQueueAclInfo;
 import 
org.apache.hadoop.yarn.server.router.webapp.dao.FederationBulkActivitiesInfo;
 import 
org.apache.hadoop.yarn.server.router.webapp.dao.FederationSchedulerTypeInfo;
+import org.apache.hadoop.yarn.server.router.webapp.dao.FederationClusterInfo;
+import 
org.apache.hadoop.yarn.server.router.webapp.dao.FederationClusterUserInfo;
 import org.apache.hadoop.yarn.util.LRUCacheHashMap;
 import org.apache.hadoop.yarn.util.MonotonicClock;
 import org.apache.hadoop.yarn.util.Times;
+import org.apache.hadoop.yarn.util.YarnVersionInfo;
 import org.apache.hadoop.yarn.webapp.BadRequestException;
 import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
 import org.junit.Assert;
@@ -2127,4 +2133,86 @@ public class TestFederationInterceptorREST extends 
BaseRouterWebServicesTest {
     LambdaTestUtils.intercept(YarnRuntimeException.class, 
"removeFromClusterNodeLabels Error",
         () -> interceptor.removeFromClusterNodeLabels(oldNodeLabels1, null));
   }
+
+  @Test
+  public void testGetClusterUserInfo() {
+    String requestUserName = "test-user";
+    HttpServletRequest hsr = mock(HttpServletRequest.class);
+    when(hsr.getRemoteUser()).thenReturn(requestUserName);
+    ClusterUserInfo clusterUserInfo = interceptor.getClusterUserInfo(hsr);
+
+    Assert.assertNotNull(clusterUserInfo);
+    Assert.assertTrue(clusterUserInfo instanceof FederationClusterUserInfo);
+
+    FederationClusterUserInfo federationClusterUserInfo =
+        (FederationClusterUserInfo) clusterUserInfo;
+
+    List<ClusterUserInfo> fedClusterUserInfoList = 
federationClusterUserInfo.getList();
+    Assert.assertNotNull(fedClusterUserInfoList);
+    Assert.assertEquals(4, fedClusterUserInfoList.size());
+
+    List<String> subClusterIds = subClusters.stream().map(
+        subClusterId -> subClusterId.getId()).collect(Collectors.toList());
+    MockRM mockRM = interceptor.getMockRM();
+
+    for (ClusterUserInfo fedClusterUserInfo : fedClusterUserInfoList) {
+      // Check subClusterId
+      String subClusterId = fedClusterUserInfo.getSubClusterId();
+      Assert.assertNotNull(subClusterId);
+      Assert.assertTrue(subClusterIds.contains(subClusterId));
+
+      // Check requestedUser
+      String requestedUser = fedClusterUserInfo.getRequestedUser();
+      Assert.assertNotNull(requestedUser);
+      Assert.assertEquals(requestUserName, requestedUser);
+
+      // Check rmLoginUser
+      String rmLoginUser = fedClusterUserInfo.getRmLoginUser();
+      Assert.assertNotNull(rmLoginUser);
+      Assert.assertEquals(mockRM.getRMLoginUser(), rmLoginUser);
+    }
+  }
+
+  @Test
+  public void testGetClusterInfo() {
+    ClusterInfo clusterInfos = interceptor.getClusterInfo();
+    Assert.assertNotNull(clusterInfos);
+    Assert.assertTrue(clusterInfos instanceof FederationClusterInfo);
+
+    FederationClusterInfo federationClusterInfos =
+        (FederationClusterInfo) (clusterInfos);
+
+    List<ClusterInfo> fedClusterInfosList = federationClusterInfos.getList();
+    Assert.assertNotNull(fedClusterInfosList);
+    Assert.assertEquals(4, fedClusterInfosList.size());
+
+    List<String> subClusterIds = subClusters.stream().map(
+        subClusterId -> subClusterId.getId()).collect(Collectors.toList());
+
+    MockRM mockRM = interceptor.getMockRM();
+    String yarnVersion = YarnVersionInfo.getVersion();
+
+    for (ClusterInfo clusterInfo : fedClusterInfosList) {
+      String subClusterId = clusterInfo.getSubClusterId();
+      // Check subClusterId
+      Assert.assertTrue(subClusterIds.contains(subClusterId));
+
+      // Check state
+      String clusterState = mockRM.getServiceState().toString();
+      Assert.assertEquals(clusterState, clusterInfo.getState());
+
+      // Check rmStateStoreName
+      String rmStateStoreName =
+          mockRM.getRMContext().getStateStore().getClass().getName();
+      Assert.assertEquals(rmStateStoreName, clusterInfo.getRMStateStore());
+
+      // Check RM Version
+      Assert.assertEquals(yarnVersion, clusterInfo.getRMVersion());
+
+      // Check haZooKeeperConnectionState
+      String rmHAZookeeperConnectionState = 
mockRM.getRMContext().getHAZookeeperConnectionState();
+      Assert.assertEquals(rmHAZookeeperConnectionState,
+          clusterInfo.getHAZookeeperConnectionState());
+    }
+  }
 }
\ No newline at end of file
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/TestableFederationInterceptorREST.java
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/TestableFederationInterceptorREST.java
index 31fd756b664..0e37b7c9749 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/TestableFederationInterceptorREST.java
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/TestableFederationInterceptorREST.java
@@ -117,4 +117,8 @@ public class TestableFederationInterceptorREST
     }
     super.shutdown();
   }
+
+  public MockRM getMockRM() {
+    return mockRM;
+  }
 }
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org
For additional commands, e-mail: common-commits-h...@hadoop.apache.org

Reply via email to