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