hadoop-common-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From szets...@apache.org
Subject [05/12] YARN-2033. Merging generic-history into the Timeline Store (Contributed by Zhijie Shen)
Date Sat, 13 Sep 2014 06:57:45 GMT
http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/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 1a76eca..4a02892 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
@@ -20,12 +20,13 @@ 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 java.io.IOException;
+import java.security.PrivilegedExceptionAction;
 import java.util.Collection;
 
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
 import org.apache.hadoop.yarn.api.records.ApplicationAttemptReport;
 import org.apache.hadoop.yarn.api.records.ContainerReport;
@@ -67,10 +68,22 @@ public class AppAttemptBlock extends HtmlBlock {
       return;
     }
 
+    final ApplicationAttemptId appAttemptIdFinal = appAttemptId;
+    UserGroupInformation callerUGI = getCallerUGI();
     ApplicationAttemptReport appAttemptReport;
     try {
-      appAttemptReport = appContext.getApplicationAttempt(appAttemptId);
-    } catch (IOException e) {
+      if (callerUGI == null) {
+        appAttemptReport = appContext.getApplicationAttempt(appAttemptId);
+      } else {
+        appAttemptReport = callerUGI.doAs(
+            new PrivilegedExceptionAction<ApplicationAttemptReport> () {
+          @Override
+          public ApplicationAttemptReport run() throws Exception {
+            return appContext.getApplicationAttempt(appAttemptIdFinal);
+          }
+        });
+      }
+    } catch (Exception e) {
       String message =
           "Failed to read the application attempt " + appAttemptId + ".";
       LOG.error(message, e);
@@ -108,8 +121,26 @@ public class AppAttemptBlock extends HtmlBlock {
 
     Collection<ContainerReport> containers;
     try {
-      containers = appContext.getContainers(appAttemptId).values();
-    } catch (IOException e) {
+      if (callerUGI == null) {
+        containers = appContext.getContainers(appAttemptId).values();
+      } else {
+        containers = callerUGI.doAs(
+            new PrivilegedExceptionAction<Collection<ContainerReport>> () {
+          @Override
+          public Collection<ContainerReport> run() throws Exception {
+            return  appContext.getContainers(appAttemptIdFinal).values();
+          }
+        });
+      }
+    } catch (RuntimeException e) {
+      // have this block to suppress the findbugs warning
+      html
+      .p()
+      ._(
+        "Sorry, Failed to get containers for application attempt" + attemptid
+            + ".")._();
+      return;
+    } catch (Exception e) {
       html
         .p()
         ._(

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/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 2ae495b..8fa4086 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,10 +21,11 @@ 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 java.io.IOException;
+import java.security.PrivilegedExceptionAction;
 import java.util.Collection;
 
 import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.util.StringUtils;
 import org.apache.hadoop.yarn.api.records.ApplicationAttemptReport;
 import org.apache.hadoop.yarn.api.records.ApplicationId;
@@ -70,10 +71,22 @@ public class AppBlock extends HtmlBlock {
       return;
     }
 
+    final ApplicationId appIDFinal = appID;
+    UserGroupInformation callerUGI = getCallerUGI();
     ApplicationReport appReport;
     try {
-      appReport = appContext.getApplication(appID);
-    } catch (IOException e) {
+      if (callerUGI == null) {
+        appReport = appContext.getApplication(appID);
+      } else {
+        appReport = callerUGI.doAs(
+            new PrivilegedExceptionAction<ApplicationReport> () {
+          @Override
+          public ApplicationReport run() throws Exception {
+            return appContext.getApplication(appIDFinal);
+          }
+        });
+      }
+    } catch (Exception e) {
       String message = "Failed to read the application " + appID + ".";
       LOG.error(message, e);
       html.p()._(message)._();
@@ -106,8 +119,18 @@ public class AppBlock extends HtmlBlock {
 
     Collection<ApplicationAttemptReport> attempts;
     try {
-      attempts = appContext.getApplicationAttempts(appID).values();
-    } catch (IOException e) {
+      if (callerUGI == null) {
+        attempts = appContext.getApplicationAttempts(appID).values();
+      } else {
+        attempts = callerUGI.doAs(
+            new PrivilegedExceptionAction<Collection<ApplicationAttemptReport>> () {
+          @Override
+          public Collection<ApplicationAttemptReport> run() throws Exception {
+            return appContext.getApplicationAttempts(appIDFinal).values();
+          }
+        });
+      }
+    } catch (Exception e) {
       String message =
           "Failed to read the attempts of the application " + appID + ".";
       LOG.error(message, e);
@@ -122,14 +145,24 @@ public class AppBlock extends HtmlBlock {
           ._()._().tbody();
 
     StringBuilder attemptsTableData = new StringBuilder("[\n");
-    for (ApplicationAttemptReport appAttemptReport : attempts) {
+    for (final ApplicationAttemptReport appAttemptReport : attempts) {
       AppAttemptInfo appAttempt = new AppAttemptInfo(appAttemptReport);
       ContainerReport containerReport;
       try {
-        containerReport =
-            appContext.getAMContainer(appAttemptReport
+        if (callerUGI == null) {
+          containerReport = appContext.getAMContainer(appAttemptReport
               .getApplicationAttemptId());
-      } catch (IOException e) {
+        } else {
+          containerReport = callerUGI.doAs(
+              new PrivilegedExceptionAction<ContainerReport> () {
+            @Override
+            public ContainerReport run() throws Exception {
+              return appContext.getAMContainer(appAttemptReport
+                  .getApplicationAttemptId());
+            }
+          });
+        }
+      } catch (Exception e) {
         String message =
             "Failed to read the AM container of the application attempt "
                 + appAttemptReport.getApplicationAttemptId() + ".";

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppsBlock.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/AppsBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppsBlock.java
index d4a77a8..f341cf6 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppsBlock.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/AppsBlock.java
@@ -23,11 +23,12 @@ import static org.apache.hadoop.yarn.webapp.YarnWebParams.APP_STATE;
 import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR;
 import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR_VALUE;
 
-import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
 import java.util.Collection;
 import java.util.HashSet;
 
 import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.yarn.api.records.ApplicationReport;
 import org.apache.hadoop.yarn.api.records.YarnApplicationState;
 import org.apache.hadoop.yarn.server.api.ApplicationContext;
@@ -70,10 +71,21 @@ public class AppsBlock extends HtmlBlock {
       }
     }
 
+    UserGroupInformation callerUGI = getCallerUGI();
     Collection<ApplicationReport> appReports;
     try {
-      appReports = appContext.getAllApplications().values();
-    } catch (IOException e) {
+      if (callerUGI == null) {
+        appReports = appContext.getAllApplications().values();
+      } else {
+        appReports = callerUGI.doAs(
+            new PrivilegedExceptionAction<Collection<ApplicationReport>> () {
+          @Override
+          public Collection<ApplicationReport> run() throws Exception {
+            return appContext.getAllApplications().values();
+          }
+        });
+      }
+    } catch (Exception e) {
       String message = "Failed to read the applications.";
       LOG.error(message, e);
       html.p()._(message)._();
@@ -86,7 +98,7 @@ public class AppsBlock extends HtmlBlock {
         continue;
       }
       AppInfo app = new AppInfo(appReport);
-      String percent = String.format("%.1f", app.getProgress());
+      String percent = String.format("%.1f", app.getProgress() * 100.0F);
       // AppID numerical value parsed by parseHadoopID in yarn.dt.plugins.js
       appsTableData
         .append("[\"<a href='")

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/ContainerBlock.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/ContainerBlock.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/ContainerBlock.java
index bda80da..2bb48a8 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/ContainerBlock.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/ContainerBlock.java
@@ -20,10 +20,11 @@ package org.apache.hadoop.yarn.server.webapp;
 import static org.apache.hadoop.yarn.util.StringHelper.join;
 import static org.apache.hadoop.yarn.webapp.YarnWebParams.CONTAINER_ID;
 
-import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.util.StringUtils;
 import org.apache.hadoop.yarn.api.records.ContainerId;
 import org.apache.hadoop.yarn.api.records.ContainerReport;
@@ -63,10 +64,22 @@ public class ContainerBlock extends HtmlBlock {
       return;
     }
 
+    final ContainerId containerIdFinal = containerId;
+    UserGroupInformation callerUGI = getCallerUGI();
     ContainerReport containerReport;
     try {
-      containerReport = appContext.getContainer(containerId);
-    } catch (IOException e) {
+      if (callerUGI == null) {
+        containerReport = appContext.getContainer(containerId);
+      } else {
+        containerReport = callerUGI.doAs(
+            new PrivilegedExceptionAction<ContainerReport> () {
+          @Override
+          public ContainerReport run() throws Exception {
+            return appContext.getContainer(containerIdFinal);
+          }
+        });
+      }
+    } catch (Exception e) {
       String message = "Failed to read the container " + containerid + ".";
       LOG.error(message, e);
       html.p()._(message)._();

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/WebServices.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/WebServices.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/WebServices.java
index 5a82551..ce846b2 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/WebServices.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/WebServices.java
@@ -18,7 +18,7 @@
 
 package org.apache.hadoop.yarn.server.webapp;
 
-import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
@@ -28,6 +28,7 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.WebApplicationException;
 
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
 import org.apache.hadoop.yarn.api.records.ApplicationAttemptReport;
 import org.apache.hadoop.yarn.api.records.ApplicationId;
@@ -60,6 +61,7 @@ public class WebServices {
       String userQuery, String queueQuery, String count, String startedBegin,
       String startedEnd, String finishBegin, String finishEnd,
       Set<String> applicationTypes) {
+    UserGroupInformation callerUGI = getUser(req);
     long num = 0;
     boolean checkCount = false;
     boolean checkStart = false;
@@ -137,8 +139,18 @@ public class WebServices {
     AppsInfo allApps = new AppsInfo();
     Collection<ApplicationReport> appReports = null;
     try {
-      appReports = appContext.getAllApplications().values();
-    } catch (IOException e) {
+      if (callerUGI == null) {
+        appReports = appContext.getAllApplications().values();
+      } else {
+        appReports = callerUGI.doAs(
+            new PrivilegedExceptionAction<Collection<ApplicationReport>> () {
+          @Override
+          public Collection<ApplicationReport> run() throws Exception {
+            return appContext.getAllApplications().values();
+          }
+        });
+      }
+    } catch (Exception e) {
       throw new WebApplicationException(e);
     }
     for (ApplicationReport appReport : appReports) {
@@ -193,11 +205,22 @@ public class WebServices {
 
   public AppInfo getApp(HttpServletRequest req, HttpServletResponse res,
       String appId) {
-    ApplicationId id = parseApplicationId(appId);
+    UserGroupInformation callerUGI = getUser(req);
+    final ApplicationId id = parseApplicationId(appId);
     ApplicationReport app = null;
     try {
-      app = appContext.getApplication(id);
-    } catch (IOException e) {
+      if (callerUGI == null) {
+        app = appContext.getApplication(id);
+      } else {
+        app = callerUGI.doAs(
+            new PrivilegedExceptionAction<ApplicationReport> () {
+          @Override
+          public ApplicationReport run() throws Exception {
+            return appContext.getApplication(id);
+          }
+        });
+      }
+    } catch (Exception e) {
       throw new WebApplicationException(e);
     }
     if (app == null) {
@@ -208,11 +231,22 @@ public class WebServices {
 
   public AppAttemptsInfo getAppAttempts(HttpServletRequest req,
       HttpServletResponse res, String appId) {
-    ApplicationId id = parseApplicationId(appId);
+    UserGroupInformation callerUGI = getUser(req);
+    final ApplicationId id = parseApplicationId(appId);
     Collection<ApplicationAttemptReport> appAttemptReports = null;
     try {
-      appAttemptReports = appContext.getApplicationAttempts(id).values();
-    } catch (IOException e) {
+      if (callerUGI == null) {
+        appAttemptReports = appContext.getApplicationAttempts(id).values();
+      } else {
+        appAttemptReports = callerUGI.doAs(
+            new PrivilegedExceptionAction<Collection<ApplicationAttemptReport>> () {
+          @Override
+          public Collection<ApplicationAttemptReport> run() throws Exception {
+            return appContext.getApplicationAttempts(id).values();
+          }
+        });
+      }
+    } catch (Exception e) {
       throw new WebApplicationException(e);
     }
     AppAttemptsInfo appAttemptsInfo = new AppAttemptsInfo();
@@ -226,13 +260,24 @@ public class WebServices {
 
   public AppAttemptInfo getAppAttempt(HttpServletRequest req,
       HttpServletResponse res, String appId, String appAttemptId) {
+    UserGroupInformation callerUGI = getUser(req);
     ApplicationId aid = parseApplicationId(appId);
-    ApplicationAttemptId aaid = parseApplicationAttemptId(appAttemptId);
+    final ApplicationAttemptId aaid = parseApplicationAttemptId(appAttemptId);
     validateIds(aid, aaid, null);
     ApplicationAttemptReport appAttempt = null;
     try {
-      appAttempt = appContext.getApplicationAttempt(aaid);
-    } catch (IOException e) {
+      if (callerUGI == null) {
+        appAttempt = appContext.getApplicationAttempt(aaid);
+      } else {
+        appAttempt = callerUGI.doAs(
+            new PrivilegedExceptionAction<ApplicationAttemptReport> () {
+          @Override
+          public ApplicationAttemptReport run() throws Exception {
+            return appContext.getApplicationAttempt(aaid);
+          }
+        });
+      }
+    } catch (Exception e) {
       throw new WebApplicationException(e);
     }
     if (appAttempt == null) {
@@ -244,13 +289,24 @@ public class WebServices {
 
   public ContainersInfo getContainers(HttpServletRequest req,
       HttpServletResponse res, String appId, String appAttemptId) {
+    UserGroupInformation callerUGI = getUser(req);
     ApplicationId aid = parseApplicationId(appId);
-    ApplicationAttemptId aaid = parseApplicationAttemptId(appAttemptId);
+    final ApplicationAttemptId aaid = parseApplicationAttemptId(appAttemptId);
     validateIds(aid, aaid, null);
     Collection<ContainerReport> containerReports = null;
     try {
-      containerReports = appContext.getContainers(aaid).values();
-    } catch (IOException e) {
+      if (callerUGI == null) {
+        containerReports = appContext.getContainers(aaid).values();
+      } else {
+        containerReports = callerUGI.doAs(
+            new PrivilegedExceptionAction<Collection<ContainerReport>> () {
+          @Override
+          public Collection<ContainerReport> run() throws Exception {
+            return appContext.getContainers(aaid).values();
+          }
+        });
+      }
+    } catch (Exception e) {
       throw new WebApplicationException(e);
     }
     ContainersInfo containersInfo = new ContainersInfo();
@@ -264,14 +320,25 @@ public class WebServices {
   public ContainerInfo getContainer(HttpServletRequest req,
       HttpServletResponse res, String appId, String appAttemptId,
       String containerId) {
+    UserGroupInformation callerUGI = getUser(req);
     ApplicationId aid = parseApplicationId(appId);
     ApplicationAttemptId aaid = parseApplicationAttemptId(appAttemptId);
-    ContainerId cid = parseContainerId(containerId);
+    final ContainerId cid = parseContainerId(containerId);
     validateIds(aid, aaid, cid);
     ContainerReport container = null;
     try {
-      container = appContext.getContainer(cid);
-    } catch (IOException e) {
+      if (callerUGI == null) {
+        container = appContext.getContainer(cid);
+      } else {
+        container = callerUGI.doAs(
+            new PrivilegedExceptionAction<ContainerReport> () {
+          @Override
+          public ContainerReport run() throws Exception {
+            return appContext.getContainer(cid);
+          }
+        });
+      }
+    } catch (Exception e) {
       throw new WebApplicationException(e);
     }
     if (container == null) {
@@ -364,4 +431,14 @@ public class WebServices {
       throw new NotFoundException("appAttemptId and containerId don't match");
     }
   }
+
+  protected static UserGroupInformation getUser(HttpServletRequest req) {
+    String remoteUser = req.getRemoteUser();
+    UserGroupInformation callerUGI = null;
+    if (remoteUser != null) {
+      callerUGI = UserGroupInformation.createRemoteUser(remoteUser);
+    }
+    return callerUGI;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/dao/AppAttemptInfo.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/dao/AppAttemptInfo.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/dao/AppAttemptInfo.java
index 014ae8b..1ff7028 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/dao/AppAttemptInfo.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/dao/AppAttemptInfo.java
@@ -33,6 +33,7 @@ public class AppAttemptInfo {
   protected String host;
   protected int rpcPort;
   protected String trackingUrl;
+  protected String originalTrackingUrl;
   protected String diagnosticsInfo;
   protected YarnApplicationAttemptState appAttemptState;
   protected String amContainerId;
@@ -46,6 +47,7 @@ public class AppAttemptInfo {
     host = appAttempt.getHost();
     rpcPort = appAttempt.getRpcPort();
     trackingUrl = appAttempt.getTrackingUrl();
+    originalTrackingUrl = appAttempt.getOriginalTrackingUrl();
     diagnosticsInfo = appAttempt.getDiagnostics();
     appAttemptState = appAttempt.getYarnApplicationAttemptState();
     if (appAttempt.getAMContainerId() != null) {
@@ -69,6 +71,10 @@ public class AppAttemptInfo {
     return trackingUrl;
   }
 
+  public String getOriginalTrackingUrl() {
+    return originalTrackingUrl;
+  }
+
   public String getDiagnosticsInfo() {
     return diagnosticsInfo;
   }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/dao/AppInfo.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/dao/AppInfo.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/dao/AppInfo.java
index aedf0d3..d78f928 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/dao/AppInfo.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-common/src/main/java/org/apache/hadoop/yarn/server/webapp/dao/AppInfo.java
@@ -23,7 +23,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.apache.hadoop.yarn.api.records.ApplicationReport;
-import org.apache.hadoop.yarn.api.records.ApplicationResourceUsageReport;
 import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
 import org.apache.hadoop.yarn.api.records.YarnApplicationState;
 import org.apache.hadoop.yarn.util.Times;
@@ -50,8 +49,6 @@ public class AppInfo {
   protected long startedTime;
   protected long finishedTime;
   protected long elapsedTime;
-  protected int allocatedMB;
-  protected int allocatedVCores;
 
   public AppInfo() {
     // JAXB needs this
@@ -77,12 +74,6 @@ public class AppInfo {
     finishedTime = app.getFinishTime();
     elapsedTime = Times.elapsed(startedTime, finishedTime);
     finalAppStatus = app.getFinalApplicationStatus();
-    ApplicationResourceUsageReport usage =
-        app.getApplicationResourceUsageReport();
-    if (usage != null) {
-      allocatedMB = usage.getUsedResources().getMemory();
-      allocatedVCores = usage.getUsedResources().getVirtualCores();
-    }
     progress = app.getProgress();
   }
 
@@ -158,12 +149,4 @@ public class AppInfo {
     return elapsedTime;
   }
 
-  public int getAllocatedMB() {
-    return allocatedMB;
-  }
-
-  public int getAllocatedVCores() {
-    return allocatedVCores;
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMContext.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/RMContext.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMContext.java
index 01d5064..c57469e 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMContext.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMContext.java
@@ -26,6 +26,7 @@ import org.apache.hadoop.yarn.api.records.NodeId;
 import org.apache.hadoop.yarn.conf.ConfigurationProvider;
 import org.apache.hadoop.yarn.event.Dispatcher;
 import org.apache.hadoop.yarn.server.resourcemanager.ahs.RMApplicationHistoryWriter;
+import org.apache.hadoop.yarn.server.resourcemanager.metrics.SystemMetricsPublisher;
 import org.apache.hadoop.yarn.server.resourcemanager.recovery.RMStateStore;
 import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
 import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.AMLivelinessMonitor;
@@ -98,6 +99,10 @@ public interface RMContext {
   void setRMApplicationHistoryWriter(
       RMApplicationHistoryWriter rmApplicationHistoryWriter);
 
+  void setSystemMetricsPublisher(SystemMetricsPublisher systemMetricsPublisher);
+
+  SystemMetricsPublisher getSystemMetricsPublisher();
+
   ConfigurationProvider getConfigurationProvider();
 
   boolean isWorkPreservingRecoveryEnabled();

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMContextImpl.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/RMContextImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMContextImpl.java
index f72ef30..6405718 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMContextImpl.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMContextImpl.java
@@ -30,6 +30,7 @@ import org.apache.hadoop.yarn.conf.ConfigurationProvider;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.event.Dispatcher;
 import org.apache.hadoop.yarn.server.resourcemanager.ahs.RMApplicationHistoryWriter;
+import org.apache.hadoop.yarn.server.resourcemanager.metrics.SystemMetricsPublisher;
 import org.apache.hadoop.yarn.server.resourcemanager.recovery.NullRMStateStore;
 import org.apache.hadoop.yarn.server.resourcemanager.recovery.RMStateStore;
 import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
@@ -81,6 +82,7 @@ public class RMContextImpl implements RMContext {
   private ResourceTrackerService resourceTrackerService;
   private ApplicationMasterService applicationMasterService;
   private RMApplicationHistoryWriter rmApplicationHistoryWriter;
+  private SystemMetricsPublisher systemMetricsPublisher;
   private ConfigurationProvider configurationProvider;
   private int epoch;
 
@@ -346,6 +348,17 @@ public class RMContextImpl implements RMContext {
   }
 
   @Override
+  public void setSystemMetricsPublisher(
+      SystemMetricsPublisher systemMetricsPublisher) {
+    this.systemMetricsPublisher = systemMetricsPublisher;
+  }
+
+  @Override
+  public SystemMetricsPublisher getSystemMetricsPublisher() {
+    return systemMetricsPublisher;
+  }
+
+  @Override
   public void setRMApplicationHistoryWriter(
       RMApplicationHistoryWriter rmApplicationHistoryWriter) {
     this.rmApplicationHistoryWriter = rmApplicationHistoryWriter;

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.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/ResourceManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java
index f315702..0def615 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java
@@ -64,6 +64,7 @@ import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
 import org.apache.hadoop.yarn.server.resourcemanager.ahs.RMApplicationHistoryWriter;
 import org.apache.hadoop.yarn.server.resourcemanager.amlauncher.AMLauncherEventType;
 import org.apache.hadoop.yarn.server.resourcemanager.amlauncher.ApplicationMasterLauncher;
+import org.apache.hadoop.yarn.server.resourcemanager.metrics.SystemMetricsPublisher;
 import org.apache.hadoop.yarn.server.resourcemanager.monitor.SchedulingEditPolicy;
 import org.apache.hadoop.yarn.server.resourcemanager.monitor.SchedulingMonitor;
 import org.apache.hadoop.yarn.server.resourcemanager.recovery.NullRMStateStore;
@@ -306,6 +307,10 @@ public class ResourceManager extends CompositeService implements Recoverable {
     return new RMApplicationHistoryWriter();
   }
 
+  protected SystemMetricsPublisher createSystemMetricsPublisher() {
+    return new SystemMetricsPublisher(); 
+  }
+
   // sanity check for configurations
   protected static void validateConfigs(Configuration conf) {
     // validate max-attempts
@@ -409,6 +414,10 @@ public class ResourceManager extends CompositeService implements Recoverable {
       addService(rmApplicationHistoryWriter);
       rmContext.setRMApplicationHistoryWriter(rmApplicationHistoryWriter);
 
+      SystemMetricsPublisher systemMetricsPublisher = createSystemMetricsPublisher();
+      addService(systemMetricsPublisher);
+      rmContext.setSystemMetricsPublisher(systemMetricsPublisher);
+
       // Register event handler for NodesListManager
       nodesListManager = new NodesListManager(rmContext);
       rmDispatcher.register(NodesListManagerEventType.class, nodesListManager);

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ahs/RMApplicationHistoryWriter.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/ahs/RMApplicationHistoryWriter.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ahs/RMApplicationHistoryWriter.java
index 53d2ab2..58d2e3d 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ahs/RMApplicationHistoryWriter.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ahs/RMApplicationHistoryWriter.java
@@ -85,13 +85,17 @@ public class RMApplicationHistoryWriter extends CompositeService {
         conf.getBoolean(YarnConfiguration.APPLICATION_HISTORY_ENABLED,
           YarnConfiguration.DEFAULT_APPLICATION_HISTORY_ENABLED);
 
-    writer = createApplicationHistoryStore(conf);
-    addIfService(writer);
-
-    dispatcher = createDispatcher(conf);
-    dispatcher.register(WritingHistoryEventType.class,
-      new ForwardingEventHandler());
-    addIfService(dispatcher);
+    // Only create the services when the history service is enabled, preventing
+    // wasting the system resources.
+    if (historyServiceEnabled) {
+      writer = createApplicationHistoryStore(conf);
+      addIfService(writer);
+  
+      dispatcher = createDispatcher(conf);
+      dispatcher.register(WritingHistoryEventType.class,
+        new ForwardingEventHandler());
+      addIfService(dispatcher);
+    }
     super.serviceInit(conf);
   }
 

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/AppAttemptFinishedEvent.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/metrics/AppAttemptFinishedEvent.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/AppAttemptFinishedEvent.java
new file mode 100644
index 0000000..71d9363
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/AppAttemptFinishedEvent.java
@@ -0,0 +1,82 @@
+/**
+ * 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.metrics;
+
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
+import org.apache.hadoop.yarn.api.records.YarnApplicationAttemptState;
+
+public class AppAttemptFinishedEvent extends
+    SystemMetricsEvent {
+
+  private ApplicationAttemptId appAttemptId;
+  private String trackingUrl;
+  private String originalTrackingUrl;
+  private String diagnosticsInfo;
+  private FinalApplicationStatus appStatus;
+  private YarnApplicationAttemptState state;
+
+  public AppAttemptFinishedEvent(
+      ApplicationAttemptId appAttemptId,
+      String trackingUrl,
+      String originalTrackingUrl,
+      String diagnosticsInfo,
+      FinalApplicationStatus appStatus,
+      YarnApplicationAttemptState state,
+      long finishedTime) {
+    super(SystemMetricsEventType.APP_ATTEMPT_FINISHED, finishedTime);
+    this.appAttemptId = appAttemptId;
+    // This is the tracking URL after the application attempt is finished
+    this.trackingUrl = trackingUrl;
+    this.originalTrackingUrl = originalTrackingUrl;
+    this.diagnosticsInfo = diagnosticsInfo;
+    this.appStatus = appStatus;
+    this.state = state;
+  }
+
+  @Override
+  public int hashCode() {
+    return appAttemptId.getApplicationId().hashCode();
+  }
+
+  public ApplicationAttemptId getApplicationAttemptId() {
+    return appAttemptId;
+  }
+
+  public String getTrackingUrl() {
+    return trackingUrl;
+  }
+
+  public String getOriginalTrackingURL() {
+    return originalTrackingUrl;
+  }
+
+  public String getDiagnosticsInfo() {
+    return diagnosticsInfo;
+  }
+
+  public FinalApplicationStatus getFinalApplicationStatus() {
+    return appStatus;
+  }
+
+  public YarnApplicationAttemptState getYarnApplicationAttemptState() {
+    return state;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/AppAttemptRegisteredEvent.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/metrics/AppAttemptRegisteredEvent.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/AppAttemptRegisteredEvent.java
new file mode 100644
index 0000000..1d0f16d
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/AppAttemptRegisteredEvent.java
@@ -0,0 +1,81 @@
+/**
+ * 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.metrics;
+
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+
+public class AppAttemptRegisteredEvent extends
+    SystemMetricsEvent {
+
+  private ApplicationAttemptId appAttemptId;
+  private String host;
+  private int rpcPort;
+  private String trackingUrl;
+  private String originalTrackingUrl;
+  private ContainerId masterContainerId;
+
+  public AppAttemptRegisteredEvent(
+      ApplicationAttemptId appAttemptId,
+      String host,
+      int rpcPort,
+      String trackingUrl,
+      String originalTrackingUrl,
+      ContainerId masterContainerId,
+      long registeredTime) {
+    super(SystemMetricsEventType.APP_ATTEMPT_REGISTERED, registeredTime);
+    this.appAttemptId = appAttemptId;
+    this.host = host;
+    this.rpcPort = rpcPort;
+    // This is the tracking URL after the application attempt is registered
+    this.trackingUrl = trackingUrl;
+    this.originalTrackingUrl = originalTrackingUrl;
+    this.masterContainerId = masterContainerId;
+  }
+
+  @Override
+  public int hashCode() {
+    return appAttemptId.getApplicationId().hashCode();
+  }
+
+  public ApplicationAttemptId getApplicationAttemptId() {
+    return appAttemptId;
+  }
+
+  public String getHost() {
+    return host;
+  }
+
+  public int getRpcPort() {
+    return rpcPort;
+  }
+
+  public String getTrackingUrl() {
+    return trackingUrl;
+  }
+
+  public String getOriginalTrackingURL() {
+    return originalTrackingUrl;
+  }
+
+  public ContainerId getMasterContainerId() {
+    return masterContainerId;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ApplicationCreatedEvent.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/metrics/ApplicationCreatedEvent.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ApplicationCreatedEvent.java
new file mode 100644
index 0000000..2373b3b
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ApplicationCreatedEvent.java
@@ -0,0 +1,78 @@
+/**
+ * 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.metrics;
+
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+
+public class ApplicationCreatedEvent extends
+    SystemMetricsEvent {
+
+  private ApplicationId appId;
+  private String name;
+  private String type;
+  private String user;
+  private String queue;
+  private long submittedTime;
+
+  public ApplicationCreatedEvent(ApplicationId appId,
+      String name,
+      String type,
+      String user,
+      String queue,
+      long submittedTime,
+      long createdTime) {
+    super(SystemMetricsEventType.APP_CREATED, createdTime);
+    this.appId = appId;
+    this.name = name;
+    this.type = type;
+    this.user = user;
+    this.queue = queue;
+    this.submittedTime = submittedTime;
+  }
+
+  @Override
+  public int hashCode() {
+    return appId.hashCode();
+  }
+
+  public ApplicationId getApplicationId() {
+    return appId;
+  }
+
+  public String getApplicationName() {
+    return name;
+  }
+
+  public String getApplicationType() {
+    return type;
+  }
+
+  public String getUser() {
+    return user;
+  }
+
+  public String getQueue() {
+    return queue;
+  }
+
+  public long getSubmittedTime() {
+    return submittedTime;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ApplicationFinishedEvent.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/metrics/ApplicationFinishedEvent.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ApplicationFinishedEvent.java
new file mode 100644
index 0000000..c457710
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ApplicationFinishedEvent.java
@@ -0,0 +1,75 @@
+/**
+ * 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.metrics;
+
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
+import org.apache.hadoop.yarn.api.records.YarnApplicationState;
+
+public class ApplicationFinishedEvent extends
+    SystemMetricsEvent {
+
+  private ApplicationId appId;;
+  private String diagnosticsInfo;
+  private FinalApplicationStatus appStatus;
+  private YarnApplicationState state;
+  private ApplicationAttemptId latestAppAttemptId;
+
+  public ApplicationFinishedEvent(
+      ApplicationId appId,
+      String diagnosticsInfo,
+      FinalApplicationStatus appStatus,
+      YarnApplicationState state,
+      ApplicationAttemptId latestAppAttemptId,
+      long finishedTime) {
+    super(SystemMetricsEventType.APP_FINISHED, finishedTime);
+    this.appId = appId;
+    this.diagnosticsInfo = diagnosticsInfo;
+    this.appStatus = appStatus;
+    this.latestAppAttemptId = latestAppAttemptId;
+    this.state = state;
+  }
+
+  @Override
+  public int hashCode() {
+    return appId.hashCode();
+  }
+
+  public ApplicationId getApplicationId() {
+    return appId;
+  }
+
+  public String getDiagnosticsInfo() {
+    return diagnosticsInfo;
+  }
+
+  public FinalApplicationStatus getFinalApplicationStatus() {
+    return appStatus;
+  }
+
+  public YarnApplicationState getYarnApplicationState() {
+    return state;
+  }
+
+  public ApplicationAttemptId getLatestApplicationAttemptId() {
+    return latestAppAttemptId;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ContainerCreatedEvent.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/metrics/ContainerCreatedEvent.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ContainerCreatedEvent.java
new file mode 100644
index 0000000..eeda181
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ContainerCreatedEvent.java
@@ -0,0 +1,67 @@
+/**
+ * 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.metrics;
+
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.api.records.Priority;
+import org.apache.hadoop.yarn.api.records.Resource;
+
+public class ContainerCreatedEvent extends SystemMetricsEvent {
+
+  private ContainerId containerId;
+  private Resource allocatedResource;
+  private NodeId allocatedNode;
+  private Priority allocatedPriority;
+
+  public ContainerCreatedEvent(
+      ContainerId containerId,
+      Resource allocatedResource,
+      NodeId allocatedNode,
+      Priority allocatedPriority,
+      long createdTime) {
+    super(SystemMetricsEventType.CONTAINER_CREATED, createdTime);
+    this.containerId = containerId;
+    this.allocatedResource = allocatedResource;
+    this.allocatedNode = allocatedNode;
+    this.allocatedPriority = allocatedPriority;
+  }
+
+  @Override
+  public int hashCode() {
+    return containerId.getApplicationAttemptId().getApplicationId().hashCode();
+  }
+
+  public ContainerId getContainerId() {
+    return containerId;
+  }
+
+  public Resource getAllocatedResource() {
+    return allocatedResource;
+  }
+
+  public NodeId getAllocatedNode() {
+    return allocatedNode;
+  }
+
+  public Priority getAllocatedPriority() {
+    return allocatedPriority;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ContainerFinishedEvent.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/metrics/ContainerFinishedEvent.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ContainerFinishedEvent.java
new file mode 100644
index 0000000..aafd760
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/ContainerFinishedEvent.java
@@ -0,0 +1,65 @@
+/**
+ * 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.metrics;
+
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.api.records.ContainerState;
+
+public class ContainerFinishedEvent extends SystemMetricsEvent {
+
+  private ContainerId containerId;
+  private String diagnosticsInfo;
+  private int containerExitStatus;
+  private ContainerState state;
+
+  public ContainerFinishedEvent(
+      ContainerId containerId,
+      String diagnosticsInfo,
+      int containerExitStatus,
+      ContainerState state,
+      long finishedTime) {
+    super(SystemMetricsEventType.CONTAINER_FINISHED, finishedTime);
+    this.containerId = containerId;
+    this.diagnosticsInfo = diagnosticsInfo;
+    this.containerExitStatus = containerExitStatus;
+    this.state = state;
+  }
+
+  @Override
+  public int hashCode() {
+    return containerId.getApplicationAttemptId().getApplicationId().hashCode();
+  }
+
+  public ContainerId getContainerId() {
+    return containerId;
+  }
+
+  public String getDiagnosticsInfo() {
+    return diagnosticsInfo;
+  }
+
+  public int getContainerExitStatus() {
+    return containerExitStatus;
+  }
+
+  public ContainerState getContainerState() {
+    return state;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/SystemMetricsEvent.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/metrics/SystemMetricsEvent.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/SystemMetricsEvent.java
new file mode 100644
index 0000000..1847396
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/SystemMetricsEvent.java
@@ -0,0 +1,33 @@
+/**
+ * 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.metrics;
+
+import org.apache.hadoop.yarn.event.AbstractEvent;
+
+public class SystemMetricsEvent extends AbstractEvent<SystemMetricsEventType> {
+
+  public SystemMetricsEvent(SystemMetricsEventType type) {
+    super(type);
+  }
+
+  public SystemMetricsEvent(SystemMetricsEventType type, long timestamp) {
+    super(type, timestamp);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/SystemMetricsEventType.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/metrics/SystemMetricsEventType.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/SystemMetricsEventType.java
new file mode 100644
index 0000000..c593f69
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/SystemMetricsEventType.java
@@ -0,0 +1,34 @@
+/**
+ * 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.metrics;
+
+
+public enum SystemMetricsEventType {
+  // app events
+  APP_CREATED,
+  APP_FINISHED,
+
+  // app attempt events
+  APP_ATTEMPT_REGISTERED,
+  APP_ATTEMPT_FINISHED,
+
+  // container events
+  CONTAINER_CREATED,
+  CONTAINER_FINISHED
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/SystemMetricsPublisher.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/metrics/SystemMetricsPublisher.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/SystemMetricsPublisher.java
new file mode 100644
index 0000000..886f57d
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/metrics/SystemMetricsPublisher.java
@@ -0,0 +1,490 @@
+/**
+ * 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.metrics;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.classification.InterfaceAudience.Private;
+import org.apache.hadoop.classification.InterfaceStability.Unstable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.token.Token;
+import org.apache.hadoop.service.CompositeService;
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.api.records.timeline.TimelineEntity;
+import org.apache.hadoop.yarn.api.records.timeline.TimelineEvent;
+import org.apache.hadoop.yarn.client.api.TimelineClient;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.hadoop.yarn.event.Dispatcher;
+import org.apache.hadoop.yarn.event.Event;
+import org.apache.hadoop.yarn.event.EventHandler;
+import org.apache.hadoop.yarn.security.client.TimelineDelegationTokenIdentifier;
+import org.apache.hadoop.yarn.server.metrics.AppAttemptMetricsConstants;
+import org.apache.hadoop.yarn.server.metrics.ApplicationMetricsConstants;
+import org.apache.hadoop.yarn.server.metrics.ContainerMetricsConstants;
+import org.apache.hadoop.yarn.server.resourcemanager.RMServerUtils;
+import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
+import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState;
+import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt;
+import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptState;
+import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainer;
+import org.apache.hadoop.yarn.util.timeline.TimelineUtils;
+
+@Private
+@Unstable
+public class SystemMetricsPublisher extends CompositeService {
+
+  private static final Log LOG = LogFactory
+      .getLog(SystemMetricsPublisher.class);
+  private static final int MAX_GET_TIMELINE_DELEGATION_TOKEN_ATTEMPTS = 10;
+
+  private Dispatcher dispatcher;
+  private TimelineClient client;
+  private boolean publishSystemMetrics;
+  private int getTimelineDelegtionTokenAttempts = 0;
+  private boolean hasReceivedTimelineDelegtionToken = false;
+
+  public SystemMetricsPublisher() {
+    super(SystemMetricsPublisher.class.getName());
+  }
+
+  @Override
+  protected void serviceInit(Configuration conf) throws Exception {
+    publishSystemMetrics =
+        conf.getBoolean(YarnConfiguration.TIMELINE_SERVICE_ENABLED,
+            YarnConfiguration.DEFAULT_TIMELINE_SERVICE_ENABLED) &&
+        conf.getBoolean(YarnConfiguration.RM_SYSTEM_METRICS_PUBLISHER_ENABLED,
+            YarnConfiguration.DEFAULT_RM_SYSTEM_METRICS_PUBLISHER_ENABLED);
+
+    if (publishSystemMetrics) {
+      client = TimelineClient.createTimelineClient();
+      addIfService(client);
+
+      dispatcher = createDispatcher(conf);
+      dispatcher.register(SystemMetricsEventType.class,
+          new ForwardingEventHandler());
+      addIfService(dispatcher);
+      LOG.info("YARN system metrics publishing service is enabled");
+    } else {
+      LOG.info("YARN system metrics publishing service is not enabled");
+    }
+    super.serviceInit(conf);
+  }
+
+  @SuppressWarnings("unchecked")
+  public void appCreated(RMApp app, long createdTime) {
+    if (publishSystemMetrics) {
+      dispatcher.getEventHandler().handle(
+          new ApplicationCreatedEvent(
+              app.getApplicationId(),
+              app.getName(),
+              app.getApplicationType(),
+              app.getUser(),
+              app.getQueue(),
+              app.getSubmitTime(),
+              createdTime));
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void appFinished(RMApp app, RMAppState state, long finishedTime) {
+    if (publishSystemMetrics) {
+      dispatcher.getEventHandler().handle(
+          new ApplicationFinishedEvent(
+              app.getApplicationId(),
+              app.getDiagnostics().toString(),
+              app.getFinalApplicationStatus(),
+              RMServerUtils.createApplicationState(state),
+              app.getCurrentAppAttempt() == null ?
+                  null : app.getCurrentAppAttempt().getAppAttemptId(),
+              finishedTime));
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void appAttemptRegistered(RMAppAttempt appAttempt,
+      long registeredTime) {
+    if (publishSystemMetrics) {
+      dispatcher.getEventHandler().handle(
+          new AppAttemptRegisteredEvent(
+              appAttempt.getAppAttemptId(),
+              appAttempt.getHost(),
+              appAttempt.getRpcPort(),
+              appAttempt.getTrackingUrl(),
+              appAttempt.getOriginalTrackingUrl(),
+              appAttempt.getMasterContainer().getId(),
+              registeredTime));
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void appAttemptFinished(RMAppAttempt appAttempt,
+      RMAppAttemptState state, long finishedTime) {
+    if (publishSystemMetrics) {
+      dispatcher.getEventHandler().handle(
+          new AppAttemptFinishedEvent(
+              appAttempt.getAppAttemptId(),
+              appAttempt.getTrackingUrl(),
+              appAttempt.getOriginalTrackingUrl(),
+              appAttempt.getDiagnostics(),
+              appAttempt.getFinalApplicationStatus(),
+              RMServerUtils.createApplicationAttemptState(state),
+              finishedTime));
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void containerCreated(RMContainer container, long createdTime) {
+    if (publishSystemMetrics) {
+      dispatcher.getEventHandler().handle(
+          new ContainerCreatedEvent(
+              container.getContainerId(),
+              container.getAllocatedResource(),
+              container.getAllocatedNode(),
+              container.getAllocatedPriority(),
+              createdTime));
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public void containerFinished(RMContainer container, long finishedTime) {
+    if (publishSystemMetrics) {
+      dispatcher.getEventHandler().handle(
+          new ContainerFinishedEvent(
+              container.getContainerId(),
+              container.getDiagnosticsInfo(),
+              container.getContainerExitStatus(),
+              container.getContainerState(),
+              finishedTime));
+    }
+  }
+
+  protected Dispatcher createDispatcher(Configuration conf) {
+    MultiThreadedDispatcher dispatcher =
+        new MultiThreadedDispatcher(
+            conf.getInt(
+                YarnConfiguration.RM_SYSTEM_METRICS_PUBLISHER_DISPATCHER_POOL_SIZE,
+                YarnConfiguration.DEFAULT_RM_SYSTEM_METRICS_PUBLISHER_DISPATCHER_POOL_SIZE));
+    dispatcher.setDrainEventsOnStop();
+    return dispatcher;
+  }
+
+  protected void handleSystemMetricsEvent(
+      SystemMetricsEvent event) {
+    switch (event.getType()) {
+      case APP_CREATED:
+        publishApplicationCreatedEvent((ApplicationCreatedEvent) event);
+        break;
+      case APP_FINISHED:
+        publishApplicationFinishedEvent((ApplicationFinishedEvent) event);
+        break;
+      case APP_ATTEMPT_REGISTERED:
+        publishAppAttemptRegisteredEvent((AppAttemptRegisteredEvent) event);
+        break;
+      case APP_ATTEMPT_FINISHED:
+        publishAppAttemptFinishedEvent((AppAttemptFinishedEvent) event);
+        break;
+      case CONTAINER_CREATED:
+        publishContainerCreatedEvent((ContainerCreatedEvent) event);
+        break;
+      case CONTAINER_FINISHED:
+        publishContainerFinishedEvent((ContainerFinishedEvent) event);
+        break;
+      default:
+        LOG.error("Unknown SystemMetricsEvent type: " + event.getType());
+    }
+  }
+
+  private void publishApplicationCreatedEvent(ApplicationCreatedEvent event) {
+    TimelineEntity entity =
+        createApplicationEntity(event.getApplicationId());
+    Map<String, Object> entityInfo = new HashMap<String, Object>();
+    entityInfo.put(ApplicationMetricsConstants.NAME_ENTITY_INFO,
+        event.getApplicationName());
+    entityInfo.put(ApplicationMetricsConstants.TYPE_ENTITY_INFO,
+        event.getApplicationType());
+    entityInfo.put(ApplicationMetricsConstants.USER_ENTITY_INFO,
+        event.getUser());
+    entityInfo.put(ApplicationMetricsConstants.QUEUE_ENTITY_INFO,
+        event.getQueue());
+    entityInfo.put(ApplicationMetricsConstants.SUBMITTED_TIME_ENTITY_INFO,
+        event.getSubmittedTime());
+    entity.setOtherInfo(entityInfo);
+    TimelineEvent tEvent = new TimelineEvent();
+    tEvent.setEventType(
+        ApplicationMetricsConstants.CREATED_EVENT_TYPE);
+    tEvent.setTimestamp(event.getTimestamp());
+    entity.addEvent(tEvent);
+    putEntity(entity);
+  }
+
+  private void publishApplicationFinishedEvent(ApplicationFinishedEvent event) {
+    TimelineEntity entity =
+        createApplicationEntity(event.getApplicationId());
+    TimelineEvent tEvent = new TimelineEvent();
+    tEvent.setEventType(
+        ApplicationMetricsConstants.FINISHED_EVENT_TYPE);
+    tEvent.setTimestamp(event.getTimestamp());
+    Map<String, Object> eventInfo = new HashMap<String, Object>();
+    eventInfo.put(ApplicationMetricsConstants.DIAGNOSTICS_INFO_EVENT_INFO,
+        event.getDiagnosticsInfo());
+    eventInfo.put(ApplicationMetricsConstants.FINAL_STATUS_EVENT_INFO,
+        event.getFinalApplicationStatus().toString());
+    eventInfo.put(ApplicationMetricsConstants.STATE_EVENT_INFO,
+        event.getYarnApplicationState().toString());
+    if (event.getLatestApplicationAttemptId() != null) {
+      eventInfo.put(ApplicationMetricsConstants.LATEST_APP_ATTEMPT_EVENT_INFO,
+          event.getLatestApplicationAttemptId().toString());
+    }
+    tEvent.setEventInfo(eventInfo);
+    entity.addEvent(tEvent);
+    putEntity(entity);
+  }
+
+  private static TimelineEntity createApplicationEntity(
+      ApplicationId applicationId) {
+    TimelineEntity entity = new TimelineEntity();
+    entity.setEntityType(ApplicationMetricsConstants.ENTITY_TYPE);
+    entity.setEntityId(applicationId.toString());
+    return entity;
+  }
+
+  private void
+      publishAppAttemptRegisteredEvent(AppAttemptRegisteredEvent event) {
+    TimelineEntity entity =
+        createAppAttemptEntity(event.getApplicationAttemptId());
+    TimelineEvent tEvent = new TimelineEvent();
+    tEvent.setEventType(
+        AppAttemptMetricsConstants.REGISTERED_EVENT_TYPE);
+    tEvent.setTimestamp(event.getTimestamp());
+    Map<String, Object> eventInfo = new HashMap<String, Object>();
+    eventInfo.put(
+        AppAttemptMetricsConstants.TRACKING_URL_EVENT_INFO,
+        event.getTrackingUrl());
+    eventInfo.put(
+        AppAttemptMetricsConstants.ORIGINAL_TRACKING_URL_EVENT_INFO,
+        event.getOriginalTrackingURL());
+    eventInfo.put(AppAttemptMetricsConstants.HOST_EVENT_INFO,
+        event.getHost());
+    eventInfo.put(AppAttemptMetricsConstants.RPC_PORT_EVENT_INFO,
+        event.getRpcPort());
+    eventInfo.put(
+        AppAttemptMetricsConstants.MASTER_CONTAINER_EVENT_INFO,
+        event.getMasterContainerId().toString());
+    tEvent.setEventInfo(eventInfo);
+    entity.addEvent(tEvent);
+    putEntity(entity);
+  }
+
+  private void publishAppAttemptFinishedEvent(AppAttemptFinishedEvent event) {
+    TimelineEntity entity =
+        createAppAttemptEntity(event.getApplicationAttemptId());
+    TimelineEvent tEvent = new TimelineEvent();
+    tEvent.setEventType(AppAttemptMetricsConstants.FINISHED_EVENT_TYPE);
+    tEvent.setTimestamp(event.getTimestamp());
+    Map<String, Object> eventInfo = new HashMap<String, Object>();
+    eventInfo.put(
+        AppAttemptMetricsConstants.TRACKING_URL_EVENT_INFO,
+        event.getTrackingUrl());
+    eventInfo.put(
+        AppAttemptMetricsConstants.ORIGINAL_TRACKING_URL_EVENT_INFO,
+        event.getOriginalTrackingURL());
+    eventInfo.put(AppAttemptMetricsConstants.DIAGNOSTICS_INFO_EVENT_INFO,
+        event.getDiagnosticsInfo());
+    eventInfo.put(AppAttemptMetricsConstants.FINAL_STATUS_EVENT_INFO,
+        event.getFinalApplicationStatus().toString());
+    eventInfo.put(AppAttemptMetricsConstants.STATE_EVENT_INFO,
+        event.getYarnApplicationAttemptState().toString());
+    tEvent.setEventInfo(eventInfo);
+    entity.addEvent(tEvent);
+    putEntity(entity);
+  }
+
+  private static TimelineEntity createAppAttemptEntity(
+      ApplicationAttemptId appAttemptId) {
+    TimelineEntity entity = new TimelineEntity();
+    entity.setEntityType(
+        AppAttemptMetricsConstants.ENTITY_TYPE);
+    entity.setEntityId(appAttemptId.toString());
+    entity.addPrimaryFilter(AppAttemptMetricsConstants.PARENT_PRIMARY_FILTER,
+        appAttemptId.getApplicationId().toString());
+    return entity;
+  }
+
+  private void publishContainerCreatedEvent(ContainerCreatedEvent event) {
+    TimelineEntity entity = createContainerEntity(event.getContainerId());
+    Map<String, Object> entityInfo = new HashMap<String, Object>();
+    entityInfo.put(ContainerMetricsConstants.ALLOCATED_MEMORY_ENTITY_INFO,
+        event.getAllocatedResource().getMemory());
+    entityInfo.put(ContainerMetricsConstants.ALLOCATED_VCORE_ENTITY_INFO,
+        event.getAllocatedResource().getVirtualCores());
+    entityInfo.put(ContainerMetricsConstants.ALLOCATED_HOST_ENTITY_INFO,
+        event.getAllocatedNode().getHost());
+    entityInfo.put(ContainerMetricsConstants.ALLOCATED_PORT_ENTITY_INFO,
+        event.getAllocatedNode().getPort());
+    entityInfo.put(ContainerMetricsConstants.ALLOCATED_PRIORITY_ENTITY_INFO,
+        event.getAllocatedPriority().getPriority());
+    entity.setOtherInfo(entityInfo);
+    TimelineEvent tEvent = new TimelineEvent();
+    tEvent.setEventType(ContainerMetricsConstants.CREATED_EVENT_TYPE);
+    tEvent.setTimestamp(event.getTimestamp());
+    entity.addEvent(tEvent);
+    putEntity(entity);
+  }
+
+  private void publishContainerFinishedEvent(ContainerFinishedEvent event) {
+    TimelineEntity entity = createContainerEntity(event.getContainerId());
+    TimelineEvent tEvent = new TimelineEvent();
+    tEvent.setEventType(ContainerMetricsConstants.FINISHED_EVENT_TYPE);
+    tEvent.setTimestamp(event.getTimestamp());
+    Map<String, Object> eventInfo = new HashMap<String, Object>();
+    eventInfo.put(ContainerMetricsConstants.DIAGNOSTICS_INFO_EVENT_INFO,
+        event.getDiagnosticsInfo());
+    eventInfo.put(ContainerMetricsConstants.EXIT_STATUS_EVENT_INFO,
+        event.getContainerExitStatus());
+    eventInfo.put(ContainerMetricsConstants.STATE_EVENT_INFO,
+        event.getContainerState().toString());
+    tEvent.setEventInfo(eventInfo);
+    entity.addEvent(tEvent);
+    putEntity(entity);
+  }
+
+  private static TimelineEntity createContainerEntity(
+      ContainerId containerId) {
+    TimelineEntity entity = new TimelineEntity();
+    entity.setEntityType(
+        ContainerMetricsConstants.ENTITY_TYPE);
+    entity.setEntityId(containerId.toString());
+    entity.addPrimaryFilter(ContainerMetricsConstants.PARENT_PRIMARIY_FILTER,
+        containerId.getApplicationAttemptId().toString());
+    return entity;
+  }
+
+  private void putEntity(TimelineEntity entity) {
+    if (UserGroupInformation.isSecurityEnabled()) {
+      if (!hasReceivedTimelineDelegtionToken
+          && getTimelineDelegtionTokenAttempts < MAX_GET_TIMELINE_DELEGATION_TOKEN_ATTEMPTS) {
+        try {
+          Token<TimelineDelegationTokenIdentifier> token =
+              client.getDelegationToken(
+                  UserGroupInformation.getCurrentUser().getUserName());
+          UserGroupInformation.getCurrentUser().addToken(token);
+          hasReceivedTimelineDelegtionToken = true;
+        } catch (Exception e) {
+          LOG.error("Error happens when getting timeline delegation token", e);
+        } finally {
+          ++getTimelineDelegtionTokenAttempts;
+          if (!hasReceivedTimelineDelegtionToken
+              && getTimelineDelegtionTokenAttempts == MAX_GET_TIMELINE_DELEGATION_TOKEN_ATTEMPTS) {
+            LOG.error("Run out of the attempts to get timeline delegation token. " +
+              "Use kerberos authentication only.");
+          }
+        }
+      }
+    }
+    try {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Publishing the entity " + entity.getEntityId() +
+            ", JSON-style content: " + TimelineUtils.dumpTimelineRecordtoJSON(entity));
+      }
+      client.putEntities(entity);
+    } catch (Exception e) {
+      LOG.error("Error when publishing entity [" + entity.getEntityType() + ","
+          + entity.getEntityId() + "]", e);
+    }
+  }
+
+  /**
+   * EventHandler implementation which forward events to SystemMetricsPublisher.
+   * Making use of it, SystemMetricsPublisher can avoid to have a public handle
+   * method.
+   */
+  private final class ForwardingEventHandler implements
+      EventHandler<SystemMetricsEvent> {
+
+    @Override
+    public void handle(SystemMetricsEvent event) {
+      handleSystemMetricsEvent(event);
+    }
+
+  }
+
+  @SuppressWarnings({ "rawtypes", "unchecked" })
+  protected static class MultiThreadedDispatcher extends CompositeService
+      implements Dispatcher {
+
+    private List<AsyncDispatcher> dispatchers =
+        new ArrayList<AsyncDispatcher>();
+
+    public MultiThreadedDispatcher(int num) {
+      super(MultiThreadedDispatcher.class.getName());
+      for (int i = 0; i < num; ++i) {
+        AsyncDispatcher dispatcher = createDispatcher();
+        dispatchers.add(dispatcher);
+        addIfService(dispatcher);
+      }
+    }
+
+    @Override
+    public EventHandler getEventHandler() {
+      return new CompositEventHandler();
+    }
+
+    @Override
+    public void register(Class<? extends Enum> eventType, EventHandler handler) {
+      for (AsyncDispatcher dispatcher : dispatchers) {
+        dispatcher.register(eventType, handler);
+      }
+    }
+
+    public void setDrainEventsOnStop() {
+      for (AsyncDispatcher dispatcher : dispatchers) {
+        dispatcher.setDrainEventsOnStop();
+      }
+    }
+
+    private class CompositEventHandler implements EventHandler<Event> {
+
+      @Override
+      public void handle(Event event) {
+        // Use hashCode (of ApplicationId) to dispatch the event to the child
+        // dispatcher, such that all the writing events of one application will
+        // be handled by one thread, the scheduled order of the these events
+        // will be preserved
+        int index = (event.hashCode() & Integer.MAX_VALUE) % dispatchers.size();
+        dispatchers.get(index).getEventHandler().handle(event);
+      }
+
+    }
+
+    protected AsyncDispatcher createDispatcher() {
+      return new AsyncDispatcher();
+    }
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMApp.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/rmapp/RMApp.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMApp.java
index bf374b4..a1ae3ca 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMApp.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMApp.java
@@ -172,6 +172,12 @@ public interface RMApp extends EventHandler<RMAppEvent> {
   String getTrackingUrl();
 
   /**
+   * The original tracking url for the application master.
+   * @return the original tracking url for the application master.
+   */
+  String getOriginalTrackingUrl();
+
+  /**
    * the diagnostics information for the application master.
    * @return the diagnostics information for the application master.
    */

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMAppImpl.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/rmapp/RMAppImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMAppImpl.java
index 5b6df00..2dd2040 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMAppImpl.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMAppImpl.java
@@ -365,6 +365,7 @@ public class RMAppImpl implements RMApp, Recoverable {
     this.stateMachine = stateMachineFactory.make(this);
 
     rmContext.getRMApplicationHistoryWriter().applicationStarted(this);
+    rmContext.getSystemMetricsPublisher().appCreated(this, startTime);
   }
 
   @Override
@@ -628,6 +629,20 @@ public class RMAppImpl implements RMApp, Recoverable {
   }
 
   @Override
+  public String getOriginalTrackingUrl() {
+    this.readLock.lock();
+    
+    try {
+      if (this.currentAttempt != null) {
+        return this.currentAttempt.getOriginalTrackingUrl();
+      }
+      return null;
+    } finally {
+      this.readLock.unlock();
+    }
+  }
+
+  @Override
   public StringBuilder getDiagnostics() {
     this.readLock.lock();
 
@@ -1096,6 +1111,8 @@ public class RMAppImpl implements RMApp, Recoverable {
 
       app.rmContext.getRMApplicationHistoryWriter()
           .applicationFinished(app, finalState);
+      app.rmContext.getSystemMetricsPublisher()
+          .appFinished(app, finalState, app.finishTime);
     };
   }
 

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/attempt/RMAppAttemptImpl.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/rmapp/attempt/RMAppAttemptImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/attempt/RMAppAttemptImpl.java
index 93db340..1489696 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/attempt/RMAppAttemptImpl.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/attempt/RMAppAttemptImpl.java
@@ -1156,6 +1156,9 @@ public class RMAppAttemptImpl implements RMAppAttempt, Recoverable {
 
       appAttempt.rmContext.getRMApplicationHistoryWriter()
           .applicationAttemptFinished(appAttempt, finalAttemptState);
+      appAttempt.rmContext.getSystemMetricsPublisher()
+          .appAttemptFinished(
+              appAttempt, finalAttemptState, System.currentTimeMillis());
     }
   }
 
@@ -1269,6 +1272,8 @@ public class RMAppAttemptImpl implements RMAppAttempt, Recoverable {
 
       appAttempt.rmContext.getRMApplicationHistoryWriter()
           .applicationAttemptStarted(appAttempt);
+      appAttempt.rmContext.getSystemMetricsPublisher()
+          .appAttemptRegistered(appAttempt, System.currentTimeMillis());
     }
   }
 
@@ -1723,8 +1728,8 @@ public class RMAppAttemptImpl implements RMAppAttempt, Recoverable {
           masterContainer == null ? null : masterContainer.getId();
       attemptReport = ApplicationAttemptReport.newInstance(this
           .getAppAttemptId(), this.getHost(), this.getRpcPort(), this
-          .getTrackingUrl(), this.getDiagnostics(), YarnApplicationAttemptState
-          .valueOf(this.getState().toString()), amId);
+          .getTrackingUrl(), this.getOriginalTrackingUrl(), this.getDiagnostics(),
+          YarnApplicationAttemptState .valueOf(this.getState().toString()), amId);
     } finally {
       this.readLock.unlock();
     }

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/RMContainerImpl.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/rmcontainer/RMContainerImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/RMContainerImpl.java
index e7bb98e..885e864 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/RMContainerImpl.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/RMContainerImpl.java
@@ -192,6 +192,8 @@ public class RMContainerImpl implements RMContainer {
     this.writeLock = lock.writeLock();
 
     rmContext.getRMApplicationHistoryWriter().containerStarted(this);
+    rmContext.getSystemMetricsPublisher().containerCreated(
+        this, this.creationTime);
   }
 
   @Override
@@ -497,6 +499,8 @@ public class RMContainerImpl implements RMContainer {
 
       container.rmContext.getRMApplicationHistoryWriter().containerFinished(
         container);
+      container.rmContext.getSystemMetricsPublisher().containerFinished(
+          container, container.finishTime);
     }
 
     private static void updateAttemptMetrics(RMContainerImpl container) {

http://git-wip-us.apache.org/repos/asf/hadoop/blob/6b8b1608/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAppManager.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAppManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAppManager.java
index d720eb6..e3f1eba 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAppManager.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/TestAppManager.java
@@ -21,6 +21,7 @@ package org.apache.hadoop.yarn.server.resourcemanager;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.yarn.server.resourcemanager.metrics.SystemMetricsPublisher;
 import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppImpl;
 import static org.mockito.Matchers.isA;
 import static org.mockito.Mockito.mock;
@@ -119,6 +120,8 @@ public class TestAppManager{
       }
     };
     ((RMContextImpl)context).setStateStore(mock(RMStateStore.class));
+    ((RMContextImpl)context).setSystemMetricsPublisher(
+        mock(SystemMetricsPublisher.class));
     return context;
   }
 


Mime
View raw message