Browse Source

YARN-11368. [Federation] Improve Yarn Router's Federation Page style. (#5105)

slfan1989 2 years ago
parent
commit
845cf8bc28

+ 7 - 6
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/federation/federation.js

@@ -28,7 +28,7 @@ $(document).ready(function() {
             var capabilityArr = scTableData.filter(item => (item.subcluster === row.id()));
             var capabilityObj = JSON.parse(capabilityArr[0].capability).clusterMetrics;
             row.child(
-                '<table>' +
+                '<table style="line-height:25px;" >' +
                 '   <tr>' +
                 '      <td>' +
                 '         <h3>Application Metrics</h3>' +
@@ -42,11 +42,12 @@ $(document).ready(function() {
                 '      <td>' +
                 '        <h3>Resource Metrics</h3>' +
                 '        <h4>Memory</h4>' +
-                '        TotalMB : ' + capabilityObj.totalMB + ' </p>' +
-                '        ReservedMB : ' + capabilityObj.reservedMB + ' </p>' +
-                '        AvailableMB : ' + capabilityObj.availableMB + ' </p>' +
-                '        AllocatedMB : ' + capabilityObj.allocatedMB + ' </p>' +
-                '        PendingMB : ' + capabilityObj.pendingMB + ' </p>' +
+                '        Total Memory : ' + capabilityArr[0].totalmemory + ' </p>' +
+                '        Reserved Memory : ' + capabilityArr[0].reservedmemory + ' </p>' +
+                '        Available Memory : ' + capabilityArr[0].availablememory + ' </p>' +
+                '        Allocated Memory : ' + capabilityArr[0].allocatedmemory + ' </p>' +
+                '        Pending Memory : ' + capabilityArr[0].pendingmemory + ' </p>' +
+                '        <hr />' +
                 '        <h4>VirtualCores</h4>' +
                 '        TotalVirtualCores : ' + capabilityObj.totalVirtualCores + ' </p>' +
                 '        ReservedVirtualCores : ' + capabilityObj.reservedVirtualCores + ' </p>' +

+ 30 - 10
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/main/java/org/apache/hadoop/yarn/server/router/webapp/FederationBlock.java

@@ -23,12 +23,13 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.HashMap;
+import java.util.Date;
 
 import com.google.gson.Gson;
 import org.apache.hadoop.util.StringUtils;
-import org.apache.commons.lang3.time.DateFormatUtils;
 import org.apache.hadoop.yarn.server.federation.store.records.SubClusterId;
 import org.apache.hadoop.yarn.server.federation.store.records.SubClusterInfo;
+import org.apache.hadoop.yarn.server.federation.store.records.SubClusterState;
 import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ClusterMetricsInfo;
 import org.apache.hadoop.yarn.server.router.Router;
 import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet;
@@ -149,32 +150,51 @@ class FederationBlock extends RouterBlock {
         ClusterMetricsInfo subClusterInfo = getClusterMetricsInfo(capability);
 
         // Prepare LastStartTime & LastHeartBeat
-        String lastStartTime =
-            DateFormatUtils.format(subcluster.getLastStartTime(), DATE_PATTERN);
-        String lastHeartBeat =
-            DateFormatUtils.format(subcluster.getLastHeartBeat(), DATE_PATTERN);
+        Date lastStartTime = new Date(subcluster.getLastStartTime());
+        Date lastHeartBeat = new Date(subcluster.getLastHeartBeat());
 
         // Prepare Resource
         long totalMB = subClusterInfo.getTotalMB();
         String totalMBDesc = StringUtils.byteDesc(totalMB * BYTES_IN_MB);
         long totalVirtualCores = subClusterInfo.getTotalVirtualCores();
-        String resources = String.format("<Memory:%s, VCore:%s>", totalMBDesc, totalVirtualCores);
+        String resources = String.format("<memory:%s, vCores:%s>", totalMBDesc, totalVirtualCores);
 
         // Prepare Node
         long totalNodes = subClusterInfo.getTotalNodes();
         long activeNodes = subClusterInfo.getActiveNodes();
-        String nodes = String.format("<Total Nodes:%s, Active Nodes:%s>", totalNodes, activeNodes);
+        String nodes = String.format("<totalNodes:%s, activeNodes:%s>", totalNodes, activeNodes);
 
         // Prepare HTML Table
+        String stateStyle = "color:#dc3545;font-weight:bolder";
+        SubClusterState state = subcluster.getState();
+        if (SubClusterState.SC_RUNNING == state) {
+          stateStyle = "color:#28a745;font-weight:bolder";
+        }
+
         tbody.tr().$id(subClusterIdText)
             .td().$class("details-control").a(herfWebAppAddress, subClusterIdText).__()
-            .td(subcluster.getState().name())
-            .td(lastStartTime)
-            .td(lastHeartBeat)
+            .td().$style(stateStyle).__(state.name()).__()
+            .td().__(lastStartTime).__()
+            .td().__(lastHeartBeat).__()
             .td(resources)
             .td(nodes)
             .__();
 
+        // Formatted memory information
+        long allocatedMB = subClusterInfo.getAllocatedMB();
+        String allocatedMBDesc = StringUtils.byteDesc(allocatedMB * BYTES_IN_MB);
+        long availableMB = subClusterInfo.getAvailableMB();
+        String availableMBDesc = StringUtils.byteDesc(availableMB * BYTES_IN_MB);
+        long pendingMB = subClusterInfo.getPendingMB();
+        String pendingMBDesc = StringUtils.byteDesc(pendingMB * BYTES_IN_MB);
+        long reservedMB = subClusterInfo.getReservedMB();
+        String reservedMBDesc = StringUtils.byteDesc(reservedMB * BYTES_IN_MB);
+
+        subclusterMap.put("totalmemory", totalMBDesc);
+        subclusterMap.put("allocatedmemory", allocatedMBDesc);
+        subclusterMap.put("availablememory", availableMBDesc);
+        subclusterMap.put("pendingmemory", pendingMBDesc);
+        subclusterMap.put("reservedmemory", reservedMBDesc);
         subclusterMap.put("subcluster", subClusterId.getId());
         subclusterMap.put("capability", capability);
         lists.add(subclusterMap);

+ 13 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-router/src/test/java/org/apache/hadoop/yarn/server/router/webapp/TestFederationWebApp.java

@@ -23,14 +23,20 @@ import org.apache.hadoop.yarn.exceptions.YarnException;
 import org.apache.hadoop.yarn.server.router.Router;
 import org.apache.hadoop.yarn.webapp.test.WebAppTests;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 
 public class TestFederationWebApp extends TestRouterWebServicesREST {
 
+  private static final Logger LOG =
+      LoggerFactory.getLogger(TestFederationWebApp.class);
+
   @Test
   public void testFederationWebViewNotEnable()
       throws InterruptedException, YarnException, IOException {
+    LOG.info("testFederationWebView - NotEnable Federation.");
     // Test Federation is not Enabled
     Configuration config = new YarnConfiguration();
     config.setBoolean(YarnConfiguration.FEDERATION_ENABLED, false);
@@ -40,6 +46,7 @@ public class TestFederationWebApp extends TestRouterWebServicesREST {
   @Test
   public void testFederationWebViewEnable()
       throws InterruptedException, YarnException, IOException {
+    LOG.info("testFederationWebView - Enable Federation.");
     // Test Federation Enabled
     Configuration config = new YarnConfiguration();
     config.setBoolean(YarnConfiguration.FEDERATION_ENABLED, true);
@@ -49,6 +56,7 @@ public class TestFederationWebApp extends TestRouterWebServicesREST {
   @Test
   public void testFederationAboutViewEnable()
       throws InterruptedException, YarnException, IOException {
+    LOG.info("testFederationAboutViewEnable - Enable Federation.");
     // Test Federation Enabled
     Configuration config = new YarnConfiguration();
     config.setBoolean(YarnConfiguration.FEDERATION_ENABLED, true);
@@ -58,6 +66,7 @@ public class TestFederationWebApp extends TestRouterWebServicesREST {
   @Test
   public void testFederationAboutViewNotEnable()
       throws InterruptedException, YarnException, IOException {
+    LOG.info("testFederationAboutViewNotEnable - NotEnable Federation.");
     // Test Federation Not Enabled
     Configuration config = new YarnConfiguration();
     config.setBoolean(YarnConfiguration.FEDERATION_ENABLED, false);
@@ -67,6 +76,7 @@ public class TestFederationWebApp extends TestRouterWebServicesREST {
   @Test
   public void testFederationNodeViewEnable()
       throws InterruptedException, YarnException, IOException {
+    LOG.info("testFederationNodeViewEnable - Enable Federation.");
     // Test Federation Enabled
     Configuration config = new YarnConfiguration();
     config.setBoolean(YarnConfiguration.FEDERATION_ENABLED, true);
@@ -76,6 +86,7 @@ public class TestFederationWebApp extends TestRouterWebServicesREST {
   @Test
   public void testFederationNodeViewNotEnable()
       throws InterruptedException, YarnException, IOException {
+    LOG.info("testFederationNodeViewNotEnable - NotEnable Federation.");
     // Test Federation Not Enabled
     Configuration config = new YarnConfiguration();
     config.setBoolean(YarnConfiguration.FEDERATION_ENABLED, false);
@@ -85,6 +96,7 @@ public class TestFederationWebApp extends TestRouterWebServicesREST {
   @Test
   public void testFederationAppViewEnable()
       throws InterruptedException, YarnException, IOException {
+    LOG.info("testFederationAppViewEnable - Enable Federation.");
     // Test Federation Enabled
     Configuration config = new YarnConfiguration();
     config.setBoolean(YarnConfiguration.FEDERATION_ENABLED, true);
@@ -94,6 +106,7 @@ public class TestFederationWebApp extends TestRouterWebServicesREST {
   @Test
   public void testFederationAppViewNotEnable()
       throws InterruptedException, YarnException, IOException {
+    LOG.info("testFederationAppViewNotEnable - NotEnable Federation.");
     // Test Federation Not Enabled
     Configuration config = new YarnConfiguration();
     config.setBoolean(YarnConfiguration.FEDERATION_ENABLED, false);