diff --git a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java
index 6a6d101..6008397 100644
--- a/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java
+++ b/azkaban-web-server/src/main/java/azkaban/webapp/servlet/ProjectManagerServlet.java
@@ -74,6 +74,7 @@ import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
@@ -1151,6 +1152,22 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
final Page page =
newPage(req, resp, session,
"azkaban/webapp/servlet/velocity/jobhistorypage.vm");
+
+ final String jobId = getParam(req, "job");
+ page.add("jobId", jobId);
+
+ int pageNum = Math.max(1, getIntParam(req, "page", 1));
+ page.add("page", pageNum);
+
+ final int pageSize = Math.max(1, getIntParam(req, "size", 25));
+ page.add("pageSize", pageSize);
+
+ page.add("recordCount", 0);
+ page.add("projectId", "");
+ page.add("projectName", "");
+ page.add("dataSeries", "[]");
+ page.add("history", null);
+
final String projectName = getParam(req, "project");
final User user = session.getUser();
@@ -1166,88 +1183,36 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
return;
}
- final String jobId = getParam(req, "job");
- final int pageNum = getIntParam(req, "page", 1);
- final int pageSize = getIntParam(req, "size", 25);
-
page.add("projectId", project.getId());
page.add("projectName", project.getName());
- page.add("jobid", jobId);
- page.add("page", pageNum);
-
- final int skipPage = (pageNum - 1) * pageSize;
- int numResults = 0;
try {
- numResults = this.executorManagerAdapter.getNumberOfJobExecutions(project, jobId);
- final int maxPage = (numResults / pageSize) + 1;
- List<ExecutableJobInfo> jobInfo =
- this.executorManagerAdapter.getExecutableJobs(project, jobId, skipPage, pageSize);
+ final int numResults = this.executorManagerAdapter.getNumberOfJobExecutions(project, jobId);
+ page.add("recordCount", numResults);
- if (jobInfo == null || jobInfo.isEmpty()) {
- jobInfo = null;
+ final int totalPages = ((numResults - 1) / pageSize) + 1;
+ if (pageNum > totalPages) {
+ pageNum = totalPages;
+ page.add("page", pageNum);
}
- page.add("history", jobInfo);
+ final int elementsToSkip = (pageNum - 1) * pageSize;
+ final List<ExecutableJobInfo> jobInfo =
+ this.executorManagerAdapter.getExecutableJobs(project, jobId, elementsToSkip, pageSize);
- page.add("previous", new PageSelection("Previous", pageSize, true, false,
- Math.max(pageNum - 1, 1)));
+ if (CollectionUtils.isNotEmpty(jobInfo)) {
+ page.add("history", jobInfo);
- page.add(
- "next",
- new PageSelection("Next", pageSize, false, false, Math.min(
- pageNum + 1, maxPage)));
-
- if (jobInfo != null) {
final ArrayList<Object> dataSeries = new ArrayList<>();
for (final ExecutableJobInfo info : jobInfo) {
final Map<String, Object> map = info.toObject();
dataSeries.add(map);
}
page.add("dataSeries", JSONUtils.toJSON(dataSeries));
- } else {
- page.add("dataSeries", "[]");
}
} catch (final ExecutorManagerException e) {
page.add("errorMsg", e.getMessage());
}
- // Now for the 5 other values.
- int pageStartValue = 1;
- if (pageNum > 3) {
- pageStartValue = pageNum - 2;
- }
- final int maxPage = (numResults / pageSize) + 1;
-
- page.add(
- "page1",
- new PageSelection(String.valueOf(pageStartValue), pageSize,
- pageStartValue > maxPage, pageStartValue == pageNum, Math.min(
- pageStartValue, maxPage)));
- pageStartValue++;
- page.add(
- "page2",
- new PageSelection(String.valueOf(pageStartValue), pageSize,
- pageStartValue > maxPage, pageStartValue == pageNum, Math.min(
- pageStartValue, maxPage)));
- pageStartValue++;
- page.add(
- "page3",
- new PageSelection(String.valueOf(pageStartValue), pageSize,
- pageStartValue > maxPage, pageStartValue == pageNum, Math.min(
- pageStartValue, maxPage)));
- pageStartValue++;
- page.add(
- "page4",
- new PageSelection(String.valueOf(pageStartValue), pageSize,
- pageStartValue > maxPage, pageStartValue == pageNum, Math.min(
- pageStartValue, maxPage)));
- pageStartValue++;
- page.add(
- "page5",
- new PageSelection(String.valueOf(pageStartValue), pageSize,
- pageStartValue > maxPage, pageStartValue == pageNum, Math.min(
- pageStartValue, maxPage)));
-
page.render();
}
@@ -1657,7 +1622,8 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
status = "error";
}
}
- final String response = createJsonResponse(status, message, action, params);
+ final String response = AbstractAzkabanServlet
+ .createJsonResponse(status, message, action, params);
try {
final Writer write = resp.getWriter();
write.append(response);
@@ -1679,7 +1645,7 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
final User user = session.getUser();
final String projectName = (String) multipart.get("project");
final Project project = this.projectManager.getProject(projectName);
- if(project == null || !project.isActive()) {
+ if (project == null || !project.isActive()) {
final String failureCause = project == null ? "doesn't exist." : "was already removed.";
registerError(ret, "Installation Failed. Project '" + projectName + " "
+ failureCause, resp, 410);
diff --git a/azkaban-web-server/src/main/resources/azkaban/webapp/servlet/velocity/jobhistorypage.vm b/azkaban-web-server/src/main/resources/azkaban/webapp/servlet/velocity/jobhistorypage.vm
index e3d1d62..f25fd9f 100644
--- a/azkaban-web-server/src/main/resources/azkaban/webapp/servlet/velocity/jobhistorypage.vm
+++ b/azkaban-web-server/src/main/resources/azkaban/webapp/servlet/velocity/jobhistorypage.vm
@@ -23,6 +23,7 @@
<script type="text/javascript" src="${context}/js/raphael.min.js"></script>
<script type="text/javascript" src="${context}/js/morris.min.js"></script>
+ <script type="text/javascript" src="${context}/js/jquery.twbsPagination.min.js"></script>
<script type="text/javascript" src="${context}/js/azkaban/util/date.js"></script>
<script type="text/javascript" src="${context}/js/azkaban/view/time-graph.js"></script>
<script type="text/javascript" src="${context}/js/azkaban/view/job-history.js"></script>
@@ -35,8 +36,23 @@
var projectId = "$projectId";
var projectName = "$projectName";
- var jobName = "$jobid";
+ var jobName = "$jobId";
var dataSeries = $dataSeries;
+
+ var jobHistoryPageSettings = {
+ projectName: "${projectName}",
+ jobId: "${jobId}",
+ dataSeries: ${dataSeries},
+ page: ${page},
+ pageSize: ${pageSize},
+ visiblePages: 5,
+ recordCount: ${recordCount},
+ fetchJobHistoryUrl: contextURL + "/manager"
+ };
+
+ $(function () {
+ initJobHistoryPage(jobHistoryPageSettings);
+ });
</script>
<link rel="stylesheet" type="text/css" href="${context}/css/morris.css"/>
</head>
@@ -53,8 +69,8 @@
<div class="az-page-header page-header-bare">
<div class="container-full">
- <h1><a href="${context}/manager?project=${projectName}&job=${jobid}&history">Job History
- <small>$jobid</small>
+ <h1><a href="${context}/manager?project=${projectName}&job=${jobId}&history">Job History
+ <small>$jobId</small>
</a></h1>
</div>
</div>
@@ -64,7 +80,7 @@
<li><a
href="${context}/manager?project=${projectName}"><strong>Project</strong> $projectName
</a></li>
- <li class="active"><strong>Job History</strong> $jobid</li>
+ <li class="active"><strong>Job History</strong> $jobId</li>
</ol>
</div>
</div>
@@ -106,7 +122,9 @@
#end
</td>
<td>
- <a href="${context}/manager?project=${projectName}&flow=${job.immediateFlowId}&job=${jobid}">${jobid}</a>
+ <a href="${context}/manager?project=${projectName}&flow=${job.immediateFlowId}&job=${jobId}">
+ ${jobId}
+ </a>
</td>
<td>
<a href="${context}/manager?project=${projectName}&flow=${job.immediateFlowId}">${job.immediateFlowId}</a>
@@ -132,35 +150,7 @@
</tbody>
</table>
- <ul class="pagination" id="pageSelection">
- <li id="previous" class="first"><a
- href="${context}/manager?project=${projectName}&job=${jobid}&history&page=${previous.nextPage}&size=${previous.size}"><span
- class="arrow">←</span>Previous</a></li>
- <li id="page1" #if($page1.selected) class="active" #elseif ($page1.disabled)
- class="disabled" #end><a
- href="${context}/manager?project=${projectName}&job=${jobid}&history&page=${page1.nextPage}&size=${page1.size}">${page1.page}</a>
- </li>
- <li id="page2" #if($page2.selected) class="active" #elseif ($page2.disabled)
- class="disabled" #end><a
- href="${context}/manager?project=${projectName}&job=${jobid}&history&page=${page2.nextPage}&size=${page2.size}">${page2.page}</a>
- </li>
- <li id="page3" #if($page3.selected) class="active" #elseif ($page3.disabled)
- class="disabled" #end><a
- href="${context}/manager?project=${projectName}&job=${jobid}&history&page=${page3.nextPage}&size=${page3.size}">${page3.page}</a>
- </li>
- <li id="page4" #if($page4.selected) class="active" #elseif ($page4.disabled)
- class="disabled" #end><a
- href="${context}/manager?project=${projectName}&job=${jobid}&history&page=${page4.nextPage}&size=${page4.size}">${page4.page}</a>
- </li>
- <li id="page5" #if($page5.selected) class="active" #elseif ($page5.disabled)
- class="disabled" #end><a
- href="${context}/manager?project=${projectName}&job=${jobid}&history&page=${page5.nextPage}&size=${page5.size}">${page5.page}</a>
- </li>
- <li id="next"><a
- href="${context}/manager?project=${projectName}&job=${jobid}&history&page=${next.nextPage}&size=${next.size}">Next<span
- class="arrow">→</span></a></li>
- </ul>
-
+ <ul id="jobHistoryPagination" class="pagination"></ul>
</div><!-- /.col-xs-12 -->
</div><!-- /.row -->
diff --git a/azkaban-web-server/src/web/js/azkaban/view/job-history.js b/azkaban-web-server/src/web/js/azkaban/view/job-history.js
index c52a0ff..ea61ae9 100644
--- a/azkaban-web-server/src/web/js/azkaban/view/job-history.js
+++ b/azkaban-web-server/src/web/js/azkaban/view/job-history.js
@@ -21,18 +21,44 @@ var jobHistoryView;
var dataModel;
azkaban.DataModel = Backbone.Model.extend({});
-$(function () {
- var selected;
- var series = dataSeries;
- dataModel = new azkaban.DataModel();
- dataModel.set({
- "data": series
+var initJobHistoryPage = function (settings) {
+ dataModel = new azkaban.DataModel({
+ page: settings.page,
+ pageSize: settings.pageSize,
+ visiblePages: settings.visiblePages,
+ recordCount: settings.recordCount,
+ dataSeries: settings.dataSeries,
+ projectName: settings.projectName,
+ jobId: settings.jobId,
+ fetchJobHistoryUrl: settings.fetchJobHistoryUrl
});
+
dataModel.trigger('render');
jobHistoryView = new azkaban.TimeGraphView({
el: $('#timeGraph'),
model: dataModel,
- modelField: "data"
+ modelField: "dataSeries"
});
-});
+
+ if (settings.recordCount) {
+ $('#jobHistoryPagination').twbsPagination({
+ totalPages: Math.ceil(
+ dataModel.get("recordCount") / dataModel.get("pageSize")),
+ startPage: dataModel.get("page"),
+ initiateStartPageClick: false,
+ visiblePages: dataModel.get("visiblePages"),
+ onPageClick: function (event, page) {
+ var qparams = {
+ "project": dataModel.get("projectName"),
+ "job": dataModel.get("jobId"),
+ "page": page,
+ "size": dataModel.get("pageSize")
+ };
+ window.location.href = dataModel.get("fetchJobHistoryUrl") + "?history&"
+ + $.param(qparams);
+ }
+ });
+ }
+
+};