azkaban-uncached
Changes
src/java/azkaban/executor/ExecutorManager.java 65(+53 -12)
src/web/css/azkaban.css 21(+21 -0)
src/web/js/azkaban.history.view.js 83(+83 -0)
Details
src/java/azkaban/executor/ExecutorManager.java 65(+53 -12)
diff --git a/src/java/azkaban/executor/ExecutorManager.java b/src/java/azkaban/executor/ExecutorManager.java
index 238b6c2..0fc866a 100644
--- a/src/java/azkaban/executor/ExecutorManager.java
+++ b/src/java/azkaban/executor/ExecutorManager.java
@@ -56,8 +56,12 @@ import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.log4j.Logger;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.joda.time.format.DateTimeFormat;
import azkaban.executor.ExecutableFlow.Status;
+import azkaban.executor.ExecutorManager.ExecutionReference;
import azkaban.flow.Flow;
import azkaban.utils.ExecutableFlowLoader;
import azkaban.utils.JSONUtils;
@@ -291,15 +295,22 @@ public class ExecutorManager {
return endTime > refStart && startTime <= refEnd;
}
- public List<ExecutionReference> getFlowHistory(String regexPattern, int numResults, int skip) {
+ public List<ExecutionReference> getFlowHistory(String projRe, String flowRe, String userRe, long startTime, long endTime, int numResults, int skip, Boolean dofilter) {
ArrayList<ExecutionReference> searchFlows = new ArrayList<ExecutionReference>();
- Pattern pattern;
- try {
- pattern = Pattern.compile(regexPattern, Pattern.CASE_INSENSITIVE);
- } catch (PatternSyntaxException e) {
- logger.error("Bad regex pattern " + regexPattern);
- return searchFlows;
+ Pattern projPattern = null;
+ Pattern flowPattern = null;
+ Pattern userPattern = null;
+
+ if(dofilter == true) {
+ try {
+ projPattern = Pattern.compile(projRe, Pattern.CASE_INSENSITIVE);
+ flowPattern = Pattern.compile(flowRe, Pattern.CASE_INSENSITIVE);
+ userPattern = Pattern.compile(userRe, Pattern.CASE_INSENSITIVE);
+ } catch (PatternSyntaxException e) {
+ logger.error("Bad regex pattern " + projRe + " " + flowRe + " " + userRe);
+ return searchFlows;
+ }
}
for (ExecutionReference ref: runningReference.values()) {
@@ -307,9 +318,14 @@ public class ExecutorManager {
skip--;
}
else {
- if(pattern.matcher(ref.getFlowId()).find() ) {
- searchFlows.add(ref);
+ if(dofilter == true) {
+ if(flowPattern.matcher(ref.getFlowId()).find() && projPattern.matcher(ref.getProjectId()).find() && userPattern.matcher(ref.getUserId()).find()
+ && between(ref, startTime, endTime) ) {
+ searchFlows.add(ref);
+ }
}
+ else
+ searchFlows.add(ref);
if (searchFlows.size() == numResults) {
Collections.sort(searchFlows);
return searchFlows;
@@ -322,7 +338,25 @@ public class ExecutorManager {
return searchFlows;
}
- File[] archivePartitionsDir = archivePath.listFiles();
+ File[] archivePartitionsDir;
+ if(dofilter == true) {
+ final long startThreshold = startTime - 100000;
+ final long endThreshold = endTime + 100000;
+
+ archivePartitionsDir = archivePath.listFiles( new FileFilter() {
+ @Override
+ public boolean accept(File pathname) {
+ String name = pathname.getName();
+ long val = Long.valueOf(name);
+ return val >= startThreshold && val <= endThreshold;
+ }
+ }
+ );
+ }
+ else {
+ archivePartitionsDir = archivePath.listFiles();
+ }
+
Arrays.sort(archivePartitionsDir, new Comparator<File>() {
@Override
public int compare(File arg0, File arg1) {
@@ -347,8 +381,14 @@ public class ExecutorManager {
if (ref == null) {
continue;
}
-
- if(pattern.matcher(ref.getFlowId()).find() ) {
+
+ if(dofilter == true) {
+ if(flowPattern.matcher(ref.getFlowId()).find() && projPattern.matcher(ref.getProjectId()).find() && userPattern.matcher(ref.getUserId()).find()
+ && between(ref, startTime, endTime)) {
+ searchFlows.add(ref);
+ }
+ }
+ else {
searchFlows.add(ref);
}
} catch (IOException e) {
@@ -1374,4 +1414,5 @@ public class ExecutorManager {
}
}
+
}
diff --git a/src/java/azkaban/project/FileProjectManager.java b/src/java/azkaban/project/FileProjectManager.java
index 96cd717..43d46b0 100644
--- a/src/java/azkaban/project/FileProjectManager.java
+++ b/src/java/azkaban/project/FileProjectManager.java
@@ -219,7 +219,7 @@ public class FileProjectManager implements ProjectManager {
@Override
public List<Project> getUserProjectsByRe(User user, final String rePattern) {
- ArrayList<Project> array = new ArrayList<Project>();
+ List<Project> array = new ArrayList<Project>();
Pattern pattern;
try {
pattern = Pattern.compile(rePattern, Pattern.CASE_INSENSITIVE);
@@ -246,6 +246,23 @@ public class FileProjectManager implements ProjectManager {
return new ArrayList<Project>(projects.values());
}
+ @Override
+ public List<Project> getProjectsByRe(String rePattern) {
+ List<Project> allProjects = new ArrayList<Project>();
+ Pattern pattern;
+ try {
+ pattern = Pattern.compile(rePattern, Pattern.CASE_INSENSITIVE);
+ } catch (PatternSyntaxException e) {
+ logger.error("Bad regex pattern " + rePattern);
+ return allProjects;
+ }
+ for(Project project : getProjects()) {
+ if(pattern.matcher(project.getName()).find()) {
+ allProjects.add(project);
+ }
+ }
+ return allProjects;
+ }
@Override
public Project getProject(String name) {
@@ -662,4 +679,6 @@ public class FileProjectManager implements ProjectManager {
return "_project." + projectName + ".log";
}
+
+
}
\ No newline at end of file
diff --git a/src/java/azkaban/project/ProjectManager.java b/src/java/azkaban/project/ProjectManager.java
index 8896605..a1de6de 100644
--- a/src/java/azkaban/project/ProjectManager.java
+++ b/src/java/azkaban/project/ProjectManager.java
@@ -18,6 +18,8 @@ public interface ProjectManager {
public List<Project> getUserProjectsByRe(User user, String searchTerm);
public List<Project> getProjects();
+
+ public List<Project> getProjectsByRe(String searchTerm);
public void commitProject(String name) throws ProjectManagerException;
@@ -39,5 +41,7 @@ public interface ProjectManager {
public void getProjectLogs(String projectId, long tailBytes, long skipBytes, Writer writer) throws IOException;
+
+
}
\ No newline at end of file
diff --git a/src/java/azkaban/webapp/servlet/HistoryServlet.java b/src/java/azkaban/webapp/servlet/HistoryServlet.java
index 78d0258..7b5c74b 100644
--- a/src/java/azkaban/webapp/servlet/HistoryServlet.java
+++ b/src/java/azkaban/webapp/servlet/HistoryServlet.java
@@ -2,8 +2,7 @@ package azkaban.webapp.servlet;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
+
import java.util.HashMap;
import java.util.List;
@@ -12,9 +11,12 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import azkaban.executor.ExecutableFlow;
+import org.joda.time.DateTime;
+
+import org.joda.time.format.DateTimeFormat;
+
+
import azkaban.executor.ExecutorManager;
-import azkaban.executor.ExecutorManagerException;
import azkaban.executor.ExecutorManager.ExecutionReference;
import azkaban.utils.JSONUtils;
import azkaban.webapp.session.Session;
@@ -63,7 +65,7 @@ public class HistoryServlet extends LoginAbstractAzkabanServlet {
pageNum = 1;
}
- List<ExecutionReference> history = executorManager.getFlowHistory(searchTerm, pageSize, (pageNum - 1)*pageSize);
+ List<ExecutionReference> history = executorManager.getFlowHistory(".*", searchTerm, ".*", 0, DateTime.now().getMillis(), pageSize, (pageNum - 1)*pageSize, true);
page.add("flowHistory", history);
page.add("size", pageSize);
page.add("page", pageNum);
@@ -113,7 +115,7 @@ public class HistoryServlet extends LoginAbstractAzkabanServlet {
this.writeJSON(resp, ret);
}
}
-
+
private void fetchHistoryData(HttpServletRequest req, HttpServletResponse resp, HashMap<String, Object> ret) throws ServletException {
long start = getLongParam(req, "start");
long end = getLongParam(req, "end");
@@ -137,7 +139,7 @@ public class HistoryServlet extends LoginAbstractAzkabanServlet {
ret.put("data", refList);
}
- private void handleHistoryPage(HttpServletRequest req, HttpServletResponse resp, Session session) {
+ private void handleHistoryPage(HttpServletRequest req, HttpServletResponse resp, Session session) throws ServletException {
Page page = newPage(req, resp, session, "azkaban/webapp/servlet/velocity/historypage.vm");
int pageNum = getIntParam(req, "page", 1);
int pageSize = getIntParam(req, "size", 16);
@@ -145,8 +147,18 @@ public class HistoryServlet extends LoginAbstractAzkabanServlet {
if (pageNum < 0) {
pageNum = 1;
}
-
- List<ExecutionReference> history = executorManager.getFlowHistory(".*", pageSize, (pageNum - 1)*pageSize);
+ List<ExecutionReference> history = null;
+ if(hasParam(req, "advfilter")) {
+ String projRe = getParam(req, "projre").equals("") ? ".*" : getParam(req, "projre");
+ String flowRe = getParam(req, "flowre").equals("") ? ".*" : getParam(req, "flowre");
+ String userRe = getParam(req, "userre").equals("") ? ".*" : getParam(req, "userre");
+ long beginTime = getParam(req, "begin").equals("") ? 0 : DateTimeFormat.forPattern("MM/dd/yyyy").parseDateTime(getParam(req, "begin")).getMillis();
+ long endTime = getParam(req, "end").equals("") ? DateTime.now().getMillis() : DateTimeFormat.forPattern("MM/dd/yyyy").parseDateTime(getParam(req, "end")).getMillis();
+ history = executorManager.getFlowHistory(projRe, flowRe, userRe, beginTime, endTime, pageSize, (pageNum - 1)*pageSize, true);
+ }
+ else {
+ history = executorManager.getFlowHistory("", "", "", 0, 0, pageSize, (pageNum - 1)*pageSize, false);
+ }
page.add("flowHistory", history);
page.add("size", pageSize);
page.add("page", pageNum);
diff --git a/src/java/azkaban/webapp/servlet/IndexServlet.java b/src/java/azkaban/webapp/servlet/IndexServlet.java
index 0e84edd..6edf03d 100644
--- a/src/java/azkaban/webapp/servlet/IndexServlet.java
+++ b/src/java/azkaban/webapp/servlet/IndexServlet.java
@@ -47,7 +47,7 @@ public class IndexServlet extends LoginAbstractAzkabanServlet {
Page page = newPage(req, resp, session, "azkaban/webapp/servlet/velocity/index.vm");
if (hasParam(req, "all")) {
List<Project> projects = manager.getProjects();
- page.add("allProjects", "");
+ page.add("allProjects", "true");
page.add("projects", projects);
}
else {
@@ -72,9 +72,10 @@ public class IndexServlet extends LoginAbstractAzkabanServlet {
Page page = newPage(req, resp, session, "azkaban/webapp/servlet/velocity/index.vm");
if (hasParam(req, "all")) {
//do nothing special if one asks for 'ALL' projects
- List<Project> projects = manager.getProjects();
+ List<Project> projects = manager.getProjectsByRe(searchTerm);
page.add("allProjects", "");
page.add("projects", projects);
+ page.add("search_term", searchTerm);
}
else {
List<Project> projects = manager.getUserProjectsByRe(user, searchTerm);
diff --git a/src/java/azkaban/webapp/servlet/velocity/hdfsbrowserpage.vm b/src/java/azkaban/webapp/servlet/velocity/hdfsbrowserpage.vm
index b8ed02f..32a1311 100644
--- a/src/java/azkaban/webapp/servlet/velocity/hdfsbrowserpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/hdfsbrowserpage.vm
@@ -58,6 +58,7 @@
<th>Permission</th>
<th>Owner/Group</th>
<th>Size</th>
+ <th>Block Size</th>
<th>Reps</th>
<th>Modified Date</th>
</tr>
@@ -82,6 +83,13 @@
#if($status.isDir())
–
#else
+ $utils.displayBytes(${status.getBlockSize()})
+ #end
+ </td>
+ <td>
+ #if($status.isDir())
+ –
+ #else
${status.getReplication()}
#end
</td>
diff --git a/src/java/azkaban/webapp/servlet/velocity/historypage.vm b/src/java/azkaban/webapp/servlet/velocity/historypage.vm
index 4373199..41f5362 100644
--- a/src/java/azkaban/webapp/servlet/velocity/historypage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/historypage.vm
@@ -2,13 +2,15 @@
<html>
<head>
#parse( "azkaban/webapp/servlet/velocity/style.vm" )
- <script type="text/javascript" src="${context}/js/jquery/jquery.js"></script>
+ <script type="text/javascript" src="${context}/js/jquery/jquery.js"></script>
+ <script type="text/javascript" src="${context}/js/jqueryui/jquery-ui.custom.min.js"></script>
+ <script type="text/javascript" src="${context}/js/jqueryui/jquery.ui.datepicker.min.js"></script>
<script type="text/javascript" src="${context}/js/namespace.js"></script>
<script type="text/javascript" src="${context}/js/underscore-1.2.1-min.js"></script>
<script type="text/javascript" src="${context}/js/backbone-0.5.3-min.js"></script>
<script type="text/javascript" src="${context}/js/jquery.simplemodal.js"></script>
- <script type="text/javascript" src="${context}/js/azkaban.nav.js"></script>
- <script type="text/javascript" src="${context}/js/azkaban.main.view.js"></script>
+ <script type="text/javascript" src="${context}/js/azkaban.nav.js"></script>
+ <script type="text/javascript" src="${context}/js/azkaban.history.view.js"></script>
<script type="text/javascript">
var contextURL = "${context}";
var currentTime = ${currentTime};
@@ -26,14 +28,18 @@
<div id="all-jobs-content">
<div class="section-hd">
<h2>History</h2>
+ <a id="adv-filter-btn" class="btn1 " href="#">Advanced Filter</a>
<form id="search-form" method="post">
<input type="hidden" name="action" value="search">
<input type="submit" value="Quick Search" class="search-btn">
- <input id="searchtextbox" type="text" placeholder="by flow name containing ..." value=#if($search_term) ${search_term} #else "" #end class="search-input" name="searchterm">
+ <input id="searchtextbox" type="text" placeholder="flow name containing ..." value=#if($search_term) ${search_term} #else "" #end class="search-input" name="searchterm">
</form>
+
</div>
</div>
+
+
<div class="executionInfo">
<table id="executingJobs">
<thead>
@@ -92,5 +98,41 @@
</div>
</div>
</div>
+
+ <!-- modal content -->
+ <div id="adv-filter" class="modal">
+ <h3>Advanced Filter</h3>
+ <div id="errorMsg" class="box-error-message">$errorMsg</div>
+
+ <div class="message">
+ <fieldset>
+ <dl>
+
+ <dt><label for="path">Project Name</label></dt>
+ <dd><input id="projRe" type="text" placeholder="project name containing ..." value = "" class="filter-input" name="projre"/></dd>
+ <dt><label for="path">Flow Name Name</label></dt>
+ <dd><input id="flowRe" type="text" placeholder="flow name containing ..." value = "" class="filter-input" name="flowre"/></dd>
+ <dt><label for="path">User Name</label></dt>
+ <dd><input id="userRe" type="text" placeholder="user name containing ..." value = "" class="filter-input" name="userre"/></dd>
+ <dt>Date between</dt>
+ <dd><input type="text" id="daterangebegin" value=""/></dd>
+ <dt>and</dt>
+ <dd><input type="text" id="daterangeend" value=""/></dd>
+ </dl>
+ </fieldset>
+ </div>
+ <div class="actions">
+ <a class="yes btn2" id="filter-btn" href="#">Filter</a>
+ <a class="no simplemodal-close btn3" href="#">Cancel</a>
+ </div>
+ <div id="invalid-session" class="modal">
+ <h3>Invalid Session</h3>
+ <p>Session has expired. Please re-login.</p>
+ <div class="actions">
+ <a class="yes btn2" id="login-btn" href="#">Re-login</a>
+ </div>
+ </div>
+ </div>
+
</body>
</html>
\ No newline at end of file
diff --git a/src/java/azkaban/webapp/servlet/velocity/index.vm b/src/java/azkaban/webapp/servlet/velocity/index.vm
index d78c9f2..3454286 100644
--- a/src/java/azkaban/webapp/servlet/velocity/index.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/index.vm
@@ -44,10 +44,10 @@
<form id="search-form" method="post">
<input type="hidden" name="action" value="search">
<input type="submit" value="Quick Search" class="search-btn">
- <input id="searchtextbox" type="text" placeholder="by project name containing ..." value=#if($search_term) ${search_term} #else "" #end class="search-input" name="searchterm">
+ <input id="searchtextbox" type="text" placeholder="project name containing ..." value=#if($search_term) ${search_term} #else "" #end class="search-input" name="searchterm">
</form>
- <a id="create-project-btn" class="btn1 createproject" href="#">Create Project</a>
+ <a id="create-project-btn" class="btn1 " href="#">Create Project</a>
</div><!-- end .section-hd -->
</div>
<table id="all-jobs" class="all-jobs job-table">
diff --git a/src/java/azkaban/webapp/servlet/velocity/scheduledflowpage.vm b/src/java/azkaban/webapp/servlet/velocity/scheduledflowpage.vm
index 8890824..a41ec7f 100644
--- a/src/java/azkaban/webapp/servlet/velocity/scheduledflowpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/scheduledflowpage.vm
@@ -9,7 +9,6 @@
<script type="text/javascript" src="${context}/js/backbone-0.5.3-min.js"></script>
<script type="text/javascript" src="${context}/js/jquery.simplemodal.js"></script>
<script type="text/javascript" src="${context}/js/azkaban.nav.js"></script>
- <script type="text/javascript" src="${context}/js/azkaban.main.view.js"></script>
<script type="text/javascript" src="${context}/js/azkaban.scheduled.view.js"></script>
<script type="text/javascript">
var contextURL = "${context}";
src/web/css/azkaban.css 21(+21 -0)
diff --git a/src/web/css/azkaban.css b/src/web/css/azkaban.css
index 3fa206f..4603598 100644
--- a/src/web/css/azkaban.css
+++ b/src/web/css/azkaban.css
@@ -544,6 +544,27 @@ tr:hover td {
cursor: pointer;
}
+.advfilter-btn {
+ background: -moz-linear-gradient(center top , #E8E8E8 0pt, #CCC 100%) repeat scroll 0 0 transparent;
+ background: -webkit-gradient(linear, center top, center bottom, from(#E8E8E8), to(#CCC));
+ border: 1px solid #999;
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-left: none;
+ color: #666;
+ float: right;
+ font-weight: bold;
+ height: 24px;
+ font-size: 10pt;
+}
+
+.advfilter-btn:hover {
+ background: -moz-linear-gradient(center top , #F0F0F0 0pt, #DDD 100%) repeat scroll 0 0 transparent;
+ background: -webkit-gradient(linear, center top, center bottom, from(#F0F0F0), to(#DDD));
+ cursor: pointer;
+}
+
+
#scheduled-jobs-content,
#executing-jobs-content {
display: none;
src/web/js/azkaban.history.view.js 83(+83 -0)
diff --git a/src/web/js/azkaban.history.view.js b/src/web/js/azkaban.history.view.js
new file mode 100644
index 0000000..323a313
--- /dev/null
+++ b/src/web/js/azkaban.history.view.js
@@ -0,0 +1,83 @@
+$.namespace('azkaban');
+
+var advFilterView;
+azkaban.AdvFilterView = Backbone.View.extend({
+ events: {
+ "click #filter-btn": "handleAdvFilter"
+ },
+ initialize: function(settings) {
+ $( "#daterangebegin" ).datepicker();
+ $( "#daterangeend" ).datepicker();
+// $( "#daterangeend" ).datepicker('setDate', new Date());
+ $("#errorMsg").hide();
+ },
+ handleAdvFilter: function(evt) {
+ console.log("handleAdv");
+ var projre = $('#projRe').val();
+ var flowre = $('#flowRe').val();
+ var userre = $('#userRe').val();
+ var begin = $('#daterangebegin').val();
+ var end = $('#daterangeend').val();
+
+ console.log("filtering history");
+
+ var historyURL = contextURL + "/history"
+ var redirectURL = contextURL + "/schedule"
+
+
+ var requestURL = historyURL + "?advfilter=true&projre=" + projre + "&flowre=" + flowre + "&userre=" + userre + "&begin=" + begin + "&end=" + end ;
+ window.location = requestURL;
+
+// $.get(
+// historyURL,
+// {"action": "advfilter", "projre": projre, "flowre": flowre, "userre": userre},
+// function(data) {
+// if (data.action == "redirect") {
+// window.location = data.redirect;
+// }
+// },
+// "json"
+// )
+// $.ajax({
+// async: "false",
+// url: "history",
+// dataType: "json",
+// type: "POST",
+// data: {
+// action:"advfilter",
+// projre:projre,
+// flowre:flowre,
+// userre:userre
+// },
+// success: function(data) {
+// if (data.redirect) {
+// window.location = data.redirect;
+// }
+// }
+// })
+ },
+ render: function(){
+ }
+});
+
+$(function() {
+
+ filterView = new azkaban.AdvFilterView({el: $('#adv-filter')});
+
+ $('#adv-filter-btn').click( function() {
+ $('#adv-filter').modal({
+ closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
+ position: ["20%",],
+ containerId: 'confirm-container',
+ containerCss: {
+ 'height': '220px',
+ 'width': '500px'
+ },
+ onShow: function (dialog) {
+ var modal = this;
+ $("#errorMsg").hide();
+ }
+ });
+ });
+
+});
\ No newline at end of file