org.apache.hadoop.yarn.server.webapp.AppsBlock.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.yarn.server.webapp.AppsBlock.java

Source

/**
 * 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.webapp;

import static org.apache.hadoop.yarn.util.StringHelper.join;
import static org.apache.hadoop.yarn.webapp.YarnWebParams.APP_STATE;
import static org.apache.hadoop.yarn.webapp.YarnWebParams.APP_START_TIME_BEGIN;
import static org.apache.hadoop.yarn.webapp.YarnWebParams.APP_START_TIME_END;
import static org.apache.hadoop.yarn.webapp.YarnWebParams.APPS_NUM;
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR;
import static org.apache.hadoop.yarn.webapp.view.JQueryUI.C_PROGRESSBAR_VALUE;

import java.io.IOException;
import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import java.util.EnumSet;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.math.LongRange;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.util.StringUtils;
import org.apache.hadoop.yarn.api.ApplicationBaseProtocol;
import org.apache.hadoop.yarn.api.protocolrecords.GetApplicationsRequest;
import org.apache.hadoop.yarn.api.records.ApplicationReport;
import org.apache.hadoop.yarn.api.records.YarnApplicationState;
import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.hadoop.yarn.server.webapp.dao.AppInfo;
import org.apache.hadoop.yarn.webapp.BadRequestException;
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE;
import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY;
import org.apache.hadoop.yarn.webapp.view.HtmlBlock;

import com.google.inject.Inject;

public class AppsBlock extends HtmlBlock {

    private static final Log LOG = LogFactory.getLog(AppsBlock.class);
    protected ApplicationBaseProtocol appBaseProt;
    protected EnumSet<YarnApplicationState> reqAppStates;
    protected UserGroupInformation callerUGI;
    protected Collection<ApplicationReport> appReports;

    @Inject
    protected AppsBlock(ApplicationBaseProtocol appBaseProt, ViewContext ctx) {
        super(ctx);
        this.appBaseProt = appBaseProt;
    }

    protected void fetchData() throws YarnException, IOException, InterruptedException {
        reqAppStates = EnumSet.noneOf(YarnApplicationState.class);
        String reqStateString = $(APP_STATE);
        if (reqStateString != null && !reqStateString.isEmpty()) {
            String[] appStateStrings = reqStateString.split(",");
            for (String stateString : appStateStrings) {
                reqAppStates.add(YarnApplicationState.valueOf(stateString.trim()));
            }
        }
        callerUGI = getCallerUGI();
        final GetApplicationsRequest request = GetApplicationsRequest.newInstance(reqAppStates);
        String appsNumStr = $(APPS_NUM);
        if (appsNumStr != null && !appsNumStr.isEmpty()) {
            long appsNum = Long.parseLong(appsNumStr);
            request.setLimit(appsNum);
        }

        String appStartedTimeBegainStr = $(APP_START_TIME_BEGIN);
        long appStartedTimeBegain = 0;
        if (appStartedTimeBegainStr != null && !appStartedTimeBegainStr.isEmpty()) {
            appStartedTimeBegain = Long.parseLong(appStartedTimeBegainStr);
            if (appStartedTimeBegain < 0) {
                throw new BadRequestException("app.started-time.begin must be greater than 0");
            }
        }
        String appStartedTimeEndStr = $(APP_START_TIME_END);
        long appStartedTimeEnd = Long.MAX_VALUE;
        if (appStartedTimeEndStr != null && !appStartedTimeEndStr.isEmpty()) {
            appStartedTimeEnd = Long.parseLong(appStartedTimeEndStr);
            if (appStartedTimeEnd < 0) {
                throw new BadRequestException("app.started-time.end must be greater than 0");
            }
        }
        if (appStartedTimeBegain > appStartedTimeEnd) {
            throw new BadRequestException("app.started-time.end must be greater than app.started-time.begin");
        }
        request.setStartRange(new LongRange(appStartedTimeBegain, appStartedTimeEnd));

        if (callerUGI == null) {
            appReports = appBaseProt.getApplications(request).getApplicationList();
        } else {
            appReports = callerUGI.doAs(new PrivilegedExceptionAction<Collection<ApplicationReport>>() {
                @Override
                public Collection<ApplicationReport> run() throws Exception {
                    return appBaseProt.getApplications(request).getApplicationList();
                }
            });
        }
    }

    @Override
    public void render(Block html) {
        setTitle("Applications");

        try {
            fetchData();
        } catch (Exception e) {
            String message = "Failed to read the applications.";
            LOG.error(message, e);
            html.p()._(message)._();
            return;
        }
        renderData(html);
    }

    protected void renderData(Block html) {
        TBODY<TABLE<Hamlet>> tbody = html.table("#apps").thead().tr().th(".id", "ID").th(".user", "User")
                .th(".name", "Name").th(".type", "Application Type").th(".queue", "Queue")
                .th(".priority", "Application Priority").th(".starttime", "StartTime")
                .th(".finishtime", "FinishTime").th(".state", "State").th(".finalstatus", "FinalStatus")
                .th(".progress", "Progress").th(".ui", "Tracking UI")._()._().tbody();

        StringBuilder appsTableData = new StringBuilder("[\n");
        for (ApplicationReport appReport : appReports) {
            // TODO: remove the following condition. It is still here because
            // the history side implementation of ApplicationBaseProtocol
            // hasn't filtering capability (YARN-1819).
            if (!reqAppStates.isEmpty() && !reqAppStates.contains(appReport.getYarnApplicationState())) {
                continue;
            }
            AppInfo app = new AppInfo(appReport);
            String percent = StringUtils.format("%.1f", app.getProgress());
            appsTableData.append("[\"<a href='").append(url("app", app.getAppId())).append("'>")
                    .append(app.getAppId()).append("</a>\",\"")
                    .append(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(app.getUser())))
                    .append("\",\"")
                    .append(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(app.getName())))
                    .append("\",\"")
                    .append(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(app.getType())))
                    .append("\",\"")
                    .append(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(app.getQueue())))
                    .append("\",\"").append(String.valueOf(app.getPriority())).append("\",\"")
                    .append(app.getStartedTime()).append("\",\"").append(app.getFinishedTime()).append("\",\"")
                    .append(app.getAppState() == null ? UNAVAILABLE : app.getAppState()).append("\",\"")
                    .append(app.getFinalAppStatus()).append("\",\"")
                    // Progress bar
                    .append("<br title='").append(percent).append("'> <div class='").append(C_PROGRESSBAR)
                    .append("' title='").append(join(percent, '%')).append("'> ").append("<div class='")
                    .append(C_PROGRESSBAR_VALUE).append("' style='").append(join("width:", percent, '%'))
                    .append("'> </div> </div>").append("\",\"<a ");

            String trackingURL = app.getTrackingUrl() == null || app.getTrackingUrl().equals(UNAVAILABLE) ? null
                    : app.getTrackingUrl();

            String trackingUI = app.getTrackingUrl() == null || app.getTrackingUrl().equals(UNAVAILABLE)
                    ? "Unassigned"
                    : app.getAppState() == YarnApplicationState.FINISHED
                            || app.getAppState() == YarnApplicationState.FAILED
                            || app.getAppState() == YarnApplicationState.KILLED ? "History" : "ApplicationMaster";
            appsTableData.append(trackingURL == null ? "#" : "href='" + trackingURL).append("'>").append(trackingUI)
                    .append("</a>\"],\n");

        }
        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._()._();
    }
}