You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by ji...@apache.org on 2015/03/20 06:28:05 UTC

hadoop git commit: YARN-3379. Fixed missing data in localityTable and ResourceRequests table in RM WebUI. Contributed by Xuan Gong (cherry picked from commit 4e886eb9cbd2dcb128bbfd17309c734083093a4c)

Repository: hadoop
Updated Branches:
  refs/heads/branch-2 90164ffd8 -> 3f0c9e5fe


YARN-3379. Fixed missing data in localityTable and ResourceRequests table in RM WebUI. Contributed by Xuan Gong
(cherry picked from commit 4e886eb9cbd2dcb128bbfd17309c734083093a4c)


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

Branch: refs/heads/branch-2
Commit: 3f0c9e5fe36d201de021d989b23ebaeb2d9a027b
Parents: 90164ff
Author: Jian He <ji...@apache.org>
Authored: Thu Mar 19 22:27:21 2015 -0700
Committer: Jian He <ji...@apache.org>
Committed: Thu Mar 19 22:27:57 2015 -0700

----------------------------------------------------------------------
 hadoop-yarn-project/CHANGES.txt                 |   3 +
 .../yarn/server/webapp/AppAttemptBlock.java     |  71 +-------
 .../hadoop/yarn/server/webapp/AppBlock.java     |  87 +--------
 .../resourcemanager/webapp/AppAttemptPage.java  |   3 +-
 .../server/resourcemanager/webapp/AppPage.java  |   3 +-
 .../webapp/RMAppAttemptBlock.java               | 177 +++++++++++++++++++
 .../resourcemanager/webapp/RMAppBlock.java      |  94 ++++++++++
 7 files changed, 290 insertions(+), 148 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/3f0c9e5f/hadoop-yarn-project/CHANGES.txt
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt
index 66079e2..5f9e8dd 100644
--- a/hadoop-yarn-project/CHANGES.txt
+++ b/hadoop-yarn-project/CHANGES.txt
@@ -751,6 +751,9 @@ Release 2.7.0 - UNRELEASED
     YARN-3349. Treat all exceptions as failure in
     TestFSRMStateStore#testFSRMStateStoreClientRetry. (Zhihai Xu via ozawa)
 
+    YARN-3379. Fixed missing data in localityTable and ResourceRequests table
+    in RM WebUI. (Xuan Gong via jianhe)
+
 Release 2.6.0 - 2014-11-18
 
   INCOMPATIBLE CHANGES

http://git-wip-us.apache.org/repos/asf/hadoop/blob/3f0c9e5f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppAttemptBlock.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppAttemptBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppAttemptBlock.java
index eeccf0f..dca39d6 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppAttemptBlock.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppAttemptBlock.java
@@ -19,12 +19,6 @@ package org.apache.hadoop.yarn.server.webapp;
 
 import static org.apache.hadoop.yarn.util.StringHelper.join;
 import static org.apache.hadoop.yarn.webapp.YarnWebParams.APPLICATION_ATTEMPT_ID;
-import static org.apache.hadoop.yarn.webapp.YarnWebParams.WEB_UI_TYPE;
-import static org.apache.hadoop.yarn.webapp.view.JQueryUI._EVEN;
-import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP;
-import static org.apache.hadoop.yarn.webapp.view.JQueryUI._ODD;
-import static org.apache.hadoop.yarn.webapp.view.JQueryUI._TH;
-
 import java.security.PrivilegedExceptionAction;
 import java.util.Collection;
 
@@ -43,20 +37,18 @@ import org.apache.hadoop.yarn.api.records.YarnApplicationAttemptState;
 import org.apache.hadoop.yarn.server.webapp.dao.AppAttemptInfo;
 import org.apache.hadoop.yarn.server.webapp.dao.ContainerInfo;
 import org.apache.hadoop.yarn.util.ConverterUtils;
-import org.apache.hadoop.yarn.webapp.YarnWebParams;
 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
-import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV;
 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE;
 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY;
 import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
 import org.apache.hadoop.yarn.webapp.view.InfoBlock;
-
 import com.google.inject.Inject;
 
 public class AppAttemptBlock extends HtmlBlock {
 
   private static final Log LOG = LogFactory.getLog(AppAttemptBlock.class);
   protected ApplicationBaseProtocol appBaseProt;
+  protected ApplicationAttemptId appAttemptId = null;
 
   @Inject
   public AppAttemptBlock(ApplicationBaseProtocol appBaseProt, ViewContext ctx) {
@@ -66,14 +58,12 @@ public class AppAttemptBlock extends HtmlBlock {
 
   @Override
   protected void render(Block html) {
-    String webUiType = $(WEB_UI_TYPE);
     String attemptid = $(APPLICATION_ATTEMPT_ID);
     if (attemptid.isEmpty()) {
       puts("Bad request: requires application attempt ID");
       return;
     }
 
-    ApplicationAttemptId appAttemptId = null;
     try {
       appAttemptId = ConverterUtils.toApplicationAttemptId(attemptid);
     } catch (IllegalArgumentException e) {
@@ -183,17 +173,7 @@ public class AppAttemptBlock extends HtmlBlock {
       return;
     }
 
-    // TODO need to render applicationHeadRoom value from
-    // ApplicationAttemptMetrics after YARN-3284
-    if (webUiType.equals(YarnWebParams.RM_WEB_UI)) {
-      if (!isApplicationInFinalState(appAttempt.getAppAttemptState())) {
-        DIV<Hamlet> pdiv = html._(InfoBlock.class).div(_INFO_WRAP);
-        info("Application Attempt Overview").clear();
-        info("Application Attempt Metrics")._(
-            "Application Attempt Headroom : ", 0);
-        pdiv._();
-      }
-    }
+    createAttemptHeadRoomTable(html);
     html._(InfoBlock.class);
 
     // Container Table
@@ -236,45 +216,6 @@ public class AppAttemptBlock extends HtmlBlock {
       ._("var containersTableData=" + containersTableData)._();
 
     tbody._()._();
-
-    if (webUiType.equals(YarnWebParams.RM_WEB_UI)) {
-      createContainerLocalityTable(html); // TODO:YARN-3284
-    }
-  }
-
-  //TODO: YARN-3284
-  //The containerLocality metrics will be exposed from AttemptReport
-  private void createContainerLocalityTable(Block html) {
-    int totalAllocatedContainers = 0; //TODO: YARN-3284
-    int[][] localityStatistics = new int[0][0];//TODO:YARN-3284
-    DIV<Hamlet> div = html.div(_INFO_WRAP);
-    TABLE<DIV<Hamlet>> table =
-        div.h3(
-          "Total Allocated Containers: "
-              + totalAllocatedContainers).h3("Each table cell"
-            + " represents the number of NodeLocal/RackLocal/OffSwitch containers"
-            + " satisfied by NodeLocal/RackLocal/OffSwitch resource requests.").table(
-          "#containerLocality");
-    table.
-      tr().
-        th(_TH, "").
-        th(_TH, "Node Local Request").
-        th(_TH, "Rack Local Request").
-        th(_TH, "Off Switch Request").
-      _();
-
-    String[] containersType =
-        { "Num Node Local Containers (satisfied by)", "Num Rack Local Containers (satisfied by)",
-            "Num Off Switch Containers (satisfied by)" };
-    boolean odd = false;
-    for (int i = 0; i < localityStatistics.length; i++) {
-      table.tr((odd = !odd) ? _ODD : _EVEN).td(containersType[i])
-        .td(String.valueOf(localityStatistics[i][0]))
-        .td(i == 0 ? "" : String.valueOf(localityStatistics[i][1]))
-        .td(i <= 1 ? "" : String.valueOf(localityStatistics[i][2]))._();
-    }
-    table._();
-    div._();
   }
 
   private boolean hasAMContainer(ContainerId containerId,
@@ -286,10 +227,8 @@ public class AppAttemptBlock extends HtmlBlock {
     }
     return false;
   }
-  
-  private boolean isApplicationInFinalState(YarnApplicationAttemptState state) {
-    return state == YarnApplicationAttemptState.FINISHED
-        || state == YarnApplicationAttemptState.FAILED
-        || state == YarnApplicationAttemptState.KILLED;
+
+  protected void createAttemptHeadRoomTable(Block html) {
+    
   }
 }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/3f0c9e5f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppBlock.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppBlock.java
index 5fc5fa0..abb6b9c 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppBlock.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppBlock.java
@@ -21,11 +21,8 @@ package org.apache.hadoop.yarn.server.webapp;
 import static org.apache.hadoop.yarn.util.StringHelper.join;
 import static org.apache.hadoop.yarn.webapp.YarnWebParams.APPLICATION_ID;
 import static org.apache.hadoop.yarn.webapp.YarnWebParams.WEB_UI_TYPE;
-import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP;
 import java.security.PrivilegedExceptionAction;
 import java.util.Collection;
-import java.util.List;
-
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -39,12 +36,9 @@ import org.apache.hadoop.yarn.api.protocolrecords.GetContainerReportRequest;
 import org.apache.hadoop.yarn.api.records.ApplicationAttemptReport;
 import org.apache.hadoop.yarn.api.records.ApplicationId;
 import org.apache.hadoop.yarn.api.records.ApplicationReport;
-import org.apache.hadoop.yarn.api.records.ApplicationResourceUsageReport;
 import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.hadoop.yarn.api.records.ContainerReport;
 import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
-import org.apache.hadoop.yarn.api.records.Resource;
-import org.apache.hadoop.yarn.api.records.ResourceRequest;
 import org.apache.hadoop.yarn.api.records.YarnApplicationState;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.exceptions.ContainerNotFoundException;
@@ -53,10 +47,8 @@ import org.apache.hadoop.yarn.server.webapp.dao.AppInfo;
 import org.apache.hadoop.yarn.server.webapp.dao.ContainerInfo;
 import org.apache.hadoop.yarn.util.Apps;
 import org.apache.hadoop.yarn.util.Times;
-import org.apache.hadoop.yarn.util.resource.Resources;
 import org.apache.hadoop.yarn.webapp.YarnWebParams;
 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
-import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV;
 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE;
 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY;
 import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
@@ -69,9 +61,11 @@ public class AppBlock extends HtmlBlock {
   private static final Log LOG = LogFactory.getLog(AppBlock.class);
   protected ApplicationBaseProtocol appBaseProt;
   protected Configuration conf;
+  protected ApplicationId appID = null;
 
   @Inject
-  AppBlock(ApplicationBaseProtocol appBaseProt, ViewContext ctx, Configuration conf) {
+  protected AppBlock(ApplicationBaseProtocol appBaseProt, ViewContext ctx,
+      Configuration conf) {
     super(ctx);
     this.appBaseProt = appBaseProt;
     this.conf = conf;
@@ -86,7 +80,6 @@ public class AppBlock extends HtmlBlock {
       return;
     }
 
-    ApplicationId appID = null;
     try {
       appID = Apps.toAppID(aid);
     } catch (Exception e) {
@@ -213,31 +206,7 @@ public class AppBlock extends HtmlBlock {
       return;
     }
 
-    //TODO:YARN-3284
-    //The preemption metrics will be exposed from ApplicationReport
-    // and ApplicationAttemptReport
-    ApplicationResourceUsageReport usageReport =
-        appReport.getApplicationResourceUsageReport();
-    DIV<Hamlet> pdiv = html.
-        _(InfoBlock.class).
-        div(_INFO_WRAP);
-    info("Application Overview").clear();
-    info("Application Metrics")
-        ._("Total Resource Preempted:",
-          Resources.none()) // TODO: YARN-3284
-        ._("Total Number of Non-AM Containers Preempted:",
-          String.valueOf(0)) // TODO: YARN-3284
-        ._("Total Number of AM Containers Preempted:",
-          String.valueOf(0)) // TODO: YARN-3284
-        ._("Resource Preempted from Current Attempt:",
-          Resources.none()) // TODO: YARN-3284
-        ._("Number of Non-AM Containers Preempted from Current Attempt:",
-          0) // TODO: YARN-3284
-        ._("Aggregate Resource Allocation:",
-          String.format("%d MB-seconds, %d vcore-seconds", usageReport == null
-            ? 0 : usageReport.getMemorySeconds(), usageReport == null ? 0
-            : usageReport.getVcoreSeconds()));
-    pdiv._();
+    createApplicationMetricsTable(html);
 
     html._(InfoBlock.class);
 
@@ -319,49 +288,6 @@ public class AppBlock extends HtmlBlock {
       ._("var attemptsTableData=" + attemptsTableData)._();
 
     tbody._()._();
-
-    if (webUiType != null && webUiType.equals(YarnWebParams.RM_WEB_UI)) {
-      createResourceRequestsTable(html, null); // TODO:YARN-3284
-    }
-  }
-
-  //TODO:YARN-3284
-  //The resource requests metrics will be exposed from attemptReport
-  private void createResourceRequestsTable(Block html, List<ResourceRequest> resouceRequests) {
-    TBODY<TABLE<Hamlet>> tbody =
-        html.table("#ResourceRequests").thead().tr()
-          .th(".priority", "Priority")
-          .th(".resourceName", "ResourceName")
-          .th(".totalResource", "Capability")
-          .th(".numContainers", "NumContainers")
-          .th(".relaxLocality", "RelaxLocality")
-          .th(".nodeLabelExpression", "NodeLabelExpression")._()._().tbody();
-
-    Resource totalResource = Resource.newInstance(0, 0);
-    if (resouceRequests != null) {
-      for (ResourceRequest request : resouceRequests) {
-        if (request.getNumContainers() == 0) {
-          continue;
-        }
-
-        tbody.tr()
-          .td(String.valueOf(request.getPriority()))
-          .td(request.getResourceName())
-          .td(String.valueOf(request.getCapability()))
-          .td(String.valueOf(request.getNumContainers()))
-          .td(String.valueOf(request.getRelaxLocality()))
-          .td(request.getNodeLabelExpression() == null ? "N/A" : request
-              .getNodeLabelExpression())._();
-        if (request.getResourceName().equals(ResourceRequest.ANY)) {
-          Resources.addTo(totalResource,
-            Resources.multiply(request.getCapability(),
-              request.getNumContainers()));
-        }
-      }
-    }
-    html.div().$class("totalResourceRequests")
-      .h3("Total Outstanding Resource Requests: " + totalResource)._();
-    tbody._()._();
   }
 
   private String clarifyAppState(YarnApplicationState state) {
@@ -389,4 +315,9 @@ public class AppBlock extends HtmlBlock {
     }
     return status.toString();
   }
+
+  // The preemption metrics only need to be shown in RM WebUI
+  protected void createApplicationMetricsTable(Block html) {
+
+  }
 }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/3f0c9e5f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppAttemptPage.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/AppAttemptPage.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppAttemptPage.java
index 6e4cfad..df5fb9e 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppAttemptPage.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppAttemptPage.java
@@ -23,7 +23,6 @@ import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES;
 import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES_ID;
 import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID;
 
-import org.apache.hadoop.yarn.server.webapp.AppAttemptBlock;
 import org.apache.hadoop.yarn.server.webapp.WebPageUtils;
 import org.apache.hadoop.yarn.webapp.SubView;
 import org.apache.hadoop.yarn.webapp.YarnWebParams;
@@ -51,7 +50,7 @@ public class AppAttemptPage extends RmView {
 
   @Override
   protected Class<? extends SubView> content() {
-    return AppAttemptBlock.class;
+    return RMAppAttemptBlock.class;
   }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/3f0c9e5f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppPage.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/AppPage.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppPage.java
index 9f9b7c9..0c5516a 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppPage.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/AppPage.java
@@ -23,7 +23,6 @@ import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES;
 import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES_ID;
 import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID;
 
-import org.apache.hadoop.yarn.server.webapp.AppBlock;
 import org.apache.hadoop.yarn.server.webapp.WebPageUtils;
 import org.apache.hadoop.yarn.webapp.SubView;
 import org.apache.hadoop.yarn.webapp.YarnWebParams;
@@ -50,6 +49,6 @@ public class AppPage extends RmView {
 
   @Override 
   protected Class<? extends SubView> content() {
-    return AppBlock.class;
+    return RMAppBlock.class;
   }
 }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/3f0c9e5f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMAppAttemptBlock.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/RMAppAttemptBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMAppAttemptBlock.java
new file mode 100644
index 0000000..419c0ce
--- /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/RMAppAttemptBlock.java
@@ -0,0 +1,177 @@
+/**
+ * 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;
+
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._EVEN;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._ODD;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._TH;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.api.records.Resource;
+import org.apache.hadoop.yarn.api.records.ResourceRequest;
+import org.apache.hadoop.yarn.api.records.YarnApplicationAttemptState;
+import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
+import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
+import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt;
+import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptMetrics;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.AppInfo;
+import org.apache.hadoop.yarn.server.webapp.AppAttemptBlock;
+import org.apache.hadoop.yarn.util.resource.Resources;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY;
+import org.apache.hadoop.yarn.webapp.util.WebAppUtils;
+import org.apache.hadoop.yarn.webapp.view.InfoBlock;
+import com.google.inject.Inject;
+
+public class RMAppAttemptBlock extends AppAttemptBlock{
+
+  private final ResourceManager rm;
+  protected Configuration conf;
+
+  @Inject
+  RMAppAttemptBlock(ViewContext ctx, ResourceManager rm, Configuration conf) {
+    super(rm.getClientRMService(), ctx);
+    this.rm = rm;
+    this.conf = conf;
+  }
+
+  @Override
+  protected void render(Block html) {
+    super.render(html);
+    createContainerLocalityTable(html);
+    createResourceRequestsTable(html);
+  }
+
+  private void createResourceRequestsTable(Block html) {
+    AppInfo app =
+        new AppInfo(rm, rm.getRMContext().getRMApps()
+          .get(this.appAttemptId.getApplicationId()), true,
+          WebAppUtils.getHttpSchemePrefix(conf));
+    TBODY<TABLE<Hamlet>> tbody =
+        html.table("#ResourceRequests").thead().tr()
+          .th(".priority", "Priority")
+          .th(".resourceName", "ResourceName")
+          .th(".totalResource", "Capability")
+          .th(".numContainers", "NumContainers")
+          .th(".relaxLocality", "RelaxLocality")
+          .th(".nodeLabelExpression", "NodeLabelExpression")._()._().tbody();
+
+    Resource totalResource = Resource.newInstance(0, 0);
+    if (app.getResourceRequests() != null) {
+      for (ResourceRequest request : app.getResourceRequests()) {
+        if (request.getNumContainers() == 0) {
+          continue;
+        }
+
+        tbody.tr()
+          .td(String.valueOf(request.getPriority()))
+          .td(request.getResourceName())
+          .td(String.valueOf(request.getCapability()))
+          .td(String.valueOf(request.getNumContainers()))
+          .td(String.valueOf(request.getRelaxLocality()))
+          .td(request.getNodeLabelExpression() == null ? "N/A" : request
+              .getNodeLabelExpression())._();
+        if (request.getResourceName().equals(ResourceRequest.ANY)) {
+          Resources.addTo(totalResource,
+            Resources.multiply(request.getCapability(),
+              request.getNumContainers()));
+        }
+      }
+    }
+    html.div().$class("totalResourceRequests")
+      .h3("Total Outstanding Resource Requests: " + totalResource)._();
+    tbody._()._();
+  }
+
+  private void createContainerLocalityTable(Block html) {
+    RMAppAttemptMetrics attemptMetrics = null;
+    RMAppAttempt attempt = getRMAppAttempt();
+    if (attempt != null) {
+      attemptMetrics = attempt.getRMAppAttemptMetrics();
+    }
+    
+    if (attemptMetrics == null) {
+      return;
+    }
+
+    DIV<Hamlet> div = html.div(_INFO_WRAP);
+    TABLE<DIV<Hamlet>> table =
+        div.h3(
+          "Total Allocated Containers: "
+              + attemptMetrics.getTotalAllocatedContainers()).h3("Each table cell"
+            + " represents the number of NodeLocal/RackLocal/OffSwitch containers"
+            + " satisfied by NodeLocal/RackLocal/OffSwitch resource requests.").table(
+          "#containerLocality");
+    table.
+      tr().
+        th(_TH, "").
+        th(_TH, "Node Local Request").
+        th(_TH, "Rack Local Request").
+        th(_TH, "Off Switch Request").
+      _();
+
+    String[] containersType =
+        { "Num Node Local Containers (satisfied by)", "Num Rack Local Containers (satisfied by)",
+            "Num Off Switch Containers (satisfied by)" };
+    boolean odd = false;
+    for (int i = 0; i < attemptMetrics.getLocalityStatistics().length; i++) {
+      table.tr((odd = !odd) ? _ODD : _EVEN).td(containersType[i])
+        .td(String.valueOf(attemptMetrics.getLocalityStatistics()[i][0]))
+        .td(i == 0 ? "" : String.valueOf(attemptMetrics.getLocalityStatistics()[i][1]))
+        .td(i <= 1 ? "" : String.valueOf(attemptMetrics.getLocalityStatistics()[i][2]))._();
+    }
+    table._();
+    div._();
+  }
+
+  private boolean isApplicationInFinalState(YarnApplicationAttemptState state) {
+    return state == YarnApplicationAttemptState.FINISHED
+        || state == YarnApplicationAttemptState.FAILED
+        || state == YarnApplicationAttemptState.KILLED;
+  }
+
+  @Override
+  protected void createAttemptHeadRoomTable(Block html) {
+    RMAppAttempt attempt = getRMAppAttempt();
+    if (attempt != null) {
+      if (!isApplicationInFinalState(YarnApplicationAttemptState
+          .valueOf(attempt.getAppAttemptState().toString()))) {
+        DIV<Hamlet> pdiv = html._(InfoBlock.class).div(_INFO_WRAP);
+        info("Application Attempt Overview").clear();
+        info("Application Attempt Metrics")._(
+          "Application Attempt Headroom : ", 0);
+        pdiv._();
+      }
+    }
+  }
+
+  private RMAppAttempt getRMAppAttempt() {
+    ApplicationId appId = this.appAttemptId.getApplicationId();
+    RMAppAttempt attempt = null;
+    RMApp rmApp = rm.getRMContext().getRMApps().get(appId);
+    if (rmApp != null) { 
+      attempt = rmApp.getAppAttempts().get(appAttemptId);
+    }
+    return attempt;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/3f0c9e5f/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMAppBlock.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/RMAppBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/RMAppBlock.java
new file mode 100644
index 0000000..64c5747
--- /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/RMAppBlock.java
@@ -0,0 +1,94 @@
+/**
+ * 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;
+
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.yarn.api.records.Resource;
+import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
+import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
+import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppMetrics;
+import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptMetrics;
+import org.apache.hadoop.yarn.server.webapp.AppBlock;
+import org.apache.hadoop.yarn.util.resource.Resources;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV;
+import org.apache.hadoop.yarn.webapp.view.InfoBlock;
+
+import com.google.inject.Inject;
+
+public class RMAppBlock extends AppBlock{
+
+  private final ResourceManager rm;
+
+  @Inject
+  RMAppBlock(ViewContext ctx, Configuration conf, ResourceManager rm) {
+    super(rm.getClientRMService(), ctx, conf);
+    this.rm = rm;
+  }
+
+  @Override
+  protected void render(Block html) {
+    super.render(html);
+  }
+
+  @Override
+  protected void createApplicationMetricsTable(Block html){
+    RMApp rmApp = this.rm.getRMContext().getRMApps().get(appID);
+    RMAppMetrics appMetrics = rmApp == null ? null : rmApp.getRMAppMetrics();
+    // Get attempt metrics and fields, it is possible currentAttempt of RMApp is
+    // null. In that case, we will assume resource preempted and number of Non
+    // AM container preempted on that attempt is 0
+    RMAppAttemptMetrics attemptMetrics;
+    if (rmApp == null || null == rmApp.getCurrentAppAttempt()) {
+      attemptMetrics = null;
+    } else {
+      attemptMetrics = rmApp.getCurrentAppAttempt().getRMAppAttemptMetrics();
+    }
+    Resource attemptResourcePreempted =
+        attemptMetrics == null ? Resources.none() : attemptMetrics
+          .getResourcePreempted();
+    int attemptNumNonAMContainerPreempted =
+        attemptMetrics == null ? 0 : attemptMetrics
+          .getNumNonAMContainersPreempted();
+    DIV<Hamlet> pdiv = html.
+        _(InfoBlock.class).
+        div(_INFO_WRAP);
+    info("Application Overview").clear();
+    info("Application Metrics")
+        ._("Total Resource Preempted:",
+          appMetrics == null ? "N/A" : appMetrics.getResourcePreempted())
+        ._("Total Number of Non-AM Containers Preempted:",
+          appMetrics == null ? "N/A"
+              : appMetrics.getNumNonAMContainersPreempted())
+        ._("Total Number of AM Containers Preempted:",
+          appMetrics == null ? "N/A"
+              : appMetrics.getNumAMContainersPreempted())
+        ._("Resource Preempted from Current Attempt:",
+          attemptResourcePreempted)
+        ._("Number of Non-AM Containers Preempted from Current Attempt:",
+          attemptNumNonAMContainerPreempted)
+        ._("Aggregate Resource Allocation:",
+          String.format("%d MB-seconds, %d vcore-seconds",
+              appMetrics == null ? "N/A" : appMetrics.getMemorySeconds(),
+              appMetrics == null ? "N/A" : appMetrics.getVcoreSeconds()));
+    pdiv._();
+  }
+}