| /** |
| * 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.mapreduce.v2.app.webapp.dao; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.xml.bind.annotation.XmlAccessType; |
| import javax.xml.bind.annotation.XmlAccessorType; |
| import javax.xml.bind.annotation.XmlRootElement; |
| import javax.xml.bind.annotation.XmlTransient; |
| |
| import org.apache.hadoop.mapreduce.JobACL; |
| import org.apache.hadoop.mapreduce.v2.api.records.JobReport; |
| import org.apache.hadoop.mapreduce.v2.api.records.JobState; |
| import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId; |
| import org.apache.hadoop.mapreduce.v2.api.records.TaskId; |
| import org.apache.hadoop.mapreduce.v2.app.job.Job; |
| import org.apache.hadoop.mapreduce.v2.app.job.Task; |
| import org.apache.hadoop.mapreduce.v2.app.job.TaskAttempt; |
| import org.apache.hadoop.mapreduce.v2.util.MRApps; |
| import org.apache.hadoop.mapreduce.v2.util.MRApps.TaskAttemptStateUI; |
| import org.apache.hadoop.security.authorize.AccessControlList; |
| import org.apache.hadoop.util.StringUtils; |
| import org.apache.hadoop.yarn.util.Times; |
| |
| @XmlRootElement(name = "job") |
| @XmlAccessorType(XmlAccessType.FIELD) |
| public class JobInfo { |
| |
| // ok for any user to see |
| protected long startTime; |
| protected long finishTime; |
| protected long elapsedTime; |
| protected String id; |
| protected String name; |
| protected String user; |
| protected String queue; |
| protected JobState state; |
| protected int mapsTotal; |
| protected int mapsCompleted; |
| protected int reducesTotal; |
| protected int reducesCompleted; |
| protected float mapProgress; |
| protected float reduceProgress; |
| |
| @XmlTransient |
| protected String mapProgressPercent; |
| @XmlTransient |
| protected String reduceProgressPercent; |
| |
| // these should only be seen if acls allow |
| protected int mapsPending; |
| protected int mapsRunning; |
| protected int reducesPending; |
| protected int reducesRunning; |
| protected boolean uberized; |
| protected String diagnostics; |
| protected int newReduceAttempts = 0; |
| protected int runningReduceAttempts = 0; |
| protected int failedReduceAttempts = 0; |
| protected int killedReduceAttempts = 0; |
| protected int successfulReduceAttempts = 0; |
| protected int newMapAttempts = 0; |
| protected int runningMapAttempts = 0; |
| protected int failedMapAttempts = 0; |
| protected int killedMapAttempts = 0; |
| protected int successfulMapAttempts = 0; |
| protected ArrayList<ConfEntryInfo> acls; |
| |
| public JobInfo() { |
| } |
| |
| public JobInfo(Job job, Boolean hasAccess) { |
| this.id = MRApps.toString(job.getID()); |
| JobReport report = job.getReport(); |
| this.startTime = report.getStartTime(); |
| this.finishTime = report.getFinishTime(); |
| this.elapsedTime = Times.elapsed(this.startTime, this.finishTime); |
| if (this.elapsedTime == -1) { |
| this.elapsedTime = 0; |
| } |
| this.name = job.getName().toString(); |
| this.user = job.getUserName(); |
| this.queue = job.getQueueName(); |
| this.state = job.getState(); |
| this.mapsTotal = job.getTotalMaps(); |
| this.mapsCompleted = job.getCompletedMaps(); |
| this.mapProgress = report.getMapProgress() * 100; |
| this.mapProgressPercent = |
| StringUtils.format("%.2f", getMapProgress()); |
| this.reducesTotal = job.getTotalReduces(); |
| this.reducesCompleted = job.getCompletedReduces(); |
| this.reduceProgress = report.getReduceProgress() * 100; |
| this.reduceProgressPercent = |
| StringUtils.format("%.2f", getReduceProgress()); |
| |
| this.acls = new ArrayList<ConfEntryInfo>(); |
| if (hasAccess) { |
| this.diagnostics = ""; |
| countTasksAndAttempts(job); |
| |
| this.uberized = job.isUber(); |
| |
| List<String> diagnostics = job.getDiagnostics(); |
| if (diagnostics != null && !diagnostics.isEmpty()) { |
| StringBuffer b = new StringBuffer(); |
| for (String diag : diagnostics) { |
| b.append(diag); |
| } |
| this.diagnostics = b.toString(); |
| } |
| |
| Map<JobACL, AccessControlList> allacls = job.getJobACLs(); |
| if (allacls != null) { |
| for (Map.Entry<JobACL, AccessControlList> entry : allacls.entrySet()) { |
| this.acls.add(new ConfEntryInfo(entry.getKey().getAclName(), entry |
| .getValue().getAclString())); |
| } |
| } |
| } |
| } |
| |
| public int getNewReduceAttempts() { |
| return this.newReduceAttempts; |
| } |
| |
| public int getKilledReduceAttempts() { |
| return this.killedReduceAttempts; |
| } |
| |
| public int getFailedReduceAttempts() { |
| return this.failedReduceAttempts; |
| } |
| |
| public int getRunningReduceAttempts() { |
| return this.runningReduceAttempts; |
| } |
| |
| public int getSuccessfulReduceAttempts() { |
| return this.successfulReduceAttempts; |
| } |
| |
| public int getNewMapAttempts() { |
| return this.newMapAttempts; |
| } |
| |
| public int getKilledMapAttempts() { |
| return this.killedMapAttempts; |
| } |
| |
| public ArrayList<ConfEntryInfo> getAcls() { |
| return acls; |
| } |
| |
| public int getFailedMapAttempts() { |
| return this.failedMapAttempts; |
| } |
| |
| public int getRunningMapAttempts() { |
| return this.runningMapAttempts; |
| } |
| |
| public int getSuccessfulMapAttempts() { |
| return this.successfulMapAttempts; |
| } |
| |
| public int getReducesCompleted() { |
| return this.reducesCompleted; |
| } |
| |
| public int getReducesTotal() { |
| return this.reducesTotal; |
| } |
| |
| public int getReducesPending() { |
| return this.reducesPending; |
| } |
| |
| public int getReducesRunning() { |
| return this.reducesRunning; |
| } |
| |
| public int getMapsCompleted() { |
| return this.mapsCompleted; |
| } |
| |
| public int getMapsTotal() { |
| return this.mapsTotal; |
| } |
| |
| public int getMapsPending() { |
| return this.mapsPending; |
| } |
| |
| public int getMapsRunning() { |
| return this.mapsRunning; |
| } |
| |
| public String getState() { |
| return this.state.toString(); |
| } |
| |
| public String getUserName() { |
| return this.user; |
| } |
| |
| public String getName() { |
| return this.name; |
| } |
| |
| public String getQueueName() { |
| return this.queue; |
| } |
| |
| public String getId() { |
| return this.id; |
| } |
| |
| public long getStartTime() { |
| return this.startTime; |
| } |
| |
| public long getElapsedTime() { |
| return this.elapsedTime; |
| } |
| |
| public long getFinishTime() { |
| return this.finishTime; |
| } |
| |
| public boolean isUberized() { |
| return this.uberized; |
| } |
| |
| public String getdiagnostics() { |
| return this.diagnostics; |
| } |
| |
| public float getMapProgress() { |
| return this.mapProgress; |
| } |
| |
| public String getMapProgressPercent() { |
| return this.mapProgressPercent; |
| } |
| |
| public float getReduceProgress() { |
| return this.reduceProgress; |
| } |
| |
| public String getReduceProgressPercent() { |
| return this.reduceProgressPercent; |
| } |
| |
| /** |
| * Go through a job and update the member variables with counts for |
| * information to output in the page. |
| * |
| * @param job |
| * the job to get counts for. |
| */ |
| private void countTasksAndAttempts(Job job) { |
| final Map<TaskId, Task> tasks = job.getTasks(); |
| if (tasks == null) { |
| return; |
| } |
| for (Task task : tasks.values()) { |
| switch (task.getType()) { |
| case MAP: |
| // Task counts |
| switch (task.getState()) { |
| case RUNNING: |
| ++this.mapsRunning; |
| break; |
| case SCHEDULED: |
| ++this.mapsPending; |
| break; |
| default: |
| break; |
| } |
| break; |
| case REDUCE: |
| // Task counts |
| switch (task.getState()) { |
| case RUNNING: |
| ++this.reducesRunning; |
| break; |
| case SCHEDULED: |
| ++this.reducesPending; |
| break; |
| default: |
| break; |
| } |
| break; |
| default: |
| throw new IllegalStateException( |
| "Task type is neither map nor reduce: " + task.getType()); |
| } |
| // Attempts counts |
| Map<TaskAttemptId, TaskAttempt> attempts = task.getAttempts(); |
| int newAttempts, running, successful, failed, killed; |
| for (TaskAttempt attempt : attempts.values()) { |
| |
| newAttempts = 0; |
| running = 0; |
| successful = 0; |
| failed = 0; |
| killed = 0; |
| if (TaskAttemptStateUI.NEW.correspondsTo(attempt.getState())) { |
| ++newAttempts; |
| } else if (TaskAttemptStateUI.RUNNING.correspondsTo(attempt.getState())) { |
| ++running; |
| } else if (TaskAttemptStateUI.SUCCESSFUL.correspondsTo(attempt |
| .getState())) { |
| ++successful; |
| } else if (TaskAttemptStateUI.FAILED.correspondsTo(attempt.getState())) { |
| ++failed; |
| } else if (TaskAttemptStateUI.KILLED.correspondsTo(attempt.getState())) { |
| ++killed; |
| } |
| |
| switch (task.getType()) { |
| case MAP: |
| this.newMapAttempts += newAttempts; |
| this.runningMapAttempts += running; |
| this.successfulMapAttempts += successful; |
| this.failedMapAttempts += failed; |
| this.killedMapAttempts += killed; |
| break; |
| case REDUCE: |
| this.newReduceAttempts += newAttempts; |
| this.runningReduceAttempts += running; |
| this.successfulReduceAttempts += successful; |
| this.failedReduceAttempts += failed; |
| this.killedReduceAttempts += killed; |
| break; |
| default: |
| throw new IllegalStateException("Task type neither map nor reduce: " + |
| task.getType()); |
| } |
| } |
| } |
| } |
| |
| } |