azkaban-uncached

Details

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())
                                 	&ndash;
                                 #else
+                                	$utils.displayBytes(${status.getBlockSize()})
+                                #end
+                            </td>
+                            <td>
+								#if($status.isDir())
+                                	&ndash;
+                                #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}";
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;
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