azkaban-aplcache

Details

diff --git a/src/java/azkaban/webapp/servlet/velocity/jobdetailspage.vm b/src/java/azkaban/webapp/servlet/velocity/jobdetailspage.vm
index 335f24c..f551245 100644
--- a/src/java/azkaban/webapp/servlet/velocity/jobdetailspage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/jobdetailspage.vm
@@ -84,6 +84,11 @@
             </div>
           </h3>
 
+          <div id="jobType">
+            <table id="jobTypeTable" class="table table-striped table-bordered table-hover">
+            </table>
+          </div>
+
           <div id="command-summary">
             <h4>Command Summary</h4>
             <table id="commandTable" class="table table-striped table-bordered table-hover">
@@ -121,6 +126,13 @@
               </tbody>
             </table>
           </div>
+
+          <div id="jobIds">
+            <h4>Map Reduce Jobs</h4>
+            <table class="table table-striped table-bordered table-hover">
+              <tbody id="jobIdsTableBody"></tbody>
+            </table>
+          </div>
         </div>
       </div>
     </div>
diff --git a/src/web/js/azkaban/model/log-data.js b/src/web/js/azkaban/model/log-data.js
index 2fe3ac5..90a958f 100644
--- a/src/web/js/azkaban/model/log-data.js
+++ b/src/web/js/azkaban/model/log-data.js
@@ -24,6 +24,8 @@ azkaban.LogDataModel = Backbone.Model.extend({
     HIVE_MAP_REDUCE_JOBS_SUMMARY: "MapReduce Jobs Launched:",
     HIVE_MAP_REDUCE_SUMMARY_REGEX: /Job (\d+):\s+Map: (\d+)\s+Reduce: (\d+)\s+(?:Cumulative CPU: (.+?))?\s+HDFS Read: (\d+)\s+HDFS Write: (\d+)/,
 
+    JOB_ID_REGEX: /job_\d{12}_\d{4,}/,
+
     initialize: function() {
         this.set("offset", 0 );
         this.set("logData", "");
@@ -91,14 +93,19 @@ azkaban.LogDataModel = Backbone.Model.extend({
         var lines = data.split("\n");
 
         if (this.parseCommand(lines)) {
+            this.parseJobType(lines);
             this.parseJobTrackerUrls(lines);
 
-            var jobType = this.parseJobType(lines);
-            if (jobType.indexOf("pig") !== -1) {
-                this.parsePigTable(lines, "pigSummary", this.PIG_JOB_SUMMARY_START, "", 0);
-                this.parsePigTable(lines, "pigStats", this.PIG_JOB_STATS_START, "", 1);
-            } else if (jobType.indexOf("hive") !== -1) {
-                this.parseHiveQueries(lines);
+            var jobType = this.get("jobType");
+            if (jobType) {
+                if (jobType.indexOf("pig") !== -1) {
+                    this.parsePigTable(lines, "pigSummary", this.PIG_JOB_SUMMARY_START, "", 0);
+                    this.parsePigTable(lines, "pigStats", this.PIG_JOB_STATS_START, "", 1);
+                } else if (jobType.indexOf("hive") !== -1) {
+                    this.parseHiveQueries(lines);
+                } else {
+                    this.parseJobIds(lines);
+                }
             }
         }
     },
@@ -163,16 +170,32 @@ azkaban.LogDataModel = Backbone.Model.extend({
         this.set("jobTrackerUrlsOrdered", jobTrackerUrlsOrdered);
     },
 
+    parseJobIds: function(lines) {
+        var seenJobIds = {};
+        var jobIds = [];
+        var numLines = lines.length;
+        var match;
+        for (var i = 0; i < numLines; i++) {
+            if ((match = this.JOB_ID_REGEX.exec(lines[i])) && !seenJobIds[match[0]]) {
+                seenJobIds[match[0]] = true;
+                jobIds.push(match[0]);
+            }
+        }
+
+        if (jobIds.length > 0) {
+            this.set("jobIds", jobIds);
+        }
+    },
+
     parseJobType: function(lines) {
         var numLines = lines.length;
         var match;
-        for (var i = 0; numLines; i++) {
+        for (var i = 0; i < numLines; i++) {
             if (match = this.JOB_TYPE_REGEX.exec(lines[i])) {
-                return match[1];
+                this.set("jobType", match[1]);
+                break;
             }
         }
-        
-        return null;
     },
 
     parsePigTable: function(lines, tableName, startPattern, endPattern, linesToSkipAfterStart) {
@@ -262,14 +285,12 @@ azkaban.LogDataModel = Backbone.Model.extend({
                                     job.push("<a href='" + this.get("jobTrackerUrlsOrdered")[currMapReduceJob++] + "'>" + currJob + "</a>");
                                     job.push(match[2]);
                                     job.push(match[3]);
-                                    job.push(match[4]);
-                                    job.push(match[5]);
-                                    job.push(match[6]);
-
-                                    if (match[7]) {
+                                    if (match[4]) {
                                         this.set("hasCumulativeCPU", true);
-                                        job.push(match[7]);
+                                        job.push(match[4]);
                                     }
+                                    job.push(match[5]);
+                                    job.push(match[6]);
 
                                     queryJobs.push(job);
                                     previousJob = currJob;
diff --git a/src/web/js/azkaban/view/job-details.js b/src/web/js/azkaban/view/job-details.js
index ab77045..07b823e 100644
--- a/src/web/js/azkaban/view/job-details.js
+++ b/src/web/js/azkaban/view/job-details.js
@@ -45,15 +45,19 @@ azkaban.JobSummaryView = Backbone.View.extend({
 	},
 
 	initialize: function(settings) {
+		$("#jobType").hide();
 		$("#commandSummary").hide();
 		$("#pigJobSummary").hide();
 		$("#pigJobStats").hide();
 		$("#hiveJobSummary").hide();
+		$("#jobIds").hide();
 
+		this.listenTo(this.model, "change:jobType", this.renderJobTypeTable);
 		this.listenTo(this.model, "change:commandProperties", this.renderCommandTable);
 		this.listenTo(this.model, "change:pigSummary", this.renderPigSummaryTable);
 		this.listenTo(this.model, "change:pigStats", this.renderPigStatsTable);
 		this.listenTo(this.model, "change:hiveSummary", this.renderHiveTable);
+		this.listenTo(this.model, "change:jobIds", this.renderJobIdsTable);
 	},
 
 	refresh: function() {
@@ -65,6 +69,46 @@ azkaban.JobSummaryView = Backbone.View.extend({
 		renderJobTable(jobSummary.statTableHeaders, jobSummary.statTableData, "stats");
 		renderHiveTable(jobSummary.hiveQueries, jobSummary.hiveQueryJobs);
 	},
+
+	renderJobTypeTable: function() {
+		var jobTypeTable = $("#jobTypeTable");
+		var jobType = this.model.get("jobType");
+
+		var tr = document.createElement("tr");
+		var td = document.createElement("td");
+		$(td).html("<b>Job Type</b>");
+		$(tr).append(td);
+		td = document.createElement("td");
+		$(td).html(jobType);
+		$(tr).append(td);
+
+		jobTypeTable.append(tr);
+
+		$("#jobType").show();
+	},
+
+	renderJobIdsTable: function() {
+		var oldBody = $("#jobIdsTableBody");
+		var newBody = $(document.createElement("tbody")).attr("id", "jobIdsTableBody");
+
+		var jobIds = this.model.get("jobIds");
+		var jobUrls = this.model.get("jobTrackerUrls");
+		var numJobs = jobIds.length;
+		for (var i = 0; i < numJobs; i++) {
+			var job = jobIds[i];
+			var tr = document.createElement("tr");
+			var td = document.createElement("td");
+			var html = jobUrls[job] ? "<a href='" + jobUrls[job] + "'>" + job + "</a>" : job;
+			$(td).html(html);
+			$(tr).append(td);
+			newBody.append(tr);
+		}
+
+		oldBody.replaceWith(newBody);
+
+		$("#jobIds").show();
+	},
+
 	renderCommandTable: function() {
 		var commandTable = $("#commandTable");
 		var commandProperties = this.model.get("commandProperties");