You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tez.apache.org by ac...@apache.org on 2013/03/15 22:26:48 UTC

svn commit: r1457129 [29/38] - in /incubator/tez: ./ tez-ampool/ tez-ampool/src/ tez-ampool/src/main/ tez-ampool/src/main/bin/ tez-ampool/src/main/conf/ tez-ampool/src/main/java/ tez-ampool/src/main/java/org/ tez-ampool/src/main/java/org/apache/ tez-am...

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JAXBContextResolver.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JAXBContextResolver.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JAXBContextResolver.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JAXBContextResolver.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,80 @@
+/**
+* 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.mapreduce.v2.app2.webapp;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Arrays;
+
+import com.sun.jersey.api.json.JSONConfiguration;
+import com.sun.jersey.api.json.JSONJAXBContext;
+import com.google.inject.Singleton;
+
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.Provider;
+import javax.xml.bind.JAXBContext;
+
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.AMAttemptInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.AMAttemptsInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.AppInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.ConfInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.ConfEntryInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.CounterGroupInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.CounterInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.JobCounterInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.JobInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.JobsInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.JobTaskAttemptCounterInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.JobTaskCounterInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.ReduceTaskAttemptInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.TaskAttemptInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.TaskAttemptsInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.TaskCounterGroupInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.TaskCounterInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.TaskInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.TasksInfo;
+import org.apache.hadoop.yarn.webapp.RemoteExceptionData;
+
+@Singleton
+@Provider
+public class JAXBContextResolver implements ContextResolver<JAXBContext> {
+
+  private JAXBContext context;
+  private final Set<Class> types;
+
+  // you have to specify all the dao classes here
+  private final Class[] cTypes = {AMAttemptInfo.class, AMAttemptsInfo.class,
+    AppInfo.class, CounterInfo.class, JobTaskAttemptCounterInfo.class,
+    JobTaskCounterInfo.class, TaskCounterGroupInfo.class, ConfInfo.class,
+    JobCounterInfo.class, TaskCounterInfo.class, CounterGroupInfo.class,
+    JobInfo.class, JobsInfo.class, ReduceTaskAttemptInfo.class,
+    TaskAttemptInfo.class, TaskInfo.class, TasksInfo.class,
+    TaskAttemptsInfo.class, ConfEntryInfo.class, RemoteExceptionData.class};
+
+  public JAXBContextResolver() throws Exception {
+    this.types = new HashSet<Class>(Arrays.asList(cTypes));
+    this.context = new JSONJAXBContext(JSONConfiguration.natural().
+        rootUnwrapping(false).build(), cTypes);
+  }
+
+  @Override
+  public JAXBContext getContext(Class<?> objectType) {
+    return (types.contains(objectType)) ? context : null;
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobBlock.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobBlock.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobBlock.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobBlock.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,203 @@
+/**
+* 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.mapreduce.v2.app2.webapp;
+
+import static org.apache.hadoop.mapreduce.v2.app2.webapp.AMParams.JOB_ID;
+import static org.apache.hadoop.yarn.util.StringHelper.join;
+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._PROGRESSBAR;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._PROGRESSBAR_VALUE;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._TH;
+
+import java.util.Date;
+import java.util.List;
+
+import org.apache.hadoop.http.HttpConfig;
+import org.apache.hadoop.mapreduce.v2.api.records.AMInfo;
+import org.apache.hadoop.mapreduce.v2.api.records.JobId;
+import org.apache.hadoop.mapreduce.v2.app2.AppContext;
+import org.apache.hadoop.mapreduce.v2.app2.job.Job;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.AMAttemptInfo;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.JobInfo;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+import org.apache.hadoop.mapreduce.v2.util.MRApps.TaskAttemptStateUI;
+import org.apache.hadoop.util.StringUtils;
+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.view.HtmlBlock;
+import org.apache.hadoop.yarn.webapp.view.InfoBlock;
+
+import com.google.inject.Inject;
+
+public class JobBlock extends HtmlBlock {
+  final AppContext appContext;
+
+  @Inject JobBlock(AppContext appctx) {
+    appContext = appctx;
+  }
+
+  @Override protected void render(Block html) {
+    String jid = $(JOB_ID);
+    if (jid.isEmpty()) {
+      html.
+        p()._("Sorry, can't do anything without a JobID.")._();
+      return;
+    }
+    JobId jobID = MRApps.toJobID(jid);
+    Job job = appContext.getJob(jobID);
+    if (job == null) {
+      html.
+        p()._("Sorry, ", jid, " not found.")._();
+      return;
+    }
+
+    List<AMInfo> amInfos = job.getAMInfos();
+    String amString =
+        amInfos.size() == 1 ? "ApplicationMaster" : "ApplicationMasters"; 
+
+    JobInfo jinfo = new JobInfo(job, true);
+    info("Job Overview").
+        _("Job Name:", jinfo.getName()).
+        _("State:", jinfo.getState()).
+        _("Uberized:", jinfo.isUberized()).
+        _("Started:", new Date(jinfo.getStartTime())).
+        _("Elapsed:", StringUtils.formatTime(jinfo.getElapsedTime()));
+    DIV<Hamlet> div = html.
+      _(InfoBlock.class).
+      div(_INFO_WRAP);
+
+    // MRAppMasters Table
+    TABLE<DIV<Hamlet>> table = div.table("#job");
+    table.
+      tr().
+      th(amString).
+      _().
+      tr().
+      th(_TH, "Attempt Number").
+      th(_TH, "Start Time").
+      th(_TH, "Node").
+      th(_TH, "Logs").
+      _();
+    for (AMInfo amInfo : amInfos) {
+      AMAttemptInfo attempt = new AMAttemptInfo(amInfo,
+          jinfo.getId(), jinfo.getUserName());
+
+      table.tr().
+        td(String.valueOf(attempt.getAttemptId())).
+        td(new Date(attempt.getStartTime()).toString()).
+        td().a(".nodelink", url(HttpConfig.getSchemePrefix(),
+            attempt.getNodeHttpAddress()),
+            attempt.getNodeHttpAddress())._().
+        td().a(".logslink", url(attempt.getLogsLink()), 
+            "logs")._().
+        _();
+    }
+
+    table._();
+    div._();
+
+    html.div(_INFO_WRAP).        
+      // Tasks table
+        table("#job").
+          tr().
+            th(_TH, "Task Type").
+            th(_TH, "Progress").
+            th(_TH, "Total").
+            th(_TH, "Pending").
+            th(_TH, "Running").
+            th(_TH, "Complete")._().
+          tr(_ODD).
+            th().
+              a(url("tasks", jid, "m"), "Map")._().
+            td().
+              div(_PROGRESSBAR).
+                $title(join(jinfo.getMapProgressPercent(), '%')). // tooltip
+                div(_PROGRESSBAR_VALUE).
+                  $style(join("width:", jinfo.getMapProgressPercent(), '%'))._()._()._().
+            td(String.valueOf(jinfo.getMapsTotal())).
+            td(String.valueOf(jinfo.getMapsPending())).
+            td(String.valueOf(jinfo.getMapsRunning())).
+            td(String.valueOf(jinfo.getMapsCompleted()))._().
+          tr(_EVEN).
+            th().
+              a(url("tasks", jid, "r"), "Reduce")._().
+            td().
+              div(_PROGRESSBAR).
+                $title(join(jinfo.getReduceProgressPercent(), '%')). // tooltip
+                div(_PROGRESSBAR_VALUE).
+                  $style(join("width:", jinfo.getReduceProgressPercent(), '%'))._()._()._().
+            td(String.valueOf(jinfo.getReducesTotal())).
+            td(String.valueOf(jinfo.getReducesPending())).
+            td(String.valueOf(jinfo.getReducesRunning())).
+            td(String.valueOf(jinfo.getReducesCompleted()))._()
+          ._().
+
+        // Attempts table
+        table("#job").
+        tr().
+          th(_TH, "Attempt Type").
+          th(_TH, "New").
+          th(_TH, "Running").
+          th(_TH, "Failed").
+          th(_TH, "Killed").
+          th(_TH, "Successful")._().
+        tr(_ODD).
+          th("Maps").
+          td().a(url("attempts", jid, "m",
+              TaskAttemptStateUI.NEW.toString()),
+              String.valueOf(jinfo.getNewMapAttempts()))._().
+          td().a(url("attempts", jid, "m",
+              TaskAttemptStateUI.RUNNING.toString()),
+              String.valueOf(jinfo.getRunningMapAttempts()))._().
+          td().a(url("attempts", jid, "m",
+              TaskAttemptStateUI.FAILED.toString()),
+              String.valueOf(jinfo.getFailedMapAttempts()))._().
+          td().a(url("attempts", jid, "m",
+              TaskAttemptStateUI.KILLED.toString()),
+              String.valueOf(jinfo.getKilledMapAttempts()))._().
+          td().a(url("attempts", jid, "m",
+              TaskAttemptStateUI.SUCCESSFUL.toString()),
+              String.valueOf(jinfo.getSuccessfulMapAttempts()))._().
+        _().
+        tr(_EVEN).
+          th("Reduces").
+          td().a(url("attempts", jid, "r",
+              TaskAttemptStateUI.NEW.toString()),
+              String.valueOf(jinfo.getNewReduceAttempts()))._().
+          td().a(url("attempts", jid, "r",
+              TaskAttemptStateUI.RUNNING.toString()),
+              String.valueOf(jinfo.getRunningReduceAttempts()))._().
+          td().a(url("attempts", jid, "r",
+              TaskAttemptStateUI.FAILED.toString()),
+              String.valueOf(jinfo.getFailedReduceAttempts()))._().
+          td().a(url("attempts", jid, "r",
+              TaskAttemptStateUI.KILLED.toString()),
+              String.valueOf(jinfo.getKilledReduceAttempts()))._().
+          td().a(url("attempts", jid, "r",
+              TaskAttemptStateUI.SUCCESSFUL.toString()),
+              String.valueOf(jinfo.getSuccessfulReduceAttempts()))._().
+         _().
+       _().
+     _();
+  }
+
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobConfPage.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobConfPage.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobConfPage.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobConfPage.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,97 @@
+/**
+* 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.mapreduce.v2.app2.webapp;
+
+import static org.apache.hadoop.mapreduce.v2.app2.webapp.AMParams.JOB_ID;
+import static org.apache.hadoop.yarn.util.StringHelper.join;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.ACCORDION;
+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 static org.apache.hadoop.yarn.webapp.view.JQueryUI.postInitID;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.tableInit;
+
+import org.apache.hadoop.mapreduce.v2.app2.webapp.ConfBlock;
+import org.apache.hadoop.yarn.webapp.SubView;
+
+/**
+ * Render a page with the configuration for a given job in it.
+ */
+public class JobConfPage extends AppView {
+
+  /*
+   * (non-Javadoc)
+   * @see org.apache.hadoop.mapreduce.v2.hs.webapp.HsView#preHead(org.apache.hadoop.yarn.webapp.hamlet.Hamlet.HTML)
+   */
+  @Override protected void preHead(Page.HTML<_> html) {
+    String jobID = $(JOB_ID);
+    set(TITLE, jobID.isEmpty() ? "Bad request: missing job ID"
+        : join("Configuration for MapReduce Job ", $(JOB_ID)));
+    commonPreHead(html);
+    set(initID(ACCORDION, "nav"), "{autoHeight:false, active:2}");
+    set(DATATABLES_ID, "conf");
+    set(initID(DATATABLES, "conf"), confTableInit());
+    set(postInitID(DATATABLES, "conf"), confPostTableInit());
+    setTableStyles(html, "conf");
+  }
+
+  /**
+   * The body of this block is the configuration block.
+   * @return ConfBlock.class
+   */
+  @Override protected Class<? extends SubView> content() {
+    return ConfBlock.class;
+  }
+
+  /**
+   * @return the end of the JS map that is the jquery datatable config for the
+   * conf table.
+   */
+  private String confTableInit() {
+    return tableInit().append("}").toString();
+  }
+
+  /**
+   * @return the java script code to allow the jquery conf datatable to filter
+   * by column.
+   */
+  private String confPostTableInit() {
+    return "var confInitVals = new Array();\n" +
+    "$('tfoot input').keyup( function () \n{"+
+    "  confDataTable.fnFilter( this.value, $('tfoot input').index(this) );\n"+
+    "} );\n"+
+    "$('tfoot input').each( function (i) {\n"+
+    "  confInitVals[i] = this.value;\n"+
+    "} );\n"+
+    "$('tfoot input').focus( function () {\n"+
+    "  if ( this.className == 'search_init' )\n"+
+    "  {\n"+
+    "    this.className = '';\n"+
+    "    this.value = '';\n"+
+    "  }\n"+
+    "} );\n"+
+    "$('tfoot input').blur( function (i) {\n"+
+    "  if ( this.value == '' )\n"+
+    "  {\n"+
+    "    this.className = 'search_init';\n"+
+    "    this.value = confInitVals[$('tfoot input').index(this)];\n"+
+    "  }\n"+
+    "} );\n";
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobPage.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobPage.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobPage.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobPage.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,42 @@
+/**
+* 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.mapreduce.v2.app2.webapp;
+
+import static org.apache.hadoop.mapreduce.v2.app2.webapp.AMParams.JOB_ID;
+import static org.apache.hadoop.yarn.util.StringHelper.join;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.ACCORDION;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID;
+
+import org.apache.hadoop.yarn.webapp.SubView;
+
+public class JobPage extends AppView {
+
+  @Override protected void preHead(Page.HTML<_> html) {
+    String jobID = $(JOB_ID);
+    set(TITLE, jobID.isEmpty() ? "Bad request: missing job ID"
+               : join("MapReduce Job ", $(JOB_ID)));
+    commonPreHead(html);
+
+    set(initID(ACCORDION, "nav"), "{autoHeight:false, active:2}");
+  }
+
+  @Override protected Class<? extends SubView> content() {
+    return JobBlock.class;
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobsBlock.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobsBlock.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobsBlock.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/JobsBlock.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,86 @@
+/**
+* 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.mapreduce.v2.app2.webapp;
+
+import static org.apache.hadoop.yarn.util.StringHelper.join;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._PROGRESSBAR;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._PROGRESSBAR_VALUE;
+
+import org.apache.hadoop.mapreduce.v2.app2.AppContext;
+import org.apache.hadoop.mapreduce.v2.app2.job.Job;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.JobInfo;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+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 com.google.inject.Inject;
+
+public class JobsBlock extends HtmlBlock {
+  final AppContext appContext;
+
+  @Inject JobsBlock(AppContext appCtx) {
+    appContext = appCtx;
+  }
+
+  @Override protected void render(Block html) {
+    TBODY<TABLE<Hamlet>> tbody = html.
+      h2("Active Jobs").
+      table("#jobs").
+        thead().
+          tr().
+            th(".id", "Job ID").
+            th(".name", "Name").
+            th(".state", "State").
+            th("Map Progress").
+            th("Maps Total").
+            th("Maps Completed").
+            th("Reduce Progress").
+            th("Reduces Total").
+            th("Reduces Completed")._()._().
+        tbody();
+    for (Job j : appContext.getAllJobs().values()) {
+      JobInfo job = new JobInfo(j, false);
+      tbody.
+        tr().
+          td().
+            span().$title(String.valueOf(job.getId()))._(). // for sorting
+            a(url("job", job.getId()), job.getId())._().
+          td(job.getName()).
+          td(job.getState()).
+          td().
+            span().$title(job.getMapProgressPercent())._(). // for sorting
+            div(_PROGRESSBAR).
+              $title(join(job.getMapProgressPercent(), '%')). // tooltip
+              div(_PROGRESSBAR_VALUE).
+                $style(join("width:", job.getMapProgressPercent(), '%'))._()._()._().
+          td(String.valueOf(job.getMapsTotal())).
+          td(String.valueOf(job.getMapsCompleted())).
+          td().
+            span().$title(job.getReduceProgressPercent())._(). // for sorting
+            div(_PROGRESSBAR).
+              $title(join(job.getReduceProgressPercent(), '%')). // tooltip
+              div(_PROGRESSBAR_VALUE).
+                $style(join("width:", job.getReduceProgressPercent(), '%'))._()._()._().
+          td(String.valueOf(job.getReducesTotal())).
+          td(String.valueOf(job.getReducesCompleted()))._();
+    }
+    tbody._()._();
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/NavBlock.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/NavBlock.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/NavBlock.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/NavBlock.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,88 @@
+/**
+* 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.mapreduce.v2.app2.webapp;
+
+import java.util.List;
+
+import com.google.inject.Inject;
+
+import static org.apache.hadoop.mapreduce.v2.app2.webapp.AMWebApp.*;
+
+import org.apache.hadoop.http.HttpConfig;
+import org.apache.hadoop.mapreduce.v2.api.records.AMInfo;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.*;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+
+public class NavBlock extends HtmlBlock {
+  final App app;
+
+  @Inject NavBlock(App app) { this.app = app; }
+
+  @Override protected void render(Block html) {
+    String rmweb = $(RM_WEB);
+    DIV<Hamlet> nav = html.
+      div("#nav").
+        h3("Cluster").
+        ul().
+          li().a(url(rmweb, "cluster", "cluster"), "About")._().
+          li().a(url(rmweb, "cluster", "apps"), "Applications")._().
+          li().a(url(rmweb, "cluster", "scheduler"), "Scheduler")._()._().
+        h3("Application").
+        ul().
+          li().a(url("app/info"), "About")._().
+          li().a(url("app"), "Jobs")._()._();
+    if (app.getJob() != null) {
+      String jobid = MRApps.toString(app.getJob().getID());
+      List<AMInfo> amInfos = app.getJob().getAMInfos();
+      AMInfo thisAmInfo = amInfos.get(amInfos.size()-1);
+      String nodeHttpAddress = thisAmInfo.getNodeManagerHost() + ":" 
+          + thisAmInfo.getNodeManagerHttpPort();
+      nav.
+        h3("Job").
+        ul().
+          li().a(url("job", jobid), "Overview")._().
+          li().a(url("jobcounters", jobid), "Counters")._().
+          li().a(url("conf", jobid), "Configuration")._().
+          li().a(url("tasks", jobid, "m"), "Map tasks")._().
+          li().a(url("tasks", jobid, "r"), "Reduce tasks")._().
+          li().a(".logslink", url(HttpConfig.getSchemePrefix(),
+              nodeHttpAddress, "node",
+              "containerlogs", thisAmInfo.getContainerId().toString(), 
+              app.getJob().getUserName()), 
+              "AM Logs")._()._();
+      if (app.getTask() != null) {
+        String taskid = MRApps.toString(app.getTask().getID());
+        nav.
+          h3("Task").
+          ul().
+            li().a(url("task", taskid), "Task Overview")._().
+            li().a(url("taskcounters", taskid), "Counters")._()._();
+      }
+    }
+    nav.
+      h3("Tools").
+      ul().
+        li().a("/conf", "Configuration")._().
+        li().a("/logs", "Local logs")._().
+        li().a("/stacks", "Server stacks")._().
+        li().a("/metrics", "Server metrics")._()._()._();
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/SingleCounterBlock.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/SingleCounterBlock.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/SingleCounterBlock.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/SingleCounterBlock.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,157 @@
+/**
+* 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.mapreduce.v2.app2.webapp;
+
+import static org.apache.hadoop.mapreduce.v2.app2.webapp.AMParams.COUNTER_GROUP;
+import static org.apache.hadoop.mapreduce.v2.app2.webapp.AMParams.COUNTER_NAME;
+import static org.apache.hadoop.mapreduce.v2.app2.webapp.AMParams.JOB_ID;
+import static org.apache.hadoop.mapreduce.v2.app2.webapp.AMParams.TASK_ID;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.hadoop.mapreduce.Counter;
+import org.apache.hadoop.mapreduce.CounterGroup;
+import org.apache.hadoop.mapreduce.Counters;
+import org.apache.hadoop.mapreduce.v2.api.records.JobId;
+import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId;
+import org.apache.hadoop.mapreduce.v2.api.records.TaskId;
+import org.apache.hadoop.mapreduce.v2.app2.AppContext;
+import org.apache.hadoop.mapreduce.v2.app2.job.Job;
+import org.apache.hadoop.mapreduce.v2.app2.job.Task;
+import org.apache.hadoop.mapreduce.v2.app2.job.TaskAttempt;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+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.hamlet.Hamlet.TR;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+
+import com.google.inject.Inject;
+
+public class SingleCounterBlock extends HtmlBlock {
+  protected TreeMap<String, Long> values = new TreeMap<String, Long>(); 
+  protected Job job;
+  protected Task task;
+  
+  @Inject SingleCounterBlock(AppContext appCtx, ViewContext ctx) {
+    super(ctx);
+    this.populateMembers(appCtx);
+  }
+
+  @Override protected void render(Block html) {
+    if (job == null) {
+      html.
+        p()._("Sorry, no counters for nonexistent", $(JOB_ID, "job"))._();
+      return;
+    }
+    if (!$(TASK_ID).isEmpty() && task == null) {
+      html.
+        p()._("Sorry, no counters for nonexistent", $(TASK_ID, "task"))._();
+      return;
+    }
+    
+    String columnType = task == null ? "Task" : "Task Attempt";
+    
+    TBODY<TABLE<DIV<Hamlet>>> tbody = html.
+      div(_INFO_WRAP).
+      table("#singleCounter").
+        thead().
+          tr().
+            th(".ui-state-default", columnType).
+            th(".ui-state-default", "Value")._()._().
+          tbody();
+    for (Map.Entry<String, Long> entry : values.entrySet()) {
+      TR<TBODY<TABLE<DIV<Hamlet>>>> row = tbody.tr();
+      String id = entry.getKey();
+      String val = entry.getValue().toString();
+      if(task != null) {
+        row.td(id);
+        row.td().br().$title(val)._()._(val)._();
+      } else {
+        row.td().a(url("singletaskcounter",entry.getKey(),
+            $(COUNTER_GROUP), $(COUNTER_NAME)), id)._();
+        row.td().br().$title(val)._().a(url("singletaskcounter",entry.getKey(),
+            $(COUNTER_GROUP), $(COUNTER_NAME)), val)._();
+      }
+      row._();
+    }
+    tbody._()._()._();
+  }
+
+  private void populateMembers(AppContext ctx) {
+    JobId jobID = null;
+    TaskId taskID = null;
+    String tid = $(TASK_ID);
+    if (!tid.isEmpty()) {
+      taskID = MRApps.toTaskID(tid);
+      jobID = taskID.getJobId();
+    } else {
+      String jid = $(JOB_ID);
+      if (!jid.isEmpty()) {
+        jobID = MRApps.toJobID(jid);
+      }
+    }
+    if (jobID == null) {
+      return;
+    }
+    job = ctx.getJob(jobID);
+    if (job == null) {
+      return;
+    }
+    if (taskID != null) {
+      task = job.getTask(taskID);
+      if (task == null) {
+        return;
+      }
+      for(Map.Entry<TaskAttemptId, TaskAttempt> entry : 
+        task.getAttempts().entrySet()) {
+        long value = 0;
+        Counters counters = entry.getValue().getCounters();
+        CounterGroup group = (counters != null) ? counters
+          .getGroup($(COUNTER_GROUP)) : null;
+        if(group != null)  {
+          Counter c = group.findCounter($(COUNTER_NAME));
+          if(c != null) {
+            value = c.getValue();
+          }
+        }
+        values.put(MRApps.toString(entry.getKey()), value);
+      }
+      
+      return;
+    }
+    // Get all types of counters
+    Map<TaskId, Task> tasks = job.getTasks();
+    for(Map.Entry<TaskId, Task> entry : tasks.entrySet()) {
+      long value = 0;
+      CounterGroup group = entry.getValue().getCounters()
+        .getGroup($(COUNTER_GROUP));
+      if(group != null)  {
+        Counter c = group.findCounter($(COUNTER_NAME));
+        if(c != null) {
+          value = c.getValue();
+        }
+      }
+      values.put(MRApps.toString(entry.getKey()), value);
+    }
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/SingleCounterPage.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/SingleCounterPage.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/SingleCounterPage.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/SingleCounterPage.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,69 @@
+/**
+* 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.mapreduce.v2.app2.webapp;
+
+import static org.apache.hadoop.mapreduce.v2.app2.webapp.AMParams.TASK_ID;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
+
+import org.apache.hadoop.mapreduce.v2.app2.webapp.SingleCounterBlock;
+import org.apache.hadoop.yarn.webapp.SubView;
+
+/**
+ * Render the counters page
+ */
+public class SingleCounterPage extends AppView {
+
+  /*
+   * (non-Javadoc)
+   * @see org.apache.hadoop.mapreduce.v2.hs.webapp.HsView#preHead(org.apache.hadoop.yarn.webapp.hamlet.Hamlet.HTML)
+   */
+  @Override protected void preHead(Page.HTML<_> html) {
+    commonPreHead(html);
+    String tid = $(TASK_ID);
+    String activeNav = "3";
+    if(tid == null || tid.isEmpty()) {
+      activeNav = "2";
+    }
+    set(initID(ACCORDION, "nav"), "{autoHeight:false, active:"+activeNav+"}");
+    set(DATATABLES_ID, "singleCounter");
+    set(initID(DATATABLES, "singleCounter"), counterTableInit());
+    setTableStyles(html, "singleCounter");
+  }
+
+  /**
+   * @return The end of a javascript map that is the jquery datatable 
+   * configuration for the jobs table.  the Jobs table is assumed to be
+   * rendered by the class returned from {@link #content()} 
+   */
+  private String counterTableInit() {
+    return tableInit().
+        append(",aoColumnDefs:[").
+        append("{'sType':'title-numeric', 'aTargets': [ 1 ] }").
+        append("]}").
+        toString();
+  }
+  
+  /**
+   * The content of this page is the CountersBlock now.
+   * @return CountersBlock.class
+   */
+  @Override protected Class<? extends SubView> content() {
+    return SingleCounterBlock.class;
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/TaskPage.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/TaskPage.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/TaskPage.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/TaskPage.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,148 @@
+/**
+* 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.mapreduce.v2.app2.webapp;
+
+import static org.apache.hadoop.yarn.util.StringHelper.percent;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.ACCORDION;
+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 static org.apache.hadoop.yarn.webapp.view.JQueryUI.tableInit;
+
+import java.util.Collection;
+
+import org.apache.hadoop.http.HttpConfig;
+import org.apache.hadoop.mapreduce.v2.app2.job.TaskAttempt;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.TaskAttemptInfo;
+import org.apache.hadoop.util.StringUtils;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.util.Times;
+import org.apache.hadoop.yarn.webapp.SubView;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TD;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TR;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+
+import com.google.inject.Inject;
+
+public class TaskPage extends AppView {
+
+  static class AttemptsBlock extends HtmlBlock {
+    final App app;
+
+    @Inject
+    AttemptsBlock(App ctx) {
+      app = ctx;
+    }
+
+    @Override
+    protected void render(Block html) {
+      if (!isValidRequest()) {
+        html.
+          h2($(TITLE));
+        return;
+      }
+      TBODY<TABLE<Hamlet>> tbody = html.
+      table("#attempts").
+        thead().
+          tr().
+            th(".id", "Attempt").
+            th(".progress", "Progress").
+            th(".state", "State").
+            th(".node", "Node").
+            th(".logs", "Logs").
+            th(".tsh", "Started").
+            th(".tsh", "Finished").
+            th(".tsh", "Elapsed").
+            th(".note", "Note")._()._().
+        tbody();
+      for (TaskAttempt attempt : getTaskAttempts()) {
+        TaskAttemptInfo ta = new TaskAttemptInfo(attempt, true);
+        String taid = ta.getId();
+        String progress = percent(ta.getProgress() / 100);
+        ContainerId containerId = ta.getAssignedContainerId();
+
+        String nodeHttpAddr = ta.getNode();
+        long startTime = ta.getStartTime();
+        long finishTime = ta.getFinishTime();
+        long elapsed = ta.getElapsedTime();
+        String diag = ta.getNote() == null ? "" : ta.getNote();
+        TR<TBODY<TABLE<Hamlet>>> row = tbody.tr();
+        TD<TR<TBODY<TABLE<Hamlet>>>> nodeTd = row.
+          td(".id", taid).
+          td(".progress", progress).
+          td(".state", ta.getState()).td();
+        if (nodeHttpAddr == null) {
+          nodeTd._("N/A");
+        } else {
+          nodeTd.
+            a(".nodelink", url(HttpConfig.getSchemePrefix(),
+                               nodeHttpAddr), nodeHttpAddr);
+        }
+        nodeTd._();
+        if (containerId != null) {
+          String containerIdStr = ta.getAssignedContainerIdStr();
+          row.td().
+              a(".logslink", url(HttpConfig.getSchemePrefix(),
+              nodeHttpAddr, "node", "containerlogs",
+              containerIdStr, app.getJob().getUserName()), "logs")._();
+        } else {
+          row.td()._("N/A")._();
+        }
+
+        row.
+          td(".ts", Times.format(startTime)).
+          td(".ts", Times.format(finishTime)).
+          td(".dt", StringUtils.formatTime(elapsed)).
+          td(".note", diag)._();
+      }
+      tbody._()._();
+    }
+
+    protected boolean isValidRequest() {
+      return app.getTask() != null;
+    }
+
+    protected Collection<TaskAttempt> getTaskAttempts() {
+      return app.getTask().getAttempts().values();
+    }
+  }
+
+  @Override protected void preHead(Page.HTML<_> html) {
+    commonPreHead(html);
+
+    set(initID(ACCORDION, "nav"), "{autoHeight:false, active:3}");
+    set(DATATABLES_ID, "attempts");
+    set(initID(DATATABLES, "attempts"), attemptsTableInit());
+    setTableStyles(html, "attempts");
+  }
+
+  @Override protected Class<? extends SubView> content() {
+    return AttemptsBlock.class;
+  }
+
+  private String attemptsTableInit() {
+    return tableInit().
+        // Sort by id upon page load
+        append(", aaSorting: [[0, 'asc']]").
+        append("}").toString();
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/TasksBlock.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/TasksBlock.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/TasksBlock.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/TasksBlock.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,103 @@
+/**
+* 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.mapreduce.v2.app2.webapp;
+
+import static org.apache.hadoop.mapreduce.v2.app2.webapp.AMParams.TASK_TYPE;
+import static org.apache.hadoop.yarn.util.StringHelper.join;
+import static org.apache.hadoop.yarn.util.StringHelper.percent;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._PROGRESSBAR;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._PROGRESSBAR_VALUE;
+
+import org.apache.hadoop.mapreduce.v2.api.records.TaskType;
+import org.apache.hadoop.mapreduce.v2.app2.job.Task;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.dao.TaskInfo;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+import org.apache.hadoop.util.StringUtils;
+import org.apache.hadoop.yarn.util.Times;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+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 com.google.inject.Inject;
+
+public class TasksBlock extends HtmlBlock {
+  final App app;
+
+  @Inject TasksBlock(App app) {
+    this.app = app;
+  }
+
+  @Override protected void render(Block html) {
+    if (app.getJob() == null) {
+      html.
+        h2($(TITLE));
+      return;
+    }
+    TaskType type = null;
+    String symbol = $(TASK_TYPE);
+    if (!symbol.isEmpty()) {
+      type = MRApps.taskType(symbol);
+    }
+    TBODY<TABLE<Hamlet>> tbody = html.
+      table("#tasks").
+        thead().
+          tr().
+            th("Task").
+            th("Progress").
+            th("State").
+            th("Start Time").
+            th("Finish Time").
+            th("Elapsed Time")._()._().
+        tbody();
+    for (Task task : app.getJob().getTasks().values()) {
+      if (type != null && task.getType() != type) {
+        continue;
+      }
+      TaskInfo info = new TaskInfo(task);
+      String tid = info.getId();
+      String pct = percent(info.getProgress() / 100);
+      long startTime = info.getStartTime();
+      long finishTime = info.getFinishTime();
+      long elapsed = info.getElapsedTime();
+      tbody.
+        tr().
+          td().
+            br().$title(String.valueOf(info.getTaskNum()))._(). // sorting
+            a(url("task", tid), tid)._().
+          td().
+            br().$title(pct)._().
+            div(_PROGRESSBAR).
+              $title(join(pct, '%')). // tooltip
+              div(_PROGRESSBAR_VALUE).
+                $style(join("width:", pct, '%'))._()._()._().
+          td(info.getState()).
+          td().
+            br().$title(String.valueOf(startTime))._().
+            _(Times.format(startTime))._().
+          td().
+            br().$title(String.valueOf(finishTime))._().
+            _(Times.format(finishTime))._().
+          td().
+            br().$title(String.valueOf(elapsed))._().
+            _(StringUtils.formatTime(elapsed))._()._();
+    }
+    tbody._()._();
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/TasksPage.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/TasksPage.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/TasksPage.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/TasksPage.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,47 @@
+/**
+* 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.mapreduce.v2.app2.webapp;
+
+import org.apache.hadoop.yarn.webapp.SubView;
+
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
+
+public class TasksPage extends AppView {
+
+  @Override protected void preHead(Page.HTML<_> html) {
+    commonPreHead(html);
+    set(DATATABLES_ID, "tasks");
+    set(initID(ACCORDION, "nav"), "{autoHeight:false, active:2}");
+    set(initID(DATATABLES, "tasks"), tasksTableInit());
+    setTableStyles(html, "tasks");
+  }
+
+  @Override protected Class<? extends SubView> content() {
+    return TasksBlock.class;
+  }
+
+  private String tasksTableInit() {
+    return tableInit().
+        // Sort by id upon page load
+        append(", aaSorting: [[0, 'asc']]").
+        append(",aoColumns:[{sType:'title-numeric'},{sType:'title-numeric',").
+        append("bSearchable:false},null,{sType:'title-numeric'},").
+        append("{sType:'title-numeric'},{sType:'title-numeric'}]}").toString();
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/AMAttemptInfo.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/AMAttemptInfo.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/AMAttemptInfo.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/AMAttemptInfo.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,96 @@
+/**
+ * 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.mapreduce.v2.app2.webapp.dao;
+
+import static org.apache.hadoop.yarn.util.StringHelper.join;
+import static org.apache.hadoop.yarn.util.StringHelper.ujoin;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.hadoop.http.HttpConfig;
+import org.apache.hadoop.mapreduce.v2.api.records.AMInfo;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.util.BuilderUtils;
+
+@XmlRootElement(name = "jobAttempt")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class AMAttemptInfo {
+
+  protected String nodeHttpAddress;
+  protected String nodeId;
+  protected int id;
+  protected long startTime;
+  protected String containerId;
+  protected String logsLink;
+
+  public AMAttemptInfo() {
+  }
+
+  public AMAttemptInfo(AMInfo amInfo, String jobId, String user) {
+
+    this.nodeHttpAddress = "";
+    this.nodeId = "";
+    String nmHost = amInfo.getNodeManagerHost();
+    int nmHttpPort = amInfo.getNodeManagerHttpPort();
+    int nmPort = amInfo.getNodeManagerPort();
+    if (nmHost != null) {
+      this.nodeHttpAddress = nmHost + ":" + nmHttpPort;
+      NodeId nodeId = BuilderUtils.newNodeId(nmHost, nmPort);
+      this.nodeId = nodeId.toString();
+    }
+
+    this.id = amInfo.getAppAttemptId().getAttemptId();
+    this.startTime = amInfo.getStartTime();
+    this.containerId = "";
+    this.logsLink = "";
+    ContainerId containerId = amInfo.getContainerId();
+    if (containerId != null) {
+      this.containerId = containerId.toString();
+      this.logsLink = join(HttpConfig.getSchemePrefix() + nodeHttpAddress,
+          ujoin("node", "containerlogs", this.containerId, user));
+    }
+  }
+
+  public String getNodeHttpAddress() {
+    return this.nodeHttpAddress;
+  }
+
+  public String getNodeId() {
+    return this.nodeId;
+  }
+
+  public int getAttemptId() {
+    return this.id;
+  }
+
+  public long getStartTime() {
+    return this.startTime;
+  }
+
+  public String getContainerId() {
+    return this.containerId;
+  }
+
+  public String getLogsLink() {
+    return this.logsLink;
+  }
+
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/AMAttemptsInfo.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/AMAttemptsInfo.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/AMAttemptsInfo.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/AMAttemptsInfo.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,45 @@
+/**
+ * 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 joblicable 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.mapreduce.v2.app2.webapp.dao;
+
+import java.util.ArrayList;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "jobAttempts")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class AMAttemptsInfo {
+
+  @XmlElement(name = "jobAttempt")
+  protected ArrayList<AMAttemptInfo> attempt = new ArrayList<AMAttemptInfo>();
+
+  public AMAttemptsInfo() {
+  } // JAXB needs this
+
+  public void add(AMAttemptInfo info) {
+    this.attempt.add(info);
+  }
+
+  public ArrayList<AMAttemptInfo> getAttempts() {
+    return this.attempt;
+  }
+
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/AppInfo.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/AppInfo.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/AppInfo.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/AppInfo.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,69 @@
+/**
+ * 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.mapreduce.v2.app2.webapp.dao;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.hadoop.mapreduce.v2.app2.AppContext;
+import org.apache.hadoop.mapreduce.v2.app2.webapp.App;
+import org.apache.hadoop.yarn.util.Times;
+
+@XmlRootElement(name = "info")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class AppInfo {
+
+  protected String appId;
+  protected String name;
+  protected String user;
+  protected long startedOn;
+  protected long elapsedTime;
+
+  public AppInfo() {
+  }
+
+  public AppInfo(App app, AppContext context) {
+    this.appId = context.getApplicationID().toString();
+    this.name = context.getApplicationName().toString();
+    this.user = context.getUser().toString();
+    this.startedOn = context.getStartTime();
+    this.elapsedTime = Times.elapsed(this.startedOn, 0);
+  }
+
+  public String getId() {
+    return this.appId;
+  }
+
+  public String getName() {
+    return this.name;
+  }
+
+  public String getUser() {
+    return this.user;
+  }
+
+  public long getStartTime() {
+    return this.startedOn;
+  }
+
+  public long getElapsedTime() {
+    return this.elapsedTime;
+  }
+
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/ConfEntryInfo.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/ConfEntryInfo.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/ConfEntryInfo.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/ConfEntryInfo.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,56 @@
+/**
+ * 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.mapreduce.v2.app2.webapp.dao;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ConfEntryInfo {
+
+  protected String name;
+  protected String value;
+  protected String[] source;
+
+  public ConfEntryInfo() {
+  }
+
+  public ConfEntryInfo(String key, String value) {
+    this(key, value, null);
+  }
+  
+  public ConfEntryInfo(String key, String value, String[] source) {
+    this.name = key;
+    this.value = value;
+    this.source = source;
+  }
+
+  public String getName() {
+    return this.name;
+  }
+
+  public String getValue() {
+    return this.value;
+  }
+  
+  public String[] getSource() {
+    return source;
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/ConfInfo.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/ConfInfo.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/ConfInfo.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/ConfInfo.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,63 @@
+/**
+ * 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.mapreduce.v2.app2.webapp.dao;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileContext;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.mapreduce.v2.app2.job.Job;
+
+@XmlRootElement(name = "conf")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ConfInfo {
+
+  protected String path;
+  protected ArrayList<ConfEntryInfo> property;
+
+  public ConfInfo() {
+  }
+
+  public ConfInfo(Job job) throws IOException {
+
+    this.property = new ArrayList<ConfEntryInfo>();
+    Configuration jobConf = job.loadConfFile();
+    this.path = job.getConfFile().toString();
+    for (Map.Entry<String, String> entry : jobConf) {
+      this.property.add(new ConfEntryInfo(entry.getKey(), entry.getValue(), 
+          jobConf.getPropertySources(entry.getKey())));
+    }
+
+  }
+
+  public ArrayList<ConfEntryInfo> getProperties() {
+    return this.property;
+  }
+
+  public String getPath() {
+    return this.path;
+  }
+
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/CounterGroupInfo.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/CounterGroupInfo.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/CounterGroupInfo.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/CounterGroupInfo.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,54 @@
+/**
+ * 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.mapreduce.v2.app2.webapp.dao;
+
+import java.util.ArrayList;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.hadoop.mapreduce.Counter;
+import org.apache.hadoop.mapreduce.CounterGroup;
+
+@XmlRootElement(name = "counterGroup")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CounterGroupInfo {
+
+  protected String counterGroupName;
+  @XmlElement(name = "counter")
+  protected ArrayList<CounterInfo> counter;
+
+  public CounterGroupInfo() {
+  }
+
+  public CounterGroupInfo(String name, CounterGroup group, CounterGroup mg,
+      CounterGroup rg) {
+    this.counterGroupName = name;
+    this.counter = new ArrayList<CounterInfo>();
+
+    for (Counter c : group) {
+      Counter mc = mg == null ? null : mg.findCounter(c.getName());
+      Counter rc = rg == null ? null : rg.findCounter(c.getName());
+      CounterInfo cinfo = new CounterInfo(c, mc, rc);
+      this.counter.add(cinfo);
+    }
+  }
+
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/CounterInfo.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/CounterInfo.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/CounterInfo.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/CounterInfo.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,44 @@
+/**
+ * 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.mapreduce.v2.app2.webapp.dao;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.hadoop.mapreduce.Counter;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CounterInfo {
+
+  protected String name;
+  protected long totalCounterValue;
+  protected long mapCounterValue;
+  protected long reduceCounterValue;
+
+  public CounterInfo() {
+  }
+
+  public CounterInfo(Counter c, Counter mc, Counter rc) {
+    this.name = c.getName();
+    this.totalCounterValue = c.getValue();
+    this.mapCounterValue = mc == null ? 0 : mc.getValue();
+    this.reduceCounterValue = rc == null ? 0 : rc.getValue();
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobCounterInfo.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobCounterInfo.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobCounterInfo.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobCounterInfo.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,99 @@
+/**
+ * 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.mapreduce.v2.app2.webapp.dao;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.hadoop.mapreduce.CounterGroup;
+import org.apache.hadoop.mapreduce.Counters;
+import org.apache.hadoop.mapreduce.v2.api.records.TaskId;
+import org.apache.hadoop.mapreduce.v2.app2.AppContext;
+import org.apache.hadoop.mapreduce.v2.app2.job.Job;
+import org.apache.hadoop.mapreduce.v2.app2.job.Task;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+
+@XmlRootElement(name = "jobCounters")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class JobCounterInfo {
+
+  @XmlTransient
+  protected Counters total = null;
+  @XmlTransient
+  protected Counters map = null;
+  @XmlTransient
+  protected Counters reduce = null;
+
+  protected String id;
+  protected ArrayList<CounterGroupInfo> counterGroup;
+
+  public JobCounterInfo() {
+  }
+
+  public JobCounterInfo(AppContext ctx, Job job) {
+    getCounters(ctx, job);
+    counterGroup = new ArrayList<CounterGroupInfo>();
+    this.id = MRApps.toString(job.getID());
+
+    if (total != null) {
+      for (CounterGroup g : total) {
+        if (g != null) {
+          CounterGroup mg = map == null ? null : map.getGroup(g.getName());
+          CounterGroup rg = reduce == null ? null : reduce
+            .getGroup(g.getName());
+
+          CounterGroupInfo cginfo = new CounterGroupInfo(g.getName(), g,
+            mg, rg);
+          counterGroup.add(cginfo);
+        }
+      }
+    }
+  }
+
+  private void getCounters(AppContext ctx, Job job) {
+    total = new Counters();
+    if (job == null) {
+      return;
+    }
+    map = new Counters();
+    reduce = new Counters();
+    // Get all types of counters
+    Map<TaskId, Task> tasks = job.getTasks();
+    for (Task t : tasks.values()) {
+      Counters counters = t.getCounters();
+      if (counters == null) {
+        continue;
+      }
+      total.incrAllCounters(counters);
+      switch (t.getType()) {
+      case MAP:
+        map.incrAllCounters(counters);
+        break;
+      case REDUCE:
+        reduce.incrAllCounters(counters);
+        break;
+      }
+    }
+  }
+
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobInfo.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobInfo.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobInfo.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobInfo.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,345 @@
+/**
+ * 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.mapreduce.v2.app2.webapp.dao;
+
+import static org.apache.hadoop.yarn.util.StringHelper.percent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.hadoop.mapreduce.JobACL;
+import org.apache.hadoop.mapreduce.v2.api.records.JobReport;
+import org.apache.hadoop.mapreduce.v2.api.records.JobState;
+import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId;
+import org.apache.hadoop.mapreduce.v2.api.records.TaskId;
+import org.apache.hadoop.mapreduce.v2.app2.job.Job;
+import org.apache.hadoop.mapreduce.v2.app2.job.Task;
+import org.apache.hadoop.mapreduce.v2.app2.job.TaskAttempt;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+import org.apache.hadoop.mapreduce.v2.util.MRApps.TaskAttemptStateUI;
+import org.apache.hadoop.security.authorize.AccessControlList;
+import org.apache.hadoop.yarn.util.Times;
+
+@XmlRootElement(name = "job")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class JobInfo {
+
+  // ok for any user to see
+  protected long startTime;
+  protected long finishTime;
+  protected long elapsedTime;
+  protected String id;
+  protected String name;
+  protected String user;
+  protected JobState state;
+  protected int mapsTotal;
+  protected int mapsCompleted;
+  protected int reducesTotal;
+  protected int reducesCompleted;
+  protected float mapProgress;
+  protected float reduceProgress;
+
+  @XmlTransient
+  protected String mapProgressPercent;
+  @XmlTransient
+  protected String reduceProgressPercent;
+
+  // these should only be seen if acls allow
+  protected int mapsPending;
+  protected int mapsRunning;
+  protected int reducesPending;
+  protected int reducesRunning;
+  protected boolean uberized;
+  protected String diagnostics;
+  protected int newReduceAttempts = 0;
+  protected int runningReduceAttempts = 0;
+  protected int failedReduceAttempts = 0;
+  protected int killedReduceAttempts = 0;
+  protected int successfulReduceAttempts = 0;
+  protected int newMapAttempts = 0;
+  protected int runningMapAttempts = 0;
+  protected int failedMapAttempts = 0;
+  protected int killedMapAttempts = 0;
+  protected int successfulMapAttempts = 0;
+  protected ArrayList<ConfEntryInfo> acls;
+
+  public JobInfo() {
+  }
+
+  public JobInfo(Job job, Boolean hasAccess) {
+    this.id = MRApps.toString(job.getID());
+    JobReport report = job.getReport();
+    this.startTime = report.getStartTime();
+    this.finishTime = report.getFinishTime();
+    this.elapsedTime = Times.elapsed(this.startTime, this.finishTime);
+    if (this.elapsedTime == -1) {
+      this.elapsedTime = 0;
+    }
+    this.name = job.getName().toString();
+    this.user = job.getUserName();
+    this.state = job.getState();
+    this.mapsTotal = job.getTotalMaps();
+    this.mapsCompleted = job.getCompletedMaps();
+    this.mapProgress = report.getMapProgress() * 100;
+    this.mapProgressPercent = percent(report.getMapProgress());
+    this.reducesTotal = job.getTotalReduces();
+    this.reducesCompleted = job.getCompletedReduces();
+    this.reduceProgress = report.getReduceProgress() * 100;
+    this.reduceProgressPercent = percent(report.getReduceProgress());
+
+    this.acls = new ArrayList<ConfEntryInfo>();
+    if (hasAccess) {
+      this.diagnostics = "";
+      countTasksAndAttempts(job);
+
+      this.uberized = job.isUber();
+
+      List<String> diagnostics = job.getDiagnostics();
+      if (diagnostics != null && !diagnostics.isEmpty()) {
+        StringBuffer b = new StringBuffer();
+        for (String diag : diagnostics) {
+          b.append(diag);
+        }
+        this.diagnostics = b.toString();
+      }
+
+      Map<JobACL, AccessControlList> allacls = job.getJobACLs();
+      if (allacls != null) {
+        for (Map.Entry<JobACL, AccessControlList> entry : allacls.entrySet()) {
+          this.acls.add(new ConfEntryInfo(entry.getKey().getAclName(), entry
+              .getValue().getAclString()));
+        }
+      }
+    }
+  }
+
+  public int getNewReduceAttempts() {
+    return this.newReduceAttempts;
+  }
+
+  public int getKilledReduceAttempts() {
+    return this.killedReduceAttempts;
+  }
+
+  public int getFailedReduceAttempts() {
+    return this.failedReduceAttempts;
+  }
+
+  public int getRunningReduceAttempts() {
+    return this.runningReduceAttempts;
+  }
+
+  public int getSuccessfulReduceAttempts() {
+    return this.successfulReduceAttempts;
+  }
+
+  public int getNewMapAttempts() {
+    return this.newMapAttempts;
+  }
+
+  public int getKilledMapAttempts() {
+    return this.killedMapAttempts;
+  }
+
+  public ArrayList<ConfEntryInfo> getAcls() {
+    return acls;
+  }
+
+  public int getFailedMapAttempts() {
+    return this.failedMapAttempts;
+  }
+
+  public int getRunningMapAttempts() {
+    return this.runningMapAttempts;
+  }
+
+  public int getSuccessfulMapAttempts() {
+    return this.successfulMapAttempts;
+  }
+
+  public int getReducesCompleted() {
+    return this.reducesCompleted;
+  }
+
+  public int getReducesTotal() {
+    return this.reducesTotal;
+  }
+
+  public int getReducesPending() {
+    return this.reducesPending;
+  }
+
+  public int getReducesRunning() {
+    return this.reducesRunning;
+  }
+
+  public int getMapsCompleted() {
+    return this.mapsCompleted;
+  }
+
+  public int getMapsTotal() {
+    return this.mapsTotal;
+  }
+
+  public int getMapsPending() {
+    return this.mapsPending;
+  }
+
+  public int getMapsRunning() {
+    return this.mapsRunning;
+  }
+
+  public String getState() {
+    return this.state.toString();
+  }
+
+  public String getUserName() {
+    return this.user;
+  }
+
+  public String getName() {
+    return this.name;
+  }
+
+  public String getId() {
+    return this.id;
+  }
+
+  public long getStartTime() {
+    return this.startTime;
+  }
+
+  public long getElapsedTime() {
+    return this.elapsedTime;
+  }
+
+  public long getFinishTime() {
+    return this.finishTime;
+  }
+
+  public boolean isUberized() {
+    return this.uberized;
+  }
+
+  public String getdiagnostics() {
+    return this.diagnostics;
+  }
+
+  public float getMapProgress() {
+    return this.mapProgress;
+  }
+
+  public String getMapProgressPercent() {
+    return this.mapProgressPercent;
+  }
+
+  public float getReduceProgress() {
+    return this.reduceProgress;
+  }
+
+  public String getReduceProgressPercent() {
+    return this.reduceProgressPercent;
+  }
+
+  /**
+   * Go through a job and update the member variables with counts for
+   * information to output in the page.
+   *
+   * @param job
+   *          the job to get counts for.
+   */
+  private void countTasksAndAttempts(Job job) {
+    final Map<TaskId, Task> tasks = job.getTasks();
+    if (tasks == null) {
+      return;
+    }
+    for (Task task : tasks.values()) {
+      switch (task.getType()) {
+      case MAP:
+        // Task counts
+        switch (task.getState()) {
+        case RUNNING:
+          ++this.mapsRunning;
+          break;
+        case SCHEDULED:
+          ++this.mapsPending;
+          break;
+        }
+        break;
+      case REDUCE:
+        // Task counts
+        switch (task.getState()) {
+        case RUNNING:
+          ++this.reducesRunning;
+          break;
+        case SCHEDULED:
+          ++this.reducesPending;
+          break;
+        }
+        break;
+      }
+      // Attempts counts
+      Map<TaskAttemptId, TaskAttempt> attempts = task.getAttempts();
+      int newAttempts, running, successful, failed, killed;
+      for (TaskAttempt attempt : attempts.values()) {
+
+        newAttempts = 0;
+        running = 0;
+        successful = 0;
+        failed = 0;
+        killed = 0;
+        if (TaskAttemptStateUI.NEW.correspondsTo(attempt.getState())) {
+          ++newAttempts;
+        } else if (TaskAttemptStateUI.RUNNING.correspondsTo(attempt.getState())) {
+          ++running;
+        } else if (TaskAttemptStateUI.SUCCESSFUL.correspondsTo(attempt
+            .getState())) {
+          ++successful;
+        } else if (TaskAttemptStateUI.FAILED.correspondsTo(attempt.getState())) {
+          ++failed;
+        } else if (TaskAttemptStateUI.KILLED.correspondsTo(attempt.getState())) {
+          ++killed;
+        }
+
+        switch (task.getType()) {
+        case MAP:
+          this.newMapAttempts += newAttempts;
+          this.runningMapAttempts += running;
+          this.successfulMapAttempts += successful;
+          this.failedMapAttempts += failed;
+          this.killedMapAttempts += killed;
+          break;
+        case REDUCE:
+          this.newReduceAttempts += newAttempts;
+          this.runningReduceAttempts += running;
+          this.successfulReduceAttempts += successful;
+          this.failedReduceAttempts += failed;
+          this.killedReduceAttempts += killed;
+          break;
+        }
+      }
+    }
+  }
+
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobTaskAttemptCounterInfo.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobTaskAttemptCounterInfo.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobTaskAttemptCounterInfo.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobTaskAttemptCounterInfo.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,62 @@
+/**
+ * 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.mapreduce.v2.app2.webapp.dao;
+
+import java.util.ArrayList;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.hadoop.mapreduce.CounterGroup;
+import org.apache.hadoop.mapreduce.Counters;
+import org.apache.hadoop.mapreduce.v2.app2.job.TaskAttempt;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+
+@XmlRootElement(name = "jobTaskAttemptCounters")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class JobTaskAttemptCounterInfo {
+
+  @XmlTransient
+  protected Counters total = null;
+
+  protected String id;
+  protected ArrayList<TaskCounterGroupInfo> taskAttemptCounterGroup;
+
+  public JobTaskAttemptCounterInfo() {
+  }
+
+  public JobTaskAttemptCounterInfo(TaskAttempt taskattempt) {
+
+    this.id = MRApps.toString(taskattempt.getID());
+    total = taskattempt.getCounters();
+    taskAttemptCounterGroup = new ArrayList<TaskCounterGroupInfo>();
+    if (total != null) {
+      for (CounterGroup g : total) {
+        if (g != null) {
+          TaskCounterGroupInfo cginfo = new TaskCounterGroupInfo(g.getName(), g);
+          if (cginfo != null) {
+            taskAttemptCounterGroup.add(cginfo);
+          }
+        }
+      }
+    }
+  }
+}

Added: incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobTaskCounterInfo.java
URL: http://svn.apache.org/viewvc/incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobTaskCounterInfo.java?rev=1457129&view=auto
==============================================================================
--- incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobTaskCounterInfo.java (added)
+++ incubator/tez/tez-yarn-application/src/main/java/org/apache/hadoop/mapreduce/v2/app2/webapp/dao/JobTaskCounterInfo.java Fri Mar 15 21:26:36 2013
@@ -0,0 +1,59 @@
+/**
+ * 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.mapreduce.v2.app2.webapp.dao;
+
+import java.util.ArrayList;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.hadoop.mapreduce.CounterGroup;
+import org.apache.hadoop.mapreduce.Counters;
+import org.apache.hadoop.mapreduce.v2.app2.job.Task;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+
+@XmlRootElement(name = "jobTaskCounters")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class JobTaskCounterInfo {
+
+  @XmlTransient
+  protected Counters total = null;
+
+  protected String id;
+  protected ArrayList<TaskCounterGroupInfo> taskCounterGroup;
+
+  public JobTaskCounterInfo() {
+  }
+
+  public JobTaskCounterInfo(Task task) {
+    total = task.getCounters();
+    this.id = MRApps.toString(task.getID());
+    taskCounterGroup = new ArrayList<TaskCounterGroupInfo>();
+    if (total != null) {
+      for (CounterGroup g : total) {
+        if (g != null) {
+          TaskCounterGroupInfo cginfo = new TaskCounterGroupInfo(g.getName(), g);
+          taskCounterGroup.add(cginfo);
+        }
+      }
+    }
+  }
+}