1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 package org.apache.hadoop.yarn.server.resourcemanager.webapp;
20 
21 import static org.apache.hadoop.yarn.util.StringHelper.join;
22 import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR;
23 import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR_VALUE;
24 
25 import java.util.Set;
26 
27 import org.apache.commons.lang.StringEscapeUtils;
28 import org.apache.hadoop.yarn.api.ApplicationBaseProtocol;
29 import org.apache.hadoop.yarn.api.records.ApplicationReport;
30 import org.apache.hadoop.yarn.api.records.YarnApplicationState;
31 import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
32 import org.apache.hadoop.yarn.server.webapp.AppsBlock;
33 import org.apache.hadoop.yarn.server.webapp.dao.AppInfo;
34 import org.apache.hadoop.yarn.util.ConverterUtils;
35 import org.apache.hadoop.yarn.webapp.View;
36 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
37 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE;
38 import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY;
39 
40 import com.google.inject.Inject;
41 
42 public class RMAppsBlock extends AppsBlock {
43 
44   private ResourceManager rm;
45 
46   @Inject
RMAppsBlock(ResourceManager rm, ApplicationBaseProtocol appBaseProt, View.ViewContext ctx)47   RMAppsBlock(ResourceManager rm, ApplicationBaseProtocol appBaseProt,
48       View.ViewContext ctx) {
49     super(appBaseProt, ctx);
50     this.rm = rm;
51   }
52 
53   @Override
renderData(Block html)54   protected void renderData(Block html) {
55     TBODY<TABLE<Hamlet>> tbody =
56         html.table("#apps").thead().tr().th(".id", "ID").th(".user", "User")
57           .th(".name", "Name").th(".type", "Application Type")
58           .th(".queue", "Queue").th(".starttime", "StartTime")
59           .th(".finishtime", "FinishTime").th(".state", "State")
60           .th(".finalstatus", "FinalStatus").th(".progress", "Progress")
61           .th(".ui", "Tracking UI").th(".blacklisted", "Blacklisted Nodes")._()
62           ._().tbody();
63 
64     StringBuilder appsTableData = new StringBuilder("[\n");
65     for (ApplicationReport appReport : appReports) {
66       // TODO: remove the following condition. It is still here because
67       // the history side implementation of ApplicationBaseProtocol
68       // hasn't filtering capability (YARN-1819).
69       if (!reqAppStates.isEmpty()
70           && !reqAppStates.contains(appReport.getYarnApplicationState())) {
71         continue;
72       }
73 
74       AppInfo app = new AppInfo(appReport);
75       String blacklistedNodesCount = "N/A";
76       Set<String> nodes =
77           RMAppAttemptBlock
78             .getBlacklistedNodes(rm, ConverterUtils.toApplicationAttemptId(app
79               .getCurrentAppAttemptId()));
80       if (nodes != null) {
81         blacklistedNodesCount = String.valueOf(nodes.size());
82       }
83       String percent = String.format("%.1f", app.getProgress());
84       // AppID numerical value parsed by parseHadoopID in yarn.dt.plugins.js
85       appsTableData
86         .append("[\"<a href='")
87         .append(url("app", app.getAppId()))
88         .append("'>")
89         .append(app.getAppId())
90         .append("</a>\",\"")
91         .append(
92           StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(app
93             .getUser())))
94         .append("\",\"")
95         .append(
96           StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(app
97             .getName())))
98         .append("\",\"")
99         .append(
100           StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(app
101             .getType())))
102         .append("\",\"")
103         .append(
104           StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(app
105             .getQueue()))).append("\",\"").append(app.getStartedTime())
106         .append("\",\"").append(app.getFinishedTime())
107         .append("\",\"")
108         .append(app.getAppState() == null ? UNAVAILABLE : app.getAppState())
109         .append("\",\"")
110         .append(app.getFinalAppStatus())
111         .append("\",\"")
112         // Progress bar
113         .append("<br title='").append(percent).append("'> <div class='")
114         .append(C_PROGRESSBAR).append("' title='").append(join(percent, '%'))
115         .append("'> ").append("<div class='").append(C_PROGRESSBAR_VALUE)
116         .append("' style='").append(join("width:", percent, '%'))
117         .append("'> </div> </div>").append("\",\"<a ");
118 
119       String trackingURL =
120           app.getTrackingUrl() == null
121               || app.getTrackingUrl().equals(UNAVAILABLE) ? null : app
122             .getTrackingUrl();
123 
124       String trackingUI =
125           app.getTrackingUrl() == null
126               || app.getTrackingUrl().equals(UNAVAILABLE) ? "Unassigned" : app
127             .getAppState() == YarnApplicationState.FINISHED
128               || app.getAppState() == YarnApplicationState.FAILED
129               || app.getAppState() == YarnApplicationState.KILLED ? "History"
130               : "ApplicationMaster";
131       appsTableData.append(trackingURL == null ? "#" : "href='" + trackingURL)
132         .append("'>").append(trackingUI).append("</a>\",").append("\"")
133         .append(blacklistedNodesCount).append("\"],\n");
134 
135     }
136     if (appsTableData.charAt(appsTableData.length() - 2) == ',') {
137       appsTableData.delete(appsTableData.length() - 2,
138         appsTableData.length() - 1);
139     }
140     appsTableData.append("]");
141     html.script().$type("text/javascript")
142       ._("var appsTableData=" + appsTableData)._();
143 
144     tbody._()._();
145   }
146 }
147