Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/YarnWebParams.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/YarnWebParams.java (revision 1509937) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/YarnWebParams.java (working copy) @@ -24,6 +24,7 @@ public interface YarnWebParams { String NM_NODENAME = "nm.id"; String APPLICATION_ID = "app.id"; + String APPLICATION_ATTEMPT_ID = "appattempt.id"; String CONTAINER_ID = "container.id"; String CONTAINER_LOG_TYPE= "log.type"; String ENTITY_STRING = "entity.string"; Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/AHSWebServer.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/AHSWebServer.java (revision 1509937) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/AHSWebServer.java (working copy) @@ -18,12 +18,40 @@ package org.apache.hadoop.yarn.server.applicationhistoryservice; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.hadoop.service.AbstractService; +import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; +import org.apache.hadoop.yarn.server.applicationhistoryservice.webapp.AHSWebApp; +import org.apache.hadoop.yarn.webapp.WebApps; public class AHSWebServer extends AbstractService { + private static final Log LOG = LogFactory.getLog(AHSWebServer.class); + private AHSWebApp webApp; - public AHSWebServer() { + public AHSWebServer(ApplicationHistoryReader appHistoryReader) { super(AHSWebServer.class.getName()); + webApp = new AHSWebApp(appHistoryReader); } -} + @Override + protected void serviceStart() throws Exception { + String bindAddress = getConfig().get( + "yarn.applicationhistoryserver.webapp.address", "0.0.0.0:19889"); + LOG.info("Instantiating AHSWebApp at " + bindAddress); + try { + WebApps.$for("applicationhistory").at(bindAddress).with(getConfig()) + .start(this.webApp); + } catch (Exception e) { + String msg = "AHSWebapps failed to start."; + LOG.error(msg, e); + throw new YarnRuntimeException(msg, e); + } + super.serviceStart(); + } + + @Override + protected void serviceStop() throws Exception { + super.serviceStop(); + } +} \ 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/ApplicationHistoryServer.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/ApplicationHistoryServer.java (revision 1509937) +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/ApplicationHistoryServer.java (working copy) @@ -33,10 +33,13 @@ @Override protected void serviceInit(Configuration conf) throws Exception { - super.serviceInit(conf); AHSClientService ahsClientService = new AHSClientService(); addService(ahsClientService); - AHSWebServer webServer = new AHSWebServer(); + + // TODO Need to intialize the application history reader + ApplicationHistoryReader appHistoryReader = null; + AHSWebServer webServer = new AHSWebServer(appHistoryReader); addService(webServer); + super.serviceInit(conf); } } Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAboutPage.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAboutPage.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/AHSAboutPage.java (working copy) @@ -0,0 +1,40 @@ +/** + * 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.initID; + +import org.apache.hadoop.yarn.webapp.SubView; +import org.apache.hadoop.yarn.webapp.view.InfoBlock; + +public class AHSAboutPage extends AHSView { + + @Override + protected void preHead(Page.HTML<_> html) { + commonPreHead(html); + set(initID(ACCORDION, "nav"), "{autoHeight:false, active:0}"); + } + + @Override + protected Class content() { + info("History Server")._("BuildVersion", "" + " on " + "")._( + "History Server started on", ""); + return InfoBlock.class; + } +} \ 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/AHSAppAttemptBlock.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppAttemptBlock.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/AHSAppAttemptBlock.java (working copy) @@ -0,0 +1,75 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.yarn.server.applicationhistoryservice.webapp; + +import static org.apache.hadoop.yarn.webapp.view.JQueryUI._INFO_WRAP; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; +import org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryReader; +import org.apache.hadoop.yarn.server.applicationhistoryservice.records.ApplicationAttemptHistoryData; +import org.apache.hadoop.yarn.util.ConverterUtils; +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 AHSAppAttemptBlock extends HtmlBlock { + + private static final Log LOG = LogFactory.getLog(AHSAppAttemptBlock.class); + private final ApplicationHistoryReader appHistoryReader; + + @Inject + public AHSAppAttemptBlock(ApplicationHistoryReader appHistoryReader) { + this.appHistoryReader = appHistoryReader; + } + + @Override + protected void render(Block html) { + String attemptid = $(YarnWebParams.APPLICATION_ATTEMPT_ID); + if (attemptid.isEmpty()) { + html. + p()._("Sorry, can't do anything without a App Attempt Id.")._(); + return; + } + ApplicationAttemptId appAttemptId = ConverterUtils.toApplicationAttemptId(attemptid); + ApplicationAttemptHistoryData applicationAttempt; + try { + applicationAttempt = appHistoryReader.getApplicationAttempt(appAttemptId); + } catch (IOException e) { + String message = "Failed to read application attempts."; + LOG.error(message, e); + html.p()._(message)._(); + return; + } + info("Application Attempt Overview"). + _("Attempt Number:", applicationAttempt.getApplicationAttemptId()). + _("Host:", applicationAttempt.getHost()). + _("RPC Port:", applicationAttempt.getRPCPort()). + _("Tracking URL:", applicationAttempt.getTrackingURL()). + _("Diagnostics Info:", applicationAttempt.getDiagnosticsInfo()). + _("Final Application Status:", applicationAttempt.getFinalApplicationStatus()). + _("Master Container Id:", root_url("container", applicationAttempt.getMasterContainerId().toString()), + String.valueOf(applicationAttempt.getMasterContainerId())); + 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/AHSAppAttemptPage.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppAttemptPage.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/AHSAppAttemptPage.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 AHSAppAttemptPage extends AHSView { + + @Override + protected void preHead(Page.HTML<_> html) { + String appId = $(YarnWebParams.APPLICATION_ATTEMPT_ID); + set(TITLE, appId.isEmpty() ? "Bad request: missing application attempt ID" : join( + "YARN Application ", $(YarnWebParams.APPLICATION_ATTEMPT_ID))); + commonPreHead(html); + set(initID(ACCORDION, "nav"), "{autoHeight:false, active:2}"); + } + + @Override + protected Class content() { + return AHSAppAttemptBlock.class; + } +} Index: hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppAttemptsBlock.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSAppAttemptsBlock.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/AHSAppAttemptsBlock.java (working copy) @@ -0,0 +1,107 @@ +/** + * 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 org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +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.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.DIV; +import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE; +import org.apache.hadoop.yarn.webapp.view.HtmlBlock; + +import com.google.inject.Inject; + +public class AHSAppAttemptsBlock extends HtmlBlock { + + private static final Log LOG = LogFactory.getLog(AHSAppAttemptsBlock.class); + private final ApplicationHistoryReader appHistoryReader; + + @Inject + public AHSAppAttemptsBlock(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); + + DIV div = html.div(_INFO_WRAP); + Collection applicationAttempts; + try { + applicationAttempts = appHistoryReader.getApplicationAttempts( + applicationId).values(); + } catch (IOException e) { + String message = "Failed to read application attempts."; + LOG.error(message, e); + html.p()._(message)._(); + return; + } + 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/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 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 ", $(YarnWebParams.CONTAINER_ID))); + commonPreHead(html); + set(initID(ACCORDION, "nav"), "{autoHeight:false, active:1}"); + } + + @Override + protected Class 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,133 @@ +/** + * 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.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.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"); + private 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/AppAttempt Id.")._(); + return; + } + Collection containers; + try { + if (id.startsWith(ConverterUtils.APPLICATION_PREFIX)) { + ApplicationId applicationId = Apps.toAppID(id); + containers = new ArrayList(); + Set keySet = appHistoryReader + .getApplicationAttempts(applicationId).keySet(); + for (ApplicationAttemptId applicationAttemptId : keySet) { + containers.addAll(appHistoryReader + .getContainers(applicationAttemptId).values()); + } + } else { + ApplicationAttemptId applicationAttemptId = ConverterUtils + .toApplicationAttemptId(id); + containers = appHistoryReader.getContainers(applicationAttemptId) + .values(); + } + } catch (IOException e) { + html.p()._("Sorry, Failed to get containers for app/appattempt id:" + id)._(); + return; + } + 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("start_time").$value("Container ID")._()._(). + th().input("search_init").$type(InputType.text).$name("finish_time").$value("Allocated Resource")._()._(). + th().input("search_init").$type(InputType.text).$name("start_time").$value("Assigned Node")._()._(). + th().input("search_init").$type(InputType.text).$name("start_time").$value("Priority")._()._(). + th().input("search_init").$type(InputType.text).$name("start_time").$value("Start Time")._()._(). + th().input("search_init").$type(InputType.text).$name("start_time").$value("Finish Time")._()._(). + th().input("search_init").$type(InputType.text).$name("start_time").$value("Diagnostics")._()._(). + th().input("search_init").$type(InputType.text).$name("start_time").$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,94 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.yarn.server.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.util.ConverterUtils; +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) { + String appId = $(YarnWebParams.APPLICATION_ID); + set(TITLE, appId.isEmpty() ? "Bad request: missing application ID" : join( + "YARN Application ", $(YarnWebParams.APPLICATION_ID), " Containers")); + 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()); + setTitle("Application History"); + if (appId.startsWith(ConverterUtils.APPLICATION_PREFIX)) { + set(initID(ACCORDION, "nav"), "{autoHeight:false, active:1}"); + } else { + set(initID(ACCORDION, "nav"), "{autoHeight:false, active:2}"); + } + } + + 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 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 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/AHSJAXBContextResolver.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSJAXBContextResolver.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/AHSJAXBContextResolver.java (working copy) @@ -0,0 +1,52 @@ +/** + * 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.Arrays; +import java.util.HashSet; +import java.util.Set; + +import javax.ws.rs.ext.ContextResolver; +import javax.ws.rs.ext.Provider; +import javax.xml.bind.JAXBContext; + +import com.google.inject.Singleton; +import com.sun.jersey.api.json.JSONConfiguration; +import com.sun.jersey.api.json.JSONJAXBContext; + +@Singleton +@Provider +@SuppressWarnings("unchecked") +public class AHSJAXBContextResolver implements ContextResolver { + + private JAXBContext context; + private final Set types; + + private final Class[] cTypes = {}; + + public AHSJAXBContextResolver() throws Exception { + this.types = new HashSet(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; + } +} \ 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/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,66 @@ +/** + * 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.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); + appAttemptId = (appAttemptId.isEmpty() && appId + .startsWith(ConverterUtils.APPLICATION_ATTEMPT_PREFIX)) ? appId + : appAttemptId; + String containerId = $(YarnWebParams.CONTAINER_ID); + if (appId.isEmpty() == false || appAttemptId.isEmpty() == false + || containerId.isEmpty() == false) { + nav. + h3("Application"). + ul(). + li().a(url("application", appId), "Overview")._(). + li().a(url("appattempts", appId), "Attempts")._(). + li().a(url("containers", appId), "Containers")._()._(); + } + if (appAttemptId.isEmpty() == false) { + nav. + h3("Application Attempt"). + ul(). + li().a(url("appattempt", appAttemptId), "Overview")._(). + li().a(url("containers", 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 nav() { + return AHSNavBlock.class; + } + + @Override + protected Class 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,57 @@ +/** + * 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("/containers", YarnWebParams.APPLICATION_ID), + ApplicationHistoryController.class, "containers"); + 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/AHSWebServices.java =================================================================== --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/src/main/java/org/apache/hadoop/yarn/server/applicationhistoryservice/webapp/AHSWebServices.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/AHSWebServices.java (working copy) @@ -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.yarn.server.applicationhistoryservice.webapp; + +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.Path; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.UriInfo; + +import org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryReader; +import org.apache.hadoop.yarn.webapp.WebApp; + +import com.google.inject.Inject; + +@Path("/ws/v1/applicationhistory") +@SuppressWarnings("unused") +public class AHSWebServices { + private WebApp webapp; + + @Context + private HttpServletResponse response; + @Context + private UriInfo uriInfo; + + private ApplicationHistoryReader appHistoryReader; + + @Inject + public AHSWebServices(ApplicationHistoryReader appHistoryReader, WebApp webapp) { + this.appHistoryReader = appHistoryReader; + this.webapp = webapp; + } +} 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,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 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 containers() { + render(AHSAppContainersPage.class); + } + + public void container() { + render(AHSAppContainerPage.class); + } + + @Override + public void index() { + } + + +} \ 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 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") + ._() + ._()._()._()._(); + } +}