> table = div.table("#attempts");
+ table.
+ tr().
+ th(amString)._().
+ tr().
+ th(_TH, "Attempt Number").
+ th(_TH, "Host").
+ th(_TH, "RPC Port").
+ th(_TH, "Tracking URL").
+ th(_TH, "Diagnostics Info").
+ th(_TH, "Final Application Status").
+ th(_TH, "Master Container Id").
+ _();
+
+ boolean odd = false;
+ for (ApplicationAttemptHistoryData attemptData : applicationAttempts) {
+ ApplicationAttemptId appAttemptId = attemptData.getApplicationAttemptId();
+ table.tr((odd = !odd) ? _ODD : _EVEN).
+ td().a(url("appattempt", appAttemptId.toString()), String.valueOf(appAttemptId.getAttemptId()))._().
+ td(attemptData.getHost()).
+ td(String.valueOf(attemptData.getRPCPort())).
+ td(attemptData.getTrackingURL()).
+ td(attemptData.getDiagnosticsInfo()).
+ td(String.valueOf(attemptData.getFinalApplicationStatus())).
+ td().a(url("container", attemptData.getMasterContainerId().toString()),
+ String.valueOf(attemptData.getMasterContainerId()))._()._();
+ }
+ table._();
+ div._();
+ }
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppAttemptsPage.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppAttemptsPage.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppAttemptsPage.java (working copy)
@@ -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.yarn.server.applicationhistoryservice.webapp;
+
+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;
+import org.apache.hadoop.yarn.webapp.YarnWebParams;
+
+public class AHSAppAttemptsPage extends AHSView {
+
+ @Override
+ protected void preHead(Page.HTML<_> html) {
+ String appId = $(YarnWebParams.APPLICATION_ID);
+ set(TITLE, appId.isEmpty() ? "Bad request: missing application ID" : join(
+ "YARN Application ", $(YarnWebParams.APPLICATION_ID)));
+ commonPreHead(html);
+ set(initID(ACCORDION, "nav"), "{autoHeight:false, active:1}");
+ }
+
+ @Override
+ protected Class extends SubView> content() {
+ return AHSAppAttemptsBlock.class;
+ }
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppContainerBlock.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppContainerBlock.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppContainerBlock.java (working copy)
@@ -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.applicationhistoryservice.webapp;
+
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP;
+
+import java.io.IOException;
+import java.util.Date;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.util.StringUtils;
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryReader;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.records.ContainerHistoryData;
+import org.apache.hadoop.yarn.util.ConverterUtils;
+import org.apache.hadoop.yarn.util.Times;
+import org.apache.hadoop.yarn.webapp.YarnWebParams;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+import org.apache.hadoop.yarn.webapp.view.InfoBlock;
+
+import com.google.inject.Inject;
+
+public class AHSAppContainerBlock extends HtmlBlock {
+
+ private static final Log LOG = LogFactory.getLog(AHSAppContainerBlock.class);
+ private final ApplicationHistoryReader appHistoryReader;
+
+ @Inject
+ public AHSAppContainerBlock(ApplicationHistoryReader appHistoryReader) {
+ this.appHistoryReader = appHistoryReader;
+ }
+
+ @Override
+ protected void render(Block html) {
+ String containerid = $(YarnWebParams.CONTAINER_ID);
+ if (containerid.isEmpty()) {
+ html.
+ p()._("Sorry, can't do anything without a Container Id.")._();
+ return;
+ }
+ ContainerId containerId = ConverterUtils.toContainerId(containerid);
+ html.div(_INFO_WRAP);
+ ContainerHistoryData containerHistoryData;
+ try {
+ containerHistoryData = appHistoryReader.getContainer(containerId);
+ } catch (IOException e) {
+ String message = "Failed to read Container Data.";
+ LOG.error(message, e);
+ html.p()._(message)._();
+ return;
+ }
+ info("Container Overview").
+ _("Container Id:", containerHistoryData.getContainerId()).
+ _("Assigned Node:", containerHistoryData.getAssignedNode()).
+ _("Priority:", containerHistoryData.getPriority()).
+ _("Start Time:", containerHistoryData.getStartTime()).
+ _("Finish Time:", new Date(containerHistoryData.getFinishTime())).
+ _("Diagnostics Info:", containerHistoryData.getDiagnosticsInfo()).
+ _("Final Container Status:", containerHistoryData.getFinalContainerStatus()).
+ _("Logs:", containerHistoryData.getLogURL()).
+ _("Elapsed:", StringUtils.formatTime(
+ Times.elapsed(containerHistoryData.getStartTime(),
+ containerHistoryData.getFinishTime(), false)));
+ html._(InfoBlock.class).div(_INFO_WRAP);
+ }
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppContainerPage.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppContainerPage.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppContainerPage.java (working copy)
@@ -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.yarn.server.applicationhistoryservice.webapp;
+
+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;
+import org.apache.hadoop.yarn.webapp.YarnWebParams;
+
+public class AHSAppContainerPage extends AHSView {
+
+ @Override
+ protected void preHead(Page.HTML<_> html) {
+ String containerid = $(YarnWebParams.CONTAINER_ID);
+ set(TITLE, containerid.isEmpty() ? "Bad request: missing Container ID" : join(
+ "YARN Application Container ", $(YarnWebParams.CONTAINER_ID)));
+ commonPreHead(html);
+ set(initID(ACCORDION, "nav"), "{autoHeight:false, active:1}");
+ }
+
+ @Override
+ protected Class extends SubView> content() {
+ return AHSAppContainerBlock.class;
+ }
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppContainersBlock.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppContainersBlock.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppContainersBlock.java (working copy)
@@ -0,0 +1,130 @@
+/**
+ * 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.applicationhistoryservice.webapp;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Set;
+
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryReader;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.records.ContainerHistoryData;
+import org.apache.hadoop.yarn.util.Apps;
+import org.apache.hadoop.yarn.webapp.YarnWebParams;
+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.HamletSpec.InputType;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+
+import com.google.inject.Inject;
+
+public class AHSAppContainersBlock extends HtmlBlock {
+
+ private final SimpleDateFormat dateFormat = new SimpleDateFormat(
+ "yyyy.MM.dd HH:mm:ss z");
+ protected final ApplicationHistoryReader appHistoryReader;
+
+ @Inject
+ public AHSAppContainersBlock(ApplicationHistoryReader appHistoryReader) {
+ this.appHistoryReader = appHistoryReader;
+ }
+
+ @Override
+ protected void render(Block html) {
+ String id = $(YarnWebParams.APPLICATION_ID);
+ if (id.isEmpty()) {
+ html.p()._("Sorry, can't do anything without a App Id.")._();
+ return;
+ }
+ Collection
containers;
+ try {
+ ApplicationId applicationId = Apps.toAppID(id);
+ containers = new ArrayList();
+ Set keySet = appHistoryReader
+ .getApplicationAttempts(applicationId).keySet();
+ for (ApplicationAttemptId applicationAttemptId : keySet) {
+ containers.addAll(appHistoryReader.getContainers(applicationAttemptId)
+ .values());
+ }
+ } catch (IOException e) {
+ html.p()._("Sorry, Failed to get containers for app id:" + id)
+ ._();
+ return;
+ }
+ renderContainersTable(html, containers);
+ }
+
+ protected void renderContainersTable(Block html,
+ Collection containers) {
+ TBODY> tbody = html.
+ h2("Containers").
+ table("#appContainers").
+ thead().
+ tr().
+ th(".id", "Container ID").
+ th(".name", "Allocated Resource").
+ th("Assigned Node").
+ th("Priority").
+ th("Start Time").
+ th("Finish Time").
+ th("Diagnostics Info").
+ th(".state", "Final Container Status")._()._().
+ tbody();
+
+ StringBuilder containersTableData = new StringBuilder("[\n");
+ for (ContainerHistoryData containerHistoryData : containers) {
+ String containerId = String.valueOf(containerHistoryData.getContainerId());
+ containersTableData.append("[\"")
+ .append("").append(containerId).append("\",\"")
+ .append(containerHistoryData.getAllocatedResource()).append("\",\"")
+ .append(String.valueOf(containerHistoryData.getAssignedNode())).append("\",\"")
+ .append(containerHistoryData.getPriority()).append("\",\"")
+ .append(dateFormat.format(new Date(containerHistoryData.getStartTime()))).append("\",\"")
+ .append(dateFormat.format(new Date(containerHistoryData.getFinishTime()))).append("\",\"")
+ .append(containerHistoryData.getDiagnosticsInfo()).append("\",\"")
+ .append(containerHistoryData.getFinalContainerStatus()).append("\"],\n");
+ }
+
+ // Remove the last comma and close off the array of arrays
+ if (containersTableData.charAt(containersTableData.length() - 2) == ',') {
+ containersTableData.delete(containersTableData.length() - 2,
+ containersTableData.length() - 1);
+ }
+ containersTableData.append("]");
+ html.script().$type("text/javascript")._(
+ "var appContainers=" + containersTableData)._();
+ tbody._().
+ tfoot().
+ tr().
+ th().input("search_init").$type(InputType.text).$name("container_id").$value("Container ID")._()._().
+ th().input("search_init").$type(InputType.text).$name("allocated_resource").$value("Allocated Resource")._()._().
+ th().input("search_init").$type(InputType.text).$name("assigned_node").$value("Assigned Node")._()._().
+ th().input("search_init").$type(InputType.text).$name("priority").$value("Priority")._()._().
+ th().input("search_init").$type(InputType.text).$name("start_time").$value("Start Time")._()._().
+ th().input("search_init").$type(InputType.text).$name("finish_time").$value("Finish Time")._()._().
+ th().input("search_init").$type(InputType.text).$name("diagnostics").$value("Diagnostics")._()._().
+ th().input("search_init").$type(InputType.text).$name("final_container_status").$value("Final Container Status")._()._().
+ _()._()._();
+ }
+
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppContainersPage.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppContainersPage.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppContainersPage.java (working copy)
@@ -0,0 +1,92 @@
+/**
+ * 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.applicationhistoryservice.webapp;
+
+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.yarn.webapp.SubView;
+import org.apache.hadoop.yarn.webapp.YarnWebParams;
+
+public class AHSAppContainersPage extends AHSView {
+
+ @Override
+ protected void preHead(Page.HTML<_> html) {
+ commonPreHead(html);
+ set(DATATABLES_ID, "appContainers");
+ setTableStyles(html, "appContainers", ".queue {width:6em}",
+ ".ui {width:8em}");
+ set(initID(DATATABLES, "appContainers"), appContainersTableInit());
+ set(postInitID(DATATABLES, "appContainers"), appContainerssPostTableInit());
+ initTitle();
+ }
+
+ protected void initTitle() {
+ String appId = $(YarnWebParams.APPLICATION_ID);
+ set(TITLE, appId.isEmpty() ? "Bad request: missing application ID" : join(
+ "YARN Application ", $(YarnWebParams.APPLICATION_ID), " Containers"));
+ set(initID(ACCORDION, "nav"), "{autoHeight:false, active:1}");
+ }
+
+ private String appContainerssPostTableInit() {
+ return "var asInitVals = new Array();\n" +
+ "$('tfoot input').keyup( function () \n{"+
+ " appContainersDataTable.fnFilter( this.value, $('tfoot input').index(this) );\n"+
+ "} );\n"+
+ "$('tfoot input').each( function (i) {\n"+
+ " asInitVals[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 = asInitVals[$('tfoot input').index(this)];\n"+
+ " }\n"+
+ "} );\n";
+ }
+
+ private String appContainersTableInit() {
+ return tableInit().
+ append(", 'aaData': appContainers").
+ append(", bDeferRender: true").
+ append(", bProcessing: true").
+
+ // Sort by id upon page load
+ append(", aaSorting: [[0, 'desc']]").
+ append(", aoColumnDefs:[").
+ append("]}").
+ toString();
+ }
+
+ @Override
+ protected Class extends SubView> content() {
+ return AHSAppContainersBlock.class;
+ }
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSApplicationBlock.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSApplicationBlock.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSApplicationBlock.java (working copy)
@@ -0,0 +1,134 @@
+/**
+ * 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.applicationhistoryservice.webapp;
+
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._EVEN;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._ODD;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI._TH;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Date;
+
+import org.apache.hadoop.util.StringUtils;
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryReader;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.records.ApplicationAttemptHistoryData;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.records.ApplicationHistoryData;
+import org.apache.hadoop.yarn.util.Apps;
+import org.apache.hadoop.yarn.util.Times;
+import org.apache.hadoop.yarn.webapp.YarnWebParams;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+import org.apache.hadoop.yarn.webapp.view.InfoBlock;
+
+import com.google.inject.Inject;
+
+public class AHSApplicationBlock extends HtmlBlock {
+
+ private final ApplicationHistoryReader appHistoryReader;
+
+ @Inject
+ public AHSApplicationBlock(ApplicationHistoryReader appHistoryReader) {
+ this.appHistoryReader = appHistoryReader;
+ }
+
+ @Override
+ protected void render(Block html) {
+ String appid = $(YarnWebParams.APPLICATION_ID);
+ if (appid.isEmpty()) {
+ html.
+ p()._("Sorry, can't do anything without a App Id.")._();
+ return;
+ }
+ ApplicationId applicationId = Apps.toAppID(appid);
+ ApplicationHistoryData applicationHistoryData;
+ try {
+ applicationHistoryData = appHistoryReader
+ .getApplication(applicationId);
+ } catch (IOException e) {
+ return;
+ }
+ if (applicationHistoryData == null) {
+ html.
+ p()._("Sorry, ", applicationId, " not found.")._();
+ return;
+ }
+ Collection applicationAttempts;
+ try {
+ applicationAttempts = appHistoryReader
+ .getApplicationAttempts(applicationId).values();
+ } catch (IOException e) {
+ html.p()._("Sorry, Failed to read attempts for App Id:" + applicationId)
+ ._();
+ return;
+ }
+ info("Application Overview").
+ _("Application Name:", applicationHistoryData.getApplicationName()).
+ _("Type:", applicationHistoryData.getApplicationType()).
+ _("User Name:", applicationHistoryData.getApplicationName()).
+ _("Queue:", applicationHistoryData.getQueue()).
+ _("Submitted:", new Date(applicationHistoryData.getSubmitTime())).
+ _("Started:", new Date(applicationHistoryData.getStartTime())).
+ _("Finished:", new Date(applicationHistoryData.getFinishTime())).
+ _("Final Status:", applicationHistoryData.getFinalApplicationStatus()).
+ _("Diagnostics:", applicationHistoryData.getDiagnosticsInfo()).
+ _("Elapsed:", StringUtils.formatTime(
+ Times.elapsed(applicationHistoryData.getStartTime(), applicationHistoryData.getFinishTime(), false)));
+
+ DIV div = html._(InfoBlock.class).div(_INFO_WRAP);
+
+
+ String amString =
+ applicationAttempts.size() >1 ? "ApplicationMasters" : "ApplicationMaster";
+
+ TABLE> table = div.table("#attempts");
+ table.
+ tr().
+ th(amString)._().
+ tr().
+ th(_TH, "Attempt Number").
+ th(_TH, "Host").
+ th(_TH, "RPC Port").
+ th(_TH, "Tracking URL").
+ th(_TH, "Diagnostics Info").
+ th(_TH, "Final Application Status").
+ th(_TH, "Master Container Id").
+ _();
+
+ boolean odd = false;
+ for (ApplicationAttemptHistoryData attemptData : applicationAttempts) {
+ ApplicationAttemptId appAttemptId = attemptData.getApplicationAttemptId();
+ table.tr((odd = !odd) ? _ODD : _EVEN).
+ td().a(url("appattempt", appAttemptId.toString()), String.valueOf(appAttemptId.getAttemptId()))._().
+ td(attemptData.getHost()).
+ td(String.valueOf(attemptData.getRPCPort())).
+ td(attemptData.getTrackingURL()).
+ td(attemptData.getDiagnosticsInfo()).
+ td(String.valueOf(attemptData.getFinalApplicationStatus())).
+ td().a(url("container", attemptData.getMasterContainerId().toString()),
+ String.valueOf(attemptData.getMasterContainerId()))._()._();
+ }
+ table._();
+ div._();
+ }
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSApplicationPage.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSApplicationPage.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSApplicationPage.java (working copy)
@@ -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.yarn.server.applicationhistoryservice.webapp;
+
+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;
+import org.apache.hadoop.yarn.webapp.YarnWebParams;
+
+public class AHSApplicationPage extends AHSView {
+
+ @Override
+ protected void preHead(Page.HTML<_> html) {
+ String appId = $(YarnWebParams.APPLICATION_ID);
+ set(TITLE, appId.isEmpty() ? "Bad request: missing application ID" : join(
+ "YARN Application ", $(YarnWebParams.APPLICATION_ID)));
+ commonPreHead(html);
+ set(initID(ACCORDION, "nav"), "{autoHeight:false, active:1}");
+ }
+
+ @Override
+ protected Class extends SubView> content() {
+ return AHSApplicationBlock.class;
+ }
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSNavBlock.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSNavBlock.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSNavBlock.java (working copy)
@@ -0,0 +1,71 @@
+/**
+ * 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.applicationhistoryservice.webapp;
+
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.util.ConverterUtils;
+import org.apache.hadoop.yarn.webapp.YarnWebParams;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+
+public class AHSNavBlock extends HtmlBlock {
+
+ @Override
+ protected void render(Block html) {
+ DIV
nav = html.
+ div("#nav").
+ h3("Application History").
+ ul().
+ li().a(url("about"), "About")._().
+ li().a("/applicationhistory", "Applications")._()._();
+ String appId = $(YarnWebParams.APPLICATION_ID);
+ String appAttemptId = $(YarnWebParams.APPLICATION_ATTEMPT_ID);
+ String containerId = $(YarnWebParams.CONTAINER_ID);
+ if (appAttemptId.isEmpty() == false) {
+ appId = ConverterUtils.toApplicationAttemptId(appAttemptId)
+ .getApplicationId().toString();
+ } else if (containerId.isEmpty() == false) {
+ ContainerId contId = ConverterUtils.toContainerId(containerId);
+ appAttemptId = contId.getApplicationAttemptId().toString();
+ appId = contId.getApplicationAttemptId().getApplicationId().toString();
+ }
+ if (appId.isEmpty() == false) {
+ nav.
+ h3("Application").
+ ul().
+ li().a(url("application", appId), "Overview")._().
+ li().a(url("appattempts", appId), "Attempts")._().
+ li().a(url("appcontainers", appId), "Containers")._()._();
+ }
+ if (appAttemptId.isEmpty() == false) {
+ nav.
+ h3("Application Attempt").
+ ul().
+ li().a(url("appattempt", appAttemptId), "Overview")._().
+ li().a(url("appattemptcontainers", appAttemptId), "Containers")._()._();
+ }
+ nav.
+ h3("Tools").
+ ul().
+ li().a("/conf", "Configuration")._().
+ li().a("/stacks", "Thread dump")._().
+ li().a("/logs", "Logs")._().
+ li().a("/metrics", "Metrics")._()._()._();
+ }
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSView.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSView.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSView.java (working copy)
@@ -0,0 +1,95 @@
+/**
+ * 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.applicationhistoryservice.webapp;
+
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.ACCORDION;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.ACCORDION_ID;
+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.yarn.webapp.SubView;
+import org.apache.hadoop.yarn.webapp.view.TwoColumnLayout;
+
+public class AHSView extends TwoColumnLayout {
+
+ @Override
+ protected void preHead(Page.HTML<_> html) {
+ commonPreHead(html);
+ set(DATATABLES_ID, "appsTableData");
+ setTableStyles(html, "appsTableData", ".queue {width:6em}",
+ ".ui {width:8em}");
+ set(initID(DATATABLES, "appsTableData"), appsTableInit());
+ set(postInitID(DATATABLES, "appsTableData"), appsPostTableInit());
+ setTitle("Application History");
+ }
+
+ protected void commonPreHead(Page.HTML<_> html) {
+ set(ACCORDION_ID, "nav");
+ set(initID(ACCORDION, "nav"), "{autoHeight:false, active:0}");
+ }
+
+ @Override
+ protected Class extends SubView> nav() {
+ return AHSNavBlock.class;
+ }
+
+ @Override
+ protected Class extends SubView> content() {
+ return ApplicationHistoryView.class;
+ }
+
+ private String appsPostTableInit() {
+ return "var asInitVals = new Array();\n" +
+ "$('tfoot input').keyup( function () \n{"+
+ " appsTableDataDataTable.fnFilter( this.value, $('tfoot input').index(this) );\n"+
+ "} );\n"+
+ "$('tfoot input').each( function (i) {\n"+
+ " asInitVals[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 = asInitVals[$('tfoot input').index(this)];\n"+
+ " }\n"+
+ "} );\n";
+ }
+
+ private String appsTableInit() {
+ return tableInit().
+ append(", 'aaData': appsTableData").
+ append(", bDeferRender: true").
+ append(", bProcessing: true").
+
+ // Sort by id upon page load
+ append(", aaSorting: [[0, 'desc']]").
+ append(", aoColumnDefs:[").
+ append("]}").
+ toString();
+ }
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebApp.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebApp.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebApp.java (working copy)
@@ -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.yarn.server.applicationhistoryservice.webapp;
+
+import static org.apache.hadoop.yarn.util.StringHelper.pajoin;
+
+import org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryReader;
+import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
+import org.apache.hadoop.yarn.webapp.WebApp;
+import org.apache.hadoop.yarn.webapp.YarnWebParams;
+
+public class AHSWebApp extends WebApp implements YarnWebParams {
+
+ private final ApplicationHistoryReader appHistoryReader;
+
+ public AHSWebApp(ApplicationHistoryReader appHistoryReader) {
+ this.appHistoryReader = appHistoryReader;
+ }
+
+ @Override
+ public void setup() {
+// bind(AHSWebServices.class);
+ bind(GenericExceptionHandler.class);
+// bind(AHSJAXBContextResolver.class);
+ bind(ApplicationHistoryReader.class).toInstance(this.appHistoryReader);
+ route("/", ApplicationHistoryController.class, "applicationHistory");
+ route("/about", ApplicationHistoryController.class, "about");
+ route("/applicationhistory", ApplicationHistoryController.class,
+ "applicationHistory");
+ route(pajoin("/application", YarnWebParams.APPLICATION_ID),
+ ApplicationHistoryController.class, "application");
+ route(pajoin("/appattempts", YarnWebParams.APPLICATION_ID),
+ ApplicationHistoryController.class, "appAttempts");
+ route(pajoin("/appattempt", YarnWebParams.APPLICATION_ATTEMPT_ID),
+ ApplicationHistoryController.class, "appAttempt");
+ route(pajoin("/appcontainers", YarnWebParams.APPLICATION_ID),
+ ApplicationHistoryController.class, "appContainers");
+ route(
+ pajoin("/appattemptcontainers", YarnWebParams.APPLICATION_ATTEMPT_ID),
+ ApplicationHistoryController.class, "appAttemptContainers");
+ route(pajoin("/container", YarnWebParams.CONTAINER_ID),
+ ApplicationHistoryController.class, "container");
+ }
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/ApplicationHistoryController.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/ApplicationHistoryController.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/ApplicationHistoryController.java (working copy)
@@ -0,0 +1,64 @@
+/**
+ * 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.applicationhistoryservice.webapp;
+
+import org.apache.hadoop.yarn.webapp.Controller;
+import org.apache.hadoop.yarn.webapp.YarnWebParams;
+
+public class ApplicationHistoryController extends Controller implements
+ YarnWebParams {
+
+ public void applicationHistory() {
+ render(ApplicationHistoryPage.class);
+ }
+
+ public void about() {
+ render(AHSAboutPage.class);
+ }
+
+ public void application() {
+ render(AHSApplicationPage.class);
+ }
+
+ public void appAttempts() {
+ render(AHSAppAttemptsPage.class);
+ }
+
+ public void appAttempt() {
+ render(AHSAppAttemptPage.class);
+ }
+
+ public void appContainers() {
+ render(AHSAppContainersPage.class);
+ }
+
+ public void appAttemptContainers() {
+ render(AHSAppAttemptContainersPage.class);
+ }
+
+ public void container() {
+ render(AHSAppContainerPage.class);
+ }
+
+ @Override
+ public void index() {
+ setTitle("ApplicationHistory");
+ }
+
+
+}
\ No newline at end of file
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/ApplicationHistoryPage.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/ApplicationHistoryPage.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/ApplicationHistoryPage.java (working copy)
@@ -0,0 +1,123 @@
+/**
+ * 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.applicationhistoryservice.webapp;
+
+import java.util.Collection;
+import java.util.Date;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryReader;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.records.ApplicationHistoryData;
+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.HamletSpec.InputType;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+
+import com.google.inject.Inject;
+
+public class ApplicationHistoryPage extends AHSView {
+
+ @Override
+ protected Class extends SubView> content() {
+ return ApplicationHistoryView.class;
+ }
+}
+
+class ApplicationHistoryView extends HtmlBlock {
+ final SimpleDateFormat dateFormat = new SimpleDateFormat(
+ "yyyy.MM.dd HH:mm:ss z");
+ private final ApplicationHistoryReader appHistoryReader;
+
+ @Inject
+ ApplicationHistoryView(ApplicationHistoryReader appHistoryReader) {
+ this.appHistoryReader = appHistoryReader;
+ }
+
+ @Override
+ protected void render(Block html) {
+ Collection values;
+ try {
+ values = appHistoryReader.getAllApplications().values();
+ } catch (IOException e) {
+ String message = "Failed to read applications.";
+ LOG.error(message, e);
+ html.p()._(message)._();
+ return;
+ }
+ TBODY> tbody = html.
+ h2("Completed Applications").
+ table("#appsTableData").
+ thead().
+ tr().
+ th(".id", "Application ID").
+ th(".name", "Name").
+ th("Application Type").
+ th("User").
+ th("Queue").
+ th("Submit Time").
+ th("Start Time").
+ th("Finish Time").
+ th("Diagnostics").
+ th(".state", "Final Application Status")._()._().
+ tbody();
+
+ StringBuilder appsTableData = new StringBuilder("[\n");
+ for (ApplicationHistoryData appHistoryData : values) {
+ String appId = String.valueOf(appHistoryData.getApplicationId());
+ appsTableData.append("[\"")
+ .append("").append(appId).append("\",\"")
+ .append(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(appHistoryData.getApplicationName()))).append("\",\"")
+ .append(appHistoryData.getApplicationType()).append("\",\"")
+ .append(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(appHistoryData.getUser()))).append("\",\"")
+ .append(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(appHistoryData.getQueue()))).append("\",\"")
+ .append(dateFormat.format(new Date(appHistoryData.getSubmitTime()))).append("\",\"")
+ .append(dateFormat.format(new Date(appHistoryData.getStartTime()))).append("\",\"")
+ .append(dateFormat.format(new Date(appHistoryData.getFinishTime()))).append("\",\"")
+ .append(appHistoryData.getDiagnosticsInfo()).append("\",\"")
+ .append(appHistoryData.getFinalApplicationStatus()).append("\"],\n");
+ }
+
+ // Remove the last comma and close off the array of arrays
+ if (appsTableData.charAt(appsTableData.length() - 2) == ',') {
+ appsTableData.delete(appsTableData.length() - 2,
+ appsTableData.length() - 1);
+ }
+ appsTableData.append("]");
+ html.script().$type("text/javascript")._(
+ "var appsTableData=" + appsTableData)._();
+ tbody._().
+ tfoot().
+ tr().
+ th().input("search_init").$type(InputType.text).$name("application_id").$value("Application ID")._()._().
+ th().input("search_init").$type(InputType.text).$name("name").$value("Name")._()._().
+ th().input("search_init").$type(InputType.text).$name("application_type").$value("Application Type")._()._().
+ th().input("search_init").$type(InputType.text).$name("user").$value("User")._()._().
+ th().input("search_init").$type(InputType.text).$name("queue").$value("Queue")._()._().
+ th().input("search_init").$type(InputType.text).$name("submit_time").$value("Submit Time")._()._().
+ th().input("search_init").$type(InputType.text).$name("start_time").$value("Start Time")._()._().
+ th().input("search_init").$type(InputType.text).$name("finish_time").$value("Finish Time")._()._().
+ th().input("search_init").$type(InputType.text).$name("diagnostics").$value("Diagnostics")._()._()
+ .th().input("search_init").$type(InputType.text).$name("final_status").$value("Final Application Status")
+ ._()
+ ._()._()._()._();
+ }
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/dao/AHSInfo.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/dao/AHSInfo.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/dao/AHSInfo.java (working copy)
@@ -0,0 +1,58 @@
+/**
+ * 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.applicationhistoryservice.webapp.dao;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.hadoop.util.VersionInfo;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryServer;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class AHSInfo {
+
+ protected long startedOn;
+ protected String hadoopVersion;
+ protected String hadoopBuildVersion;
+ protected String hadoopVersionBuiltOn;
+
+ public AHSInfo() {
+ this.startedOn = ApplicationHistoryServer.appHistoryServerTimeStamp;
+ this.hadoopVersion = VersionInfo.getVersion();
+ this.hadoopBuildVersion = VersionInfo.getBuildVersion();
+ this.hadoopVersionBuiltOn = VersionInfo.getDate();
+ }
+
+ public String getHadoopVersion() {
+ return this.hadoopVersion;
+ }
+
+ public String getHadoopBuildVersion() {
+ return this.hadoopBuildVersion;
+ }
+
+ public String getHadoopVersionBuiltOn() {
+ return this.hadoopVersionBuiltOn;
+ }
+
+ public long getStartedOn() {
+ return this.startedOn;
+ }
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/MockApplicationHistoryReader.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/MockApplicationHistoryReader.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/MockApplicationHistoryReader.java (working copy)
@@ -0,0 +1,151 @@
+/**
+ * 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.applicationhistoryservice.webapp;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+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.FinalApplicationStatus;
+import org.apache.hadoop.yarn.api.records.NodeId;
+import org.apache.hadoop.yarn.api.records.Priority;
+import org.apache.hadoop.yarn.api.records.Resource;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryReader;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.records.ApplicationAttemptHistoryData;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.records.ApplicationHistoryData;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.records.ContainerHistoryData;
+import org.apache.hadoop.yarn.util.Records;
+
+public class MockApplicationHistoryReader implements ApplicationHistoryReader {
+ private Map apps =
+ new HashMap();
+ private Map> attempts =
+ new HashMap>();
+ private Map> containers =
+ new HashMap>();
+
+ public MockApplicationHistoryReader(int noOfApps) throws IOException {
+ long timeStamp = System.currentTimeMillis();
+ for (int i = 0; i < noOfApps; i++) {
+ ApplicationId applicationId = ApplicationId.newInstance(timeStamp, i);
+ apps.put(applicationId, getApplication(applicationId));
+ }
+ }
+
+ public MockApplicationHistoryReader(int noOfApps, int noOfAttempts)
+ throws IOException {
+ this(noOfApps);
+ for (ApplicationId appId : apps.keySet()) {
+ Map appAttempts =
+ new HashMap();
+ for (int i = 0; i < noOfAttempts; i++) {
+ ApplicationAttemptId attemptId =
+ ApplicationAttemptId.newInstance(appId, i);
+ appAttempts.put(attemptId, getApplicationAttempt(attemptId));
+ }
+ attempts.put(appId, appAttempts);
+ }
+ }
+
+ public MockApplicationHistoryReader(int noOfApps, int noOfAttempts,
+ int noOfContainers) throws IOException {
+ this(noOfApps, noOfAttempts);
+ for (ApplicationId appId : attempts.keySet()) {
+ for (ApplicationAttemptId attemptId : attempts.get(appId).keySet()) {
+ Map attemptContainers =
+ new HashMap();
+ for (int i = 0; i < noOfContainers; i++) {
+ ContainerId containerId = ContainerId.newInstance(attemptId, i);
+ attemptContainers.put(containerId, getContainer(containerId));
+ }
+ containers.put(attemptId, attemptContainers);
+ }
+ }
+ }
+
+ @Override
+ public ContainerHistoryData getAMContainer(ApplicationAttemptId appAttemptId)
+ throws IOException {
+ ContainerHistoryData data = Records.newRecord(ContainerHistoryData.class);
+ data.setContainerId(ContainerId.newInstance(appAttemptId, 0));
+ data.setAssignedNode(NodeId.newInstance("abc", 10));
+ data.setPriority(Priority.newInstance(10));
+ data.setAllocatedResource(Resource.newInstance(1024, 1));
+ return data;
+ }
+
+ @Override
+ public Map getAllApplications()
+ throws IOException {
+ return apps;
+ }
+
+ @Override
+ public ApplicationHistoryData getApplication(ApplicationId appId)
+ throws IOException {
+ ApplicationHistoryData appHistoryData =
+ Records.newRecord(ApplicationHistoryData.class);
+ appHistoryData.setApplicationId(appId);
+ appHistoryData.setQueue("Testqueue");
+ appHistoryData.setUser("TestUser");
+ return appHistoryData;
+ }
+
+ @Override
+ public ApplicationAttemptHistoryData getApplicationAttempt(
+ ApplicationAttemptId appAttemptId) throws IOException {
+ ApplicationAttemptHistoryData data =
+ Records.newRecord(ApplicationAttemptHistoryData.class);
+ data.setApplicationAttemptId(appAttemptId);
+ ContainerId containerId = ContainerId.newInstance(appAttemptId, 0);
+ data.setMasterContainerId(containerId);
+ data.setDiagnosticsInfo("Test Diagnostic info");
+ data.setHost("TestHost");
+ data.setRPCPort(123);
+ data.setFinalApplicationStatus(FinalApplicationStatus.SUCCEEDED);
+ data.setTrackingURL("http://trackingurl.com");
+ return data;
+ }
+
+ @Override
+ public Map getApplicationAttempts(
+ ApplicationId appId) throws IOException {
+ return attempts.get(appId);
+ }
+
+ @Override
+ public ContainerHistoryData getContainer(ContainerId containerId)
+ throws IOException {
+ ContainerHistoryData data = Records.newRecord(ContainerHistoryData.class);
+ data.setContainerId(containerId);
+ data.setAssignedNode(NodeId.newInstance("abc", 10));
+ data.setPriority(Priority.newInstance(10));
+ data.setAllocatedResource(Resource.newInstance(1024, 1));
+ return data;
+ }
+
+ @Override
+ public Map getContainers(
+ ApplicationAttemptId appAttemptId) throws IOException {
+ return containers.get(appAttemptId);
+ }
+
+}
Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/TestAHSWebApp.java
===================================================================
--- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/TestAHSWebApp.java (revision 0)
+++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/test/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/TestAHSWebApp.java (working copy)
@@ -0,0 +1,207 @@
+/**
+ * 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.applicationhistoryservice.webapp;
+
+import static org.apache.hadoop.yarn.webapp.Params.TITLE;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.atLeastOnce;
+
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryReader;
+import org.apache.hadoop.yarn.webapp.YarnWebParams;
+import org.apache.hadoop.yarn.webapp.test.WebAppTests;
+import org.junit.Test;
+
+import com.google.inject.Injector;
+
+public class TestAHSWebApp {
+ private final static Map EMPTY_MAP =
+ new HashMap();
+
+ @Test
+ public void testAppControllerIndex() throws Throwable {
+ ApplicationHistoryReader mockAppHSReader =
+ new MockApplicationHistoryReader(0);
+ Injector injector =
+ WebAppTests.createMockInjector(ApplicationHistoryReader.class,
+ mockAppHSReader);
+ ApplicationHistoryController controller =
+ injector.getInstance(ApplicationHistoryController.class);
+ controller.index();
+ assertEquals("ApplicationHistory", controller.get(TITLE, "unknown"));
+ }
+
+ @Test
+ public void testApplicationsPage() throws Throwable {
+ ApplicationHistoryReader mockAppHSReader =
+ new MockApplicationHistoryReader(5);
+ Injector injector =
+ WebAppTests.testPage(ApplicationHistoryPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader,
+ new HashMap());
+ PrintWriter spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw).write("Completed Applications");
+ }
+
+ @Test
+ public void testApplicationPage() throws Throwable {
+ ApplicationHistoryReader mockAppHSReader =
+ new MockApplicationHistoryReader(1);
+ Injector injector =
+ WebAppTests.testPage(AHSApplicationPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader, EMPTY_MAP);
+ PrintWriter spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw).write("Sorry, can't do anything without a App Id.");
+
+ HashMap params = new HashMap();
+ ApplicationId applicationId =
+ mockAppHSReader.getAllApplications().values().iterator().next()
+ .getApplicationId();
+ params.put(YarnWebParams.APPLICATION_ID, applicationId.toString());
+ injector =
+ WebAppTests.testPage(AHSApplicationPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader, params);
+ spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw, atLeastOnce()).write("YARN Application " + applicationId);
+ }
+
+ @Test
+ public void testAppAttemptsPage() throws Throwable {
+ ApplicationHistoryReader mockAppHSReader =
+ new MockApplicationHistoryReader(1, 4);
+ Injector injector =
+ WebAppTests.testPage(AHSAppAttemptsPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader, EMPTY_MAP);
+ PrintWriter spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw).write("Sorry, can't do anything without a App Id.");
+
+ HashMap params = new HashMap();
+ ApplicationId applicationId =
+ mockAppHSReader.getAllApplications().values().iterator().next()
+ .getApplicationId();
+ params.put(YarnWebParams.APPLICATION_ID, applicationId.toString());
+ injector =
+ WebAppTests.testPage(AHSAppAttemptsPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader, params);
+ spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw, atLeastOnce()).write("YARN Application " + applicationId);
+ }
+
+ @Test
+ public void testAppAttemptPage() throws Throwable {
+ ApplicationHistoryReader mockAppHSReader =
+ new MockApplicationHistoryReader(1, 1);
+ Injector injector = WebAppTests.testPage(AHSAppAttemptPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader, EMPTY_MAP);
+ PrintWriter spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw).write("Sorry, can't do anything without a App Attempt Id.");
+
+ HashMap params = new HashMap();
+ ApplicationId appId =
+ mockAppHSReader.getAllApplications().values().iterator().next()
+ .getApplicationId();
+ ApplicationAttemptId applicationAttemptId = mockAppHSReader
+ .getApplicationAttempts(appId).values().iterator().next()
+ .getApplicationAttemptId();
+ params.put(YarnWebParams.APPLICATION_ATTEMPT_ID, applicationAttemptId.toString());
+ injector = WebAppTests.testPage(AHSAppAttemptPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader, params);
+ spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw, atLeastOnce()).write("YARN Application " + applicationAttemptId);
+ }
+
+ @Test
+ public void testAppContainersPage() throws Throwable {
+ ApplicationHistoryReader mockAppHSReader =
+ new MockApplicationHistoryReader(1, 2, 10);
+ Injector injector =
+ WebAppTests.testPage(AHSAppContainersPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader, EMPTY_MAP);
+ PrintWriter spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw).write("Sorry, can't do anything without a App Id.");
+
+ HashMap params = new HashMap();
+ params.put(YarnWebParams.APPLICATION_ID, mockAppHSReader
+ .getAllApplications().values().iterator().next().getApplicationId()
+ .toString());
+ injector =
+ WebAppTests.testPage(AHSAppContainersPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader, params);
+ spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw, atLeastOnce()).write("Containers");
+ }
+
+ @Test
+ public void testAppAttemptContainersPage() throws Throwable {
+ ApplicationHistoryReader mockAppHSReader =
+ new MockApplicationHistoryReader(1, 1, 10);
+ Injector injector =
+ WebAppTests.testPage(AHSAppAttemptContainersPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader, EMPTY_MAP);
+ PrintWriter spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw).write("Sorry, can't do anything without a AppAttempt Id.");
+
+ HashMap params = new HashMap();
+ ApplicationId appId =
+ mockAppHSReader.getAllApplications().values().iterator().next()
+ .getApplicationId();
+ params.put(YarnWebParams.APPLICATION_ATTEMPT_ID, mockAppHSReader
+ .getApplicationAttempts(appId).values().iterator().next()
+ .getApplicationAttemptId().toString());
+ injector =
+ WebAppTests.testPage(AHSAppAttemptContainersPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader, params);
+ spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw, atLeastOnce()).write("Containers");
+ }
+
+ @Test
+ public void testAppContainerPage() throws Throwable {
+ ApplicationHistoryReader mockAppHSReader =
+ new MockApplicationHistoryReader(1, 1, 1);
+ Injector injector =
+ WebAppTests.testPage(AHSAppContainerPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader,
+ new HashMap());
+ PrintWriter spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw).write("Sorry, can't do anything without a Container Id.");
+
+ HashMap params = new HashMap();
+ ApplicationId appId =
+ mockAppHSReader.getAllApplications().values().iterator().next()
+ .getApplicationId();
+ ApplicationAttemptId attemptId =
+ mockAppHSReader.getApplicationAttempts(appId).values().iterator()
+ .next().getApplicationAttemptId();
+ String containerId =
+ mockAppHSReader.getContainers(attemptId).values().iterator().next()
+ .getContainerId().toString();
+ params.put(YarnWebParams.CONTAINER_ID, containerId);
+ injector =
+ WebAppTests.testPage(AHSAppContainerPage.class,
+ ApplicationHistoryReader.class, mockAppHSReader, params);
+ spyPw = WebAppTests.getPrintWriter(injector);
+ verify(spyPw, atLeastOnce()).write("YARN Application " + containerId);
+ }
+}