Java tutorial
/** * 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; import java.io.IOException; import java.util.Collection; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.authorize.AuthorizationException; import org.apache.hadoop.service.AbstractService; import org.apache.hadoop.yarn.api.records.ApplicationAccessType; import org.apache.hadoop.yarn.api.records.ApplicationAttemptId; import org.apache.hadoop.yarn.api.records.ApplicationAttemptReport; import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationReport; import org.apache.hadoop.yarn.api.records.ApplicationResourceUsageReport; import org.apache.hadoop.yarn.api.records.ContainerExitStatus; import org.apache.hadoop.yarn.api.records.ContainerId; import org.apache.hadoop.yarn.api.records.ContainerReport; import org.apache.hadoop.yarn.api.records.ContainerState; 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.api.records.YarnApplicationAttemptState; import org.apache.hadoop.yarn.api.records.YarnApplicationState; import org.apache.hadoop.yarn.api.records.timeline.TimelineEntities; import org.apache.hadoop.yarn.api.records.timeline.TimelineEntity; import org.apache.hadoop.yarn.api.records.timeline.TimelineEvent; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.exceptions.ApplicationAttemptNotFoundException; import org.apache.hadoop.yarn.exceptions.ApplicationNotFoundException; import org.apache.hadoop.yarn.exceptions.ContainerNotFoundException; import org.apache.hadoop.yarn.exceptions.YarnException; import org.apache.hadoop.yarn.server.metrics.AppAttemptMetricsConstants; import org.apache.hadoop.yarn.server.metrics.ApplicationMetricsConstants; import org.apache.hadoop.yarn.server.metrics.ContainerMetricsConstants; import org.apache.hadoop.yarn.server.security.ApplicationACLsManager; import org.apache.hadoop.yarn.server.timeline.NameValuePair; import org.apache.hadoop.yarn.server.timeline.TimelineDataManager; import org.apache.hadoop.yarn.server.timeline.TimelineReader.Field; import org.apache.hadoop.yarn.util.ConverterUtils; import org.apache.hadoop.yarn.webapp.util.WebAppUtils; import com.google.common.annotations.VisibleForTesting; public class ApplicationHistoryManagerOnTimelineStore extends AbstractService implements ApplicationHistoryManager { private static final Log LOG = LogFactory.getLog(ApplicationHistoryManagerOnTimelineStore.class); @VisibleForTesting static final String UNAVAILABLE = "N/A"; private TimelineDataManager timelineDataManager; private ApplicationACLsManager aclsManager; private String serverHttpAddress; private long maxLoadedApplications; public ApplicationHistoryManagerOnTimelineStore(TimelineDataManager timelineDataManager, ApplicationACLsManager aclsManager) { super(ApplicationHistoryManagerOnTimelineStore.class.getName()); this.timelineDataManager = timelineDataManager; this.aclsManager = aclsManager; } @Override protected void serviceInit(Configuration conf) throws Exception { serverHttpAddress = WebAppUtils.getHttpSchemePrefix(conf) + WebAppUtils.getAHSWebAppURLWithoutScheme(conf); maxLoadedApplications = conf.getLong(YarnConfiguration.APPLICATION_HISTORY_MAX_APPS, YarnConfiguration.DEFAULT_APPLICATION_HISTORY_MAX_APPS); super.serviceInit(conf); } @Override public ApplicationReport getApplication(ApplicationId appId) throws YarnException, IOException { return getApplication(appId, ApplicationReportField.ALL).appReport; } @Override public Map<ApplicationId, ApplicationReport> getApplications(long appsNum, long appStartedTimeBegin, long appStartedTimeEnd) throws YarnException, IOException { TimelineEntities entities = timelineDataManager.getEntities(ApplicationMetricsConstants.ENTITY_TYPE, null, null, appStartedTimeBegin, appStartedTimeEnd, null, null, appsNum == Long.MAX_VALUE ? this.maxLoadedApplications : appsNum, EnumSet.allOf(Field.class), UserGroupInformation.getLoginUser()); Map<ApplicationId, ApplicationReport> apps = new LinkedHashMap<ApplicationId, ApplicationReport>(); if (entities != null && entities.getEntities() != null) { for (TimelineEntity entity : entities.getEntities()) { try { ApplicationReportExt app = generateApplicationReport(entity, ApplicationReportField.ALL); apps.put(app.appReport.getApplicationId(), app.appReport); } catch (Exception e) { LOG.error("Error on generating application report for " + entity.getEntityId(), e); } } } return apps; } @Override public Map<ApplicationAttemptId, ApplicationAttemptReport> getApplicationAttempts(ApplicationId appId) throws YarnException, IOException { ApplicationReportExt app = getApplication(appId, ApplicationReportField.USER_AND_ACLS); checkAccess(app); TimelineEntities entities = timelineDataManager.getEntities(AppAttemptMetricsConstants.ENTITY_TYPE, new NameValuePair(AppAttemptMetricsConstants.PARENT_PRIMARY_FILTER, appId.toString()), null, null, null, null, null, Long.MAX_VALUE, EnumSet.allOf(Field.class), UserGroupInformation.getLoginUser()); Map<ApplicationAttemptId, ApplicationAttemptReport> appAttempts = new LinkedHashMap<ApplicationAttemptId, ApplicationAttemptReport>(); for (TimelineEntity entity : entities.getEntities()) { ApplicationAttemptReport appAttempt = convertToApplicationAttemptReport(entity); appAttempts.put(appAttempt.getApplicationAttemptId(), appAttempt); } return appAttempts; } @Override public ApplicationAttemptReport getApplicationAttempt(ApplicationAttemptId appAttemptId) throws YarnException, IOException { return getApplicationAttempt(appAttemptId, true); } private ApplicationAttemptReport getApplicationAttempt(ApplicationAttemptId appAttemptId, boolean checkACLs) throws YarnException, IOException { if (checkACLs) { ApplicationReportExt app = getApplication(appAttemptId.getApplicationId(), ApplicationReportField.USER_AND_ACLS); checkAccess(app); } TimelineEntity entity = timelineDataManager.getEntity(AppAttemptMetricsConstants.ENTITY_TYPE, appAttemptId.toString(), EnumSet.allOf(Field.class), UserGroupInformation.getLoginUser()); if (entity == null) { throw new ApplicationAttemptNotFoundException( "The entity for application attempt " + appAttemptId + " doesn't exist in the timeline store"); } else { return convertToApplicationAttemptReport(entity); } } @Override public ContainerReport getContainer(ContainerId containerId) throws YarnException, IOException { ApplicationReportExt app = getApplication(containerId.getApplicationAttemptId().getApplicationId(), ApplicationReportField.USER_AND_ACLS); checkAccess(app); TimelineEntity entity = timelineDataManager.getEntity(ContainerMetricsConstants.ENTITY_TYPE, containerId.toString(), EnumSet.allOf(Field.class), UserGroupInformation.getLoginUser()); if (entity == null) { throw new ContainerNotFoundException( "The entity for container " + containerId + " doesn't exist in the timeline store"); } else { return convertToContainerReport(entity, serverHttpAddress, app.appReport.getUser()); } } @Override public ContainerReport getAMContainer(ApplicationAttemptId appAttemptId) throws YarnException, IOException { ApplicationAttemptReport appAttempt = getApplicationAttempt(appAttemptId, false); return getContainer(appAttempt.getAMContainerId()); } @Override public Map<ContainerId, ContainerReport> getContainers(ApplicationAttemptId appAttemptId) throws YarnException, IOException { ApplicationReportExt app = getApplication(appAttemptId.getApplicationId(), ApplicationReportField.USER_AND_ACLS); checkAccess(app); TimelineEntities entities = timelineDataManager.getEntities(ContainerMetricsConstants.ENTITY_TYPE, new NameValuePair(ContainerMetricsConstants.PARENT_PRIMARIY_FILTER, appAttemptId.toString()), null, null, null, null, null, Long.MAX_VALUE, EnumSet.allOf(Field.class), UserGroupInformation.getLoginUser()); Map<ContainerId, ContainerReport> containers = new LinkedHashMap<ContainerId, ContainerReport>(); if (entities != null && entities.getEntities() != null) { for (TimelineEntity entity : entities.getEntities()) { ContainerReport container = convertToContainerReport(entity, serverHttpAddress, app.appReport.getUser()); containers.put(container.getContainerId(), container); } } return containers; } private static ApplicationReportExt convertToApplicationReport(TimelineEntity entity, ApplicationReportField field) { String user = null; String queue = null; String name = null; String type = null; boolean unmanagedApplication = false; long createdTime = 0; long finishedTime = 0; float progress = 0.0f; int applicationPriority = 0; ApplicationAttemptId latestApplicationAttemptId = null; String diagnosticsInfo = null; FinalApplicationStatus finalStatus = FinalApplicationStatus.UNDEFINED; YarnApplicationState state = YarnApplicationState.ACCEPTED; ApplicationResourceUsageReport appResources = null; Set<String> appTags = null; Map<ApplicationAccessType, String> appViewACLs = new HashMap<ApplicationAccessType, String>(); String appNodeLabelExpression = null; String amNodeLabelExpression = null; Map<String, Object> entityInfo = entity.getOtherInfo(); if (entityInfo != null) { if (entityInfo.containsKey(ApplicationMetricsConstants.USER_ENTITY_INFO)) { user = entityInfo.get(ApplicationMetricsConstants.USER_ENTITY_INFO).toString(); } if (entityInfo.containsKey(ApplicationMetricsConstants.APP_VIEW_ACLS_ENTITY_INFO)) { String appViewACLsStr = entityInfo.get(ApplicationMetricsConstants.APP_VIEW_ACLS_ENTITY_INFO) .toString(); if (appViewACLsStr.length() > 0) { appViewACLs.put(ApplicationAccessType.VIEW_APP, appViewACLsStr); } } if (field == ApplicationReportField.USER_AND_ACLS) { return new ApplicationReportExt(ApplicationReport.newInstance( ApplicationId.fromString(entity.getEntityId()), latestApplicationAttemptId, user, queue, name, null, -1, null, state, diagnosticsInfo, null, createdTime, finishedTime, finalStatus, null, null, progress, type, null, appTags, unmanagedApplication, Priority.newInstance(applicationPriority), appNodeLabelExpression, amNodeLabelExpression), appViewACLs); } if (entityInfo.containsKey(ApplicationMetricsConstants.QUEUE_ENTITY_INFO)) { queue = entityInfo.get(ApplicationMetricsConstants.QUEUE_ENTITY_INFO).toString(); } if (entityInfo.containsKey(ApplicationMetricsConstants.NAME_ENTITY_INFO)) { name = entityInfo.get(ApplicationMetricsConstants.NAME_ENTITY_INFO).toString(); } if (entityInfo.containsKey(ApplicationMetricsConstants.TYPE_ENTITY_INFO)) { type = entityInfo.get(ApplicationMetricsConstants.TYPE_ENTITY_INFO).toString(); } if (entityInfo.containsKey(ApplicationMetricsConstants.TYPE_ENTITY_INFO)) { type = entityInfo.get(ApplicationMetricsConstants.TYPE_ENTITY_INFO).toString(); } if (entityInfo.containsKey(ApplicationMetricsConstants.UNMANAGED_APPLICATION_ENTITY_INFO)) { unmanagedApplication = Boolean.parseBoolean( entityInfo.get(ApplicationMetricsConstants.UNMANAGED_APPLICATION_ENTITY_INFO).toString()); } if (entityInfo.containsKey(ApplicationMetricsConstants.APPLICATION_PRIORITY_INFO)) { applicationPriority = Integer .parseInt(entityInfo.get(ApplicationMetricsConstants.APPLICATION_PRIORITY_INFO).toString()); } if (entityInfo.containsKey(ApplicationMetricsConstants.APP_NODE_LABEL_EXPRESSION)) { appNodeLabelExpression = entityInfo.get(ApplicationMetricsConstants.APP_NODE_LABEL_EXPRESSION) .toString(); } if (entityInfo.containsKey(ApplicationMetricsConstants.AM_NODE_LABEL_EXPRESSION)) { amNodeLabelExpression = entityInfo.get(ApplicationMetricsConstants.AM_NODE_LABEL_EXPRESSION) .toString(); } if (entityInfo.containsKey(ApplicationMetricsConstants.APP_CPU_METRICS)) { long vcoreSeconds = parseLong(entityInfo, ApplicationMetricsConstants.APP_CPU_METRICS); long memorySeconds = parseLong(entityInfo, ApplicationMetricsConstants.APP_MEM_METRICS); long gpuSeconds = Long .parseLong(entityInfo.get(ApplicationMetricsConstants.APP_GPU_METRICS).toString()); long preemptedMemorySeconds = parseLong(entityInfo, ApplicationMetricsConstants.APP_MEM_PREEMPT_METRICS); long preemptedVcoreSeconds = parseLong(entityInfo, ApplicationMetricsConstants.APP_CPU_PREEMPT_METRICS); long preemptedGPUSeconds = parseLong(entityInfo, ApplicationMetricsConstants.APP_GPU_PREEMPT_METRICS); appResources = ApplicationResourceUsageReport.newInstance(0, 0, null, null, null, memorySeconds, vcoreSeconds, gpuSeconds, 0, 0, preemptedMemorySeconds, preemptedVcoreSeconds, preemptedGPUSeconds); } if (entityInfo.containsKey(ApplicationMetricsConstants.APP_TAGS_INFO)) { appTags = new HashSet<String>(); Object obj = entityInfo.get(ApplicationMetricsConstants.APP_TAGS_INFO); if (obj != null && obj instanceof Collection<?>) { for (Object o : (Collection<?>) obj) { if (o != null) { appTags.add(o.toString()); } } } } } List<TimelineEvent> events = entity.getEvents(); long updatedTimeStamp = 0L; if (events != null) { for (TimelineEvent event : events) { if (event.getEventType().equals(ApplicationMetricsConstants.CREATED_EVENT_TYPE)) { createdTime = event.getTimestamp(); } else if (event.getEventType().equals(ApplicationMetricsConstants.UPDATED_EVENT_TYPE)) { // This type of events are parsed in time-stamp descending order // which means the previous event could override the information // from the later same type of event. Hence compare timestamp // before over writing. if (event.getTimestamp() > updatedTimeStamp) { updatedTimeStamp = event.getTimestamp(); } else { continue; } Map<String, Object> eventInfo = event.getEventInfo(); if (eventInfo == null) { continue; } applicationPriority = Integer.parseInt( eventInfo.get(ApplicationMetricsConstants.APPLICATION_PRIORITY_INFO).toString()); queue = eventInfo.get(ApplicationMetricsConstants.QUEUE_ENTITY_INFO).toString(); } else if (event.getEventType().equals(ApplicationMetricsConstants.STATE_UPDATED_EVENT_TYPE)) { Map<String, Object> eventInfo = event.getEventInfo(); if (eventInfo == null) { continue; } if (eventInfo.containsKey(ApplicationMetricsConstants.STATE_EVENT_INFO)) { if (!isFinalState(state)) { state = YarnApplicationState.valueOf( eventInfo.get(ApplicationMetricsConstants.STATE_EVENT_INFO).toString()); } } } else if (event.getEventType().equals(ApplicationMetricsConstants.FINISHED_EVENT_TYPE)) { progress = 1.0F; finishedTime = event.getTimestamp(); Map<String, Object> eventInfo = event.getEventInfo(); if (eventInfo == null) { continue; } if (eventInfo.containsKey(ApplicationMetricsConstants.LATEST_APP_ATTEMPT_EVENT_INFO)) { latestApplicationAttemptId = ApplicationAttemptId.fromString(eventInfo .get(ApplicationMetricsConstants.LATEST_APP_ATTEMPT_EVENT_INFO).toString()); } if (eventInfo.containsKey(ApplicationMetricsConstants.DIAGNOSTICS_INFO_EVENT_INFO)) { diagnosticsInfo = eventInfo.get(ApplicationMetricsConstants.DIAGNOSTICS_INFO_EVENT_INFO) .toString(); } if (eventInfo.containsKey(ApplicationMetricsConstants.FINAL_STATUS_EVENT_INFO)) { finalStatus = FinalApplicationStatus.valueOf( eventInfo.get(ApplicationMetricsConstants.FINAL_STATUS_EVENT_INFO).toString()); } if (eventInfo.containsKey(ApplicationMetricsConstants.STATE_EVENT_INFO)) { state = YarnApplicationState .valueOf(eventInfo.get(ApplicationMetricsConstants.STATE_EVENT_INFO).toString()); } } } } return new ApplicationReportExt(ApplicationReport.newInstance( ApplicationId.fromString(entity.getEntityId()), latestApplicationAttemptId, user, queue, name, null, -1, null, state, diagnosticsInfo, null, createdTime, finishedTime, finalStatus, appResources, null, progress, type, null, appTags, unmanagedApplication, Priority.newInstance(applicationPriority), appNodeLabelExpression, amNodeLabelExpression), appViewACLs); } private static long parseLong(Map<String, Object> entityInfo, String infoKey) { long result = 0; Object infoValue = entityInfo.get(infoKey); if (infoValue != null) { result = Long.parseLong(infoValue.toString()); } return result; } private static boolean isFinalState(YarnApplicationState state) { return state == YarnApplicationState.FINISHED || state == YarnApplicationState.FAILED || state == YarnApplicationState.KILLED; } private static ApplicationAttemptReport convertToApplicationAttemptReport(TimelineEntity entity) { String host = null; int rpcPort = -1; ContainerId amContainerId = null; String trackingUrl = null; String originalTrackingUrl = null; String diagnosticsInfo = null; YarnApplicationAttemptState state = null; List<TimelineEvent> events = entity.getEvents(); if (events != null) { for (TimelineEvent event : events) { if (event.getEventType().equals(AppAttemptMetricsConstants.REGISTERED_EVENT_TYPE)) { Map<String, Object> eventInfo = event.getEventInfo(); if (eventInfo == null) { continue; } if (eventInfo.containsKey(AppAttemptMetricsConstants.HOST_EVENT_INFO)) { host = eventInfo.get(AppAttemptMetricsConstants.HOST_EVENT_INFO).toString(); } if (eventInfo.containsKey(AppAttemptMetricsConstants.RPC_PORT_EVENT_INFO)) { rpcPort = (Integer) eventInfo.get(AppAttemptMetricsConstants.RPC_PORT_EVENT_INFO); } if (eventInfo.containsKey(AppAttemptMetricsConstants.MASTER_CONTAINER_EVENT_INFO)) { amContainerId = ContainerId.fromString( eventInfo.get(AppAttemptMetricsConstants.MASTER_CONTAINER_EVENT_INFO).toString()); } } else if (event.getEventType().equals(AppAttemptMetricsConstants.FINISHED_EVENT_TYPE)) { Map<String, Object> eventInfo = event.getEventInfo(); if (eventInfo == null) { continue; } if (eventInfo.containsKey(AppAttemptMetricsConstants.TRACKING_URL_EVENT_INFO)) { trackingUrl = eventInfo.get(AppAttemptMetricsConstants.TRACKING_URL_EVENT_INFO).toString(); } if (eventInfo.containsKey(AppAttemptMetricsConstants.ORIGINAL_TRACKING_URL_EVENT_INFO)) { originalTrackingUrl = eventInfo .get(AppAttemptMetricsConstants.ORIGINAL_TRACKING_URL_EVENT_INFO).toString(); } if (eventInfo.containsKey(AppAttemptMetricsConstants.DIAGNOSTICS_INFO_EVENT_INFO)) { diagnosticsInfo = eventInfo.get(AppAttemptMetricsConstants.DIAGNOSTICS_INFO_EVENT_INFO) .toString(); } if (eventInfo.containsKey(AppAttemptMetricsConstants.STATE_EVENT_INFO)) { state = YarnApplicationAttemptState .valueOf(eventInfo.get(AppAttemptMetricsConstants.STATE_EVENT_INFO).toString()); } if (eventInfo.containsKey(AppAttemptMetricsConstants.MASTER_CONTAINER_EVENT_INFO)) { amContainerId = ContainerId.fromString( eventInfo.get(AppAttemptMetricsConstants.MASTER_CONTAINER_EVENT_INFO).toString()); } } } } return ApplicationAttemptReport.newInstance(ApplicationAttemptId.fromString(entity.getEntityId()), host, rpcPort, trackingUrl, originalTrackingUrl, diagnosticsInfo, state, amContainerId); } private static ContainerReport convertToContainerReport(TimelineEntity entity, String serverHttpAddress, String user) { int allocatedMem = 0; int allocatedVcore = 0; int allocatedGpu = 0; String allocatedHost = null; int allocatedPort = -1; int allocatedPriority = 0; long createdTime = 0; long finishedTime = 0; String diagnosticsInfo = null; int exitStatus = ContainerExitStatus.INVALID; ContainerState state = null; String nodeHttpAddress = null; Map<String, Object> entityInfo = entity.getOtherInfo(); if (entityInfo != null) { if (entityInfo.containsKey(ContainerMetricsConstants.ALLOCATED_MEMORY_ENTITY_INFO)) { allocatedMem = (Integer) entityInfo.get(ContainerMetricsConstants.ALLOCATED_MEMORY_ENTITY_INFO); } if (entityInfo.containsKey(ContainerMetricsConstants.ALLOCATED_VCORE_ENTITY_INFO)) { allocatedVcore = (Integer) entityInfo.get(ContainerMetricsConstants.ALLOCATED_VCORE_ENTITY_INFO); } if (entityInfo.containsKey(ContainerMetricsConstants.ALLOCATED_GPU_ENTITY_INFO)) { allocatedGpu = (Integer) entityInfo.get(ContainerMetricsConstants.ALLOCATED_GPU_ENTITY_INFO); } if (entityInfo.containsKey(ContainerMetricsConstants.ALLOCATED_HOST_ENTITY_INFO)) { allocatedHost = entityInfo.get(ContainerMetricsConstants.ALLOCATED_HOST_ENTITY_INFO).toString(); } if (entityInfo.containsKey(ContainerMetricsConstants.ALLOCATED_PORT_ENTITY_INFO)) { allocatedPort = (Integer) entityInfo.get(ContainerMetricsConstants.ALLOCATED_PORT_ENTITY_INFO); } if (entityInfo.containsKey(ContainerMetricsConstants.ALLOCATED_PRIORITY_ENTITY_INFO)) { allocatedPriority = (Integer) entityInfo .get(ContainerMetricsConstants.ALLOCATED_PRIORITY_ENTITY_INFO); } if (entityInfo.containsKey(ContainerMetricsConstants.ALLOCATED_HOST_HTTP_ADDRESS_ENTITY_INFO)) { nodeHttpAddress = (String) entityInfo .get(ContainerMetricsConstants.ALLOCATED_HOST_HTTP_ADDRESS_ENTITY_INFO); } } List<TimelineEvent> events = entity.getEvents(); if (events != null) { for (TimelineEvent event : events) { if (event.getEventType().equals(ContainerMetricsConstants.CREATED_EVENT_TYPE)) { createdTime = event.getTimestamp(); } else if (event.getEventType().equals(ContainerMetricsConstants.FINISHED_EVENT_TYPE)) { finishedTime = event.getTimestamp(); Map<String, Object> eventInfo = event.getEventInfo(); if (eventInfo == null) { continue; } if (eventInfo.containsKey(ContainerMetricsConstants.DIAGNOSTICS_INFO_EVENT_INFO)) { diagnosticsInfo = eventInfo.get(ContainerMetricsConstants.DIAGNOSTICS_INFO_EVENT_INFO) .toString(); } if (eventInfo.containsKey(ContainerMetricsConstants.EXIT_STATUS_EVENT_INFO)) { exitStatus = (Integer) eventInfo.get(ContainerMetricsConstants.EXIT_STATUS_EVENT_INFO); } if (eventInfo.containsKey(ContainerMetricsConstants.STATE_EVENT_INFO)) { state = ContainerState .valueOf(eventInfo.get(ContainerMetricsConstants.STATE_EVENT_INFO).toString()); } } } } ContainerId containerId = ContainerId.fromString(entity.getEntityId()); String logUrl = null; NodeId allocatedNode = null; if (allocatedHost != null) { allocatedNode = NodeId.newInstance(allocatedHost, allocatedPort); logUrl = WebAppUtils.getAggregatedLogURL(serverHttpAddress, allocatedNode.toString(), containerId.toString(), containerId.toString(), user); } return ContainerReport.newInstance(ContainerId.fromString(entity.getEntityId()), Resource.newInstance(allocatedMem, allocatedVcore, allocatedGpu), allocatedNode, Priority.newInstance(allocatedPriority), createdTime, finishedTime, diagnosticsInfo, logUrl, exitStatus, state, nodeHttpAddress); } private ApplicationReportExt generateApplicationReport(TimelineEntity entity, ApplicationReportField field) throws YarnException, IOException { ApplicationReportExt app = convertToApplicationReport(entity, field); // If only user and acls are pulled to check attempt(s)/container(s) access // control, we can return immediately if (field == ApplicationReportField.USER_AND_ACLS) { return app; } try { checkAccess(app); if (app.appReport.getCurrentApplicationAttemptId() != null) { ApplicationAttemptReport appAttempt = getApplicationAttempt( app.appReport.getCurrentApplicationAttemptId(), false); app.appReport.setHost(appAttempt.getHost()); app.appReport.setRpcPort(appAttempt.getRpcPort()); app.appReport.setTrackingUrl(appAttempt.getTrackingUrl()); app.appReport.setOriginalTrackingUrl(appAttempt.getOriginalTrackingUrl()); } } catch (AuthorizationException | ApplicationAttemptNotFoundException e) { // AuthorizationException is thrown because the user doesn't have access if (e instanceof AuthorizationException) { LOG.warn("Failed to authorize when generating application report for " + app.appReport.getApplicationId() + ". Use a placeholder for its latest attempt id. ", e); } else { // Attempt not found LOG.info("No application attempt found for " + app.appReport.getApplicationId() + ". Use a placeholder for its latest attempt id. ", e); } // It's possible that the app is finished before the first attempt is created. app.appReport.setDiagnostics(null); app.appReport.setCurrentApplicationAttemptId(null); } if (app.appReport.getCurrentApplicationAttemptId() == null) { app.appReport.setCurrentApplicationAttemptId( ApplicationAttemptId.newInstance(app.appReport.getApplicationId(), -1)); } if (app.appReport.getHost() == null) { app.appReport.setHost(UNAVAILABLE); } if (app.appReport.getRpcPort() < 0) { app.appReport.setRpcPort(-1); } if (app.appReport.getTrackingUrl() == null) { app.appReport.setTrackingUrl(UNAVAILABLE); } if (app.appReport.getOriginalTrackingUrl() == null) { app.appReport.setOriginalTrackingUrl(UNAVAILABLE); } if (app.appReport.getDiagnostics() == null) { app.appReport.setDiagnostics(""); } return app; } private ApplicationReportExt getApplication(ApplicationId appId, ApplicationReportField field) throws YarnException, IOException { TimelineEntity entity = timelineDataManager.getEntity(ApplicationMetricsConstants.ENTITY_TYPE, appId.toString(), EnumSet.allOf(Field.class), UserGroupInformation.getLoginUser()); if (entity == null) { throw new ApplicationNotFoundException( "The entity for application " + appId + " doesn't exist in the timeline store"); } else { return generateApplicationReport(entity, field); } } private void checkAccess(ApplicationReportExt app) throws YarnException, IOException { if (app.appViewACLs != null) { aclsManager.addApplication(app.appReport.getApplicationId(), app.appViewACLs); try { if (!aclsManager.checkAccess(UserGroupInformation.getCurrentUser(), ApplicationAccessType.VIEW_APP, app.appReport.getUser(), app.appReport.getApplicationId())) { throw new AuthorizationException( "User " + UserGroupInformation.getCurrentUser().getShortUserName() + " does not have privilage to see this application " + app.appReport.getApplicationId()); } } finally { aclsManager.removeApplication(app.appReport.getApplicationId()); } } } private static enum ApplicationReportField { ALL, // retrieve all the fields USER_AND_ACLS // retrieve user and ACLs info only } private static class ApplicationReportExt { private ApplicationReport appReport; private Map<ApplicationAccessType, String> appViewACLs; public ApplicationReportExt(ApplicationReport appReport, Map<ApplicationAccessType, String> appViewACLs) { this.appReport = appReport; this.appViewACLs = appViewACLs; } } }