diff --git a/hadoop-mapreduce-project/CHANGES.txt b/hadoop-mapreduce-project/CHANGES.txt index 7e57804be1f..dfac02886b0 100644 --- a/hadoop-mapreduce-project/CHANGES.txt +++ b/hadoop-mapreduce-project/CHANGES.txt @@ -483,6 +483,9 @@ Release 2.8.0 - UNRELEASED MAPREDUCE-6373. The logger reports total input paths but it is referring to input files. (Bibin A Chundatt via devaraj) + MAPREDUCE-6405. NullPointerException in App Attempts page. + (Siqi Li and Gera Shegalov via devaraj) + Release 2.7.1 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TaskPage.java b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TaskPage.java index 758b02c0220..d9f17c8ade9 100644 --- a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TaskPage.java +++ b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TaskPage.java @@ -24,11 +24,14 @@ import static org.apache.hadoop.yarn.webapp.view.JQueryUI.DATATABLES_ID; import static org.apache.hadoop.yarn.webapp.view.JQueryUI.initID; import static org.apache.hadoop.yarn.webapp.view.JQueryUI.tableInit; +import java.util.EnumSet; import java.util.Collection; import org.apache.commons.lang.StringEscapeUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.mapreduce.MRConfig; +import org.apache.hadoop.mapreduce.v2.api.records.JobId; +import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptState; import org.apache.hadoop.mapreduce.v2.app.job.TaskAttempt; import org.apache.hadoop.mapreduce.v2.app.webapp.dao.TaskAttemptInfo; import org.apache.hadoop.mapreduce.v2.util.MRWebAppUtil; @@ -48,7 +51,6 @@ public class TaskPage extends AppView { static class AttemptsBlock extends HtmlBlock { final App app; final boolean enableUIActions; - private String stateURLFormat; @Inject AttemptsBlock(App ctx, Configuration conf) { @@ -66,37 +68,36 @@ public class TaskPage extends AppView { return; } + JobId jobId = app.getJob().getID(); if (enableUIActions) { // Kill task attempt - String appID = app.getJob().getID().getAppId().toString(); - String jobID = app.getJob().getID().toString(); - String taskID = app.getTask().getID().toString(); - stateURLFormat = - String.format("/proxy/%s/ws/v1/mapreduce/jobs/%s/tasks/%s/" - + "attempts", appID, jobID, taskID) + "/%s/state"; - - String current = - String.format("/proxy/%s/mapreduce/task/%s", appID, taskID); StringBuilder script = new StringBuilder(); - script.append("function confirmAction(stateURL) {") - .append(" b = confirm(\"Are you sure?\");") - .append(" if (b == true) {") - .append(" $.ajax({") - .append(" type: 'PUT',") - .append(" url: stateURL,") - .append(" contentType: 'application/json',") - .append(" data: '{\"state\":\"KILLED\"}',") - .append(" dataType: 'json'") - .append(" }).done(function(data){") - .append(" setTimeout(function(){") - .append(" location.href = '").append(current).append("';") - .append(" }, 1000);") - .append(" }).fail(function(data){") - .append(" console.log(data);") - .append(" });") - .append(" }") - .append("}"); + script + .append("function confirmAction(appID, jobID, taskID, attID) {\n") + .append(" var b = confirm(\"Are you sure?\");\n") + .append(" if (b == true) {\n") + .append(" var current = '/proxy/' + appID") + .append(" + '/mapreduce/task/' + taskID;\n") + .append(" var stateURL = '/proxy/' + appID") + .append(" + '/ws/v1/mapreduce/jobs/' + jobID") + .append(" + '/tasks/' + taskID") + .append(" + '/attempts/' + attID + '/state';\n") + .append(" $.ajax({\n") + .append(" type: 'PUT',\n") + .append(" url: stateURL,\n") + .append(" contentType: 'application/json',\n") + .append(" data: '{\"state\":\"KILLED\"}',\n") + .append(" dataType: 'json'\n") + .append(" }).done(function(data) {\n") + .append(" setTimeout(function() {\n") + .append(" location.href = current;\n") + .append(" }, 1000);\n") + .append(" }).fail(function(data) {\n") + .append(" console.log(data);\n") + .append(" });\n") + .append(" }\n") + .append("}\n"); html.script().$type("text/javascript")._(script.toString())._(); } @@ -135,8 +136,8 @@ public class TaskPage extends AppView { StringEscapeUtils.escapeHtml(ta.getStatus()))).append("\",\"") .append(nodeHttpAddr == null ? "N/A" : - "" - + nodeHttpAddr + "") + "" + + nodeHttpAddr + "") .append("\",\"") .append(ta.getAssignedContainerId() == null ? "N/A" : @@ -151,12 +152,21 @@ public class TaskPage extends AppView { .append(StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml( diag))); if (enableUIActions) { - attemptsTableData.append("\",\"") - .append("Kill") - .append("\"],\n"); - } else { + attemptsTableData.append("\",\""); + if (EnumSet.of( + TaskAttemptState.SUCCEEDED, + TaskAttemptState.FAILED, + TaskAttemptState.KILLED).contains(attempt.getState())) { + attemptsTableData.append("N/A"); + } else { + attemptsTableData + .append("Kill"); + } attemptsTableData.append("\"],\n"); } }