azkaban-uncached

UI for quick execute.

2/5/2013 2:32:52 AM

Details

.classpath 2(+2 -0)

diff --git a/.classpath b/.classpath
index ed3781d..3265399 100644
--- a/.classpath
+++ b/.classpath
@@ -29,5 +29,7 @@
 	<classpathentry kind="lib" path="lib/commons-configuration-1.8.jar"/>
 	<classpathentry kind="lib" path="lib/commons-dbutils-1.5.jar"/>
 	<classpathentry kind="lib" path="lib/commons-dbcp-1.4.jar"/>
+	<classpathentry kind="lib" path="extlib/mysql-connector-java-5.1.16-bin.jar"/>
+	<classpathentry kind="lib" path="lib/commons-pool-1.6.jar"/>
 	<classpathentry kind="output" path="dist/classes"/>
 </classpath>
diff --git a/src/java/azkaban/project/JdbcProjectLoader.java b/src/java/azkaban/project/JdbcProjectLoader.java
index c6b9408..90f3363 100644
--- a/src/java/azkaban/project/JdbcProjectLoader.java
+++ b/src/java/azkaban/project/JdbcProjectLoader.java
@@ -846,7 +846,6 @@ public class JdbcProjectLoader implements ProjectLoader {
 		}
 	}
 	
-	
 	@Override
 	public Map<String,Props> fetchProjectProperties(int projectId, int version) throws ProjectManagerException {
 		QueryRunner runner = new QueryRunner(dataSource);
diff --git a/src/java/azkaban/webapp/servlet/velocity/projectpage.vm b/src/java/azkaban/webapp/servlet/velocity/projectpage.vm
index 723dc91..78c6763 100644
--- a/src/java/azkaban/webapp/servlet/velocity/projectpage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/projectpage.vm
@@ -94,12 +94,12 @@
 					<tbody>
 #if($flows)
 #foreach($flow in $flows)
-						<tr class="row" >
-							<td class="tb-name">
-								<div class="jobfolder expand" id="${flow.id}">
-									<span class="state-icon"></span>
-									<a href="${context}/manager?project=${project.name}&flow=${flow.id}">${flow.id}</a>
-								</div>
+						<tr class="row">
+							<td class="tb-name" flow="${flow.id}" project="${project.name}">
+									<div class="jobfolder expand" id="${flow.id}">
+										<span class="state-icon"></span>
+										<a href="${context}/manager?project=${project.name}&flow=${flow.id}">${flow.id}</a>
+									</div>
 							</td>
 						</tr>
 						<tr class="childrow" id="${flow.id}-child" style="display: none;">
@@ -166,6 +166,16 @@
 				<a class="yes btn6" id="delete-btn" href="#">Yes</a>
 			</div>
 		</div>
+		<div id="flow-execute" class="modal">
+			<h3>Execute Flow</h3>
+			<div id="execute-message" class="message">
+			</div>
+			<div class="actions">
+				<a class="yes btn1" id="execute-btn">Execute</a>
+				<a class="yes btn2" id="customize-btn">Customize Execution</a>
+				<a class="no simplemodal-close btn3">Cancel</a>
+			</div>
+		</div>
 	</body>
 </html>
 
diff --git a/src/web/css/azkaban.css b/src/web/css/azkaban.css
index 7c1aa97..80f0f17 100644
--- a/src/web/css/azkaban.css
+++ b/src/web/css/azkaban.css
@@ -657,7 +657,6 @@ tr:hover td {
 }
 
 .modal .message {
-  font-size: 81.25%;
   padding: 20px;
 }
 
@@ -1107,7 +1106,7 @@ tr:hover td {
 	margin-left:auto;
 	margin-right: auto;
 	text-align: center;
-	width: 80%;
+	width: 90%;
 }
 
 .childrow .expandedFlow {
@@ -1156,7 +1155,7 @@ tr:hover td {
 }
 
 .childrow .innerTable a.dependency {
-	color: #005066;
+	color: #0099CC;
 }
 
 .childrow .innerJobRow {
@@ -2320,6 +2319,48 @@ span .nowrap {
 	font-weight: bold;
 }
 
+/*Azkaban Hover Menu */
+#flow-tabs .row .tb-name {
+	
+}
+
+.job-hover-menu {
+	float: right;
+}
+
+.job-hover-menu div {
+	margin-left: 2px;
+	float: left;
+}
+
+/*Azkaban Hover Menu */
+.jobfolder {
+	padding-top: 3px;
+	height: 22px;
+	float: left;
+}
+
+tr.row td.tb-name {
+	padding-top: 0px;
+	padding-bottom: 0px;
+}
+
+.expandedFlow td.tb-job-name {
+	padding-top: 0px;
+	padding-bottom: 0px;
+	height: 25px;
+}
+
+.expandedFlow td.tb-job-name:hover {
+	background-color: #E1E3E2;
+}
+
+.expandedFlow td.tb-job-name a{
+	padding-top: 3px;
+	padding-bottom: 0px;
+	float: left;
+}
+
 /* old styles */
 .azkaban-charts .hitarea {
 	background-image: url("../../js/jqueryui/themes/custom-theme/images/ui-icons_cccccc_256x240.png");
@@ -2330,6 +2371,10 @@ span .nowrap {
 	cursor: pointer;
 }
 
+.job-hover-menu {
+	padding-top: 1px; 
+}
+
 .azkaban-charts .expandable-hitarea { background-position: -32px -16px; }
 .azkaban-charts .expandable-hitarea.collapse { background-position: 0 -16px; }
 /* clean up */
diff --git a/src/web/js/azkaban.project.view.js b/src/web/js/azkaban.project.view.js
index 6e0613f..a233824 100644
--- a/src/web/js/azkaban.project.view.js
+++ b/src/web/js/azkaban.project.view.js
@@ -76,7 +76,12 @@ var flowTableView;
 azkaban.FlowTableView= Backbone.View.extend({
   events : {
     "click .jobfolder": "expandFlowProject",
-    "hover .expandedFlow a": "highlight"
+    "hover .expandedFlow a": "highlight",
+    "hover .row .tb-name": "flowRunOptions",
+    "hover .innerTable .tb-job-name": "jobRunOptions",
+    "click .runJob": "runJob",
+    "click .runWithDep": "runWithDep",
+    "click .executeFlow": "executeFlow"
   },
   initialize : function(settings) {
   	_.bindAll(this, 'createJobListTable');
@@ -133,7 +138,8 @@ azkaban.FlowTableView= Backbone.View.extend({
   createJobListTable : function(data, innerTable) {
   	var nodes = data.nodes;
   	var flowId = data.flowId;
-  	var requestURL = contextURL + "/manager?project=" + data.project + "&flow=" + data.flowId + "&job=";
+  	var project = data.project;
+  	var requestURL = contextURL + "/manager?project=" + flowId + "&flow=" + project + "&job=";
   	for (var i = 0; i < nodes.length; i++) {
 		var job = nodes[i];
 		var name = job.id;
@@ -143,6 +149,10 @@ azkaban.FlowTableView= Backbone.View.extend({
 		var tr = document.createElement("tr");
 		var idtd = document.createElement("td");
 		$(idtd).addClass("tb-name");
+		$(idtd).addClass("tb-job-name");
+		idtd.flowId=flowId;
+		idtd.projectName=project;
+		idtd.jobName=name;
 		
 		var ida = document.createElement("a");
 		ida.dependents = job.dependents;
@@ -158,9 +168,75 @@ azkaban.FlowTableView= Backbone.View.extend({
 		$(innerTable).append(tr);
   	}
   },
+  flowRunOptions: function(evt) {
+  	var hover = evt.type == "mouseover";
+  	var projectName = $(evt.currentTarget).attr("project");
+  	var flowId = $(evt.currentTarget).attr("flow");
+  	
+  	var menuName = flowId + "-hover-menu";
+  	if (hover) {
+  		var divMenu = document.createElement("div");
+  		$(divMenu).attr("id", menuName);
+  		$(divMenu).addClass("job-hover-menu");
+  		
+  		var divRunJob = document.createElement("div");
+  		$(divRunJob).addClass("btn1");
+  		$(divRunJob).addClass("executeFlow");
+  		$(divRunJob).text("Execute Flow");
+  		divRunJob.flowId = flowId;
+  		$(divMenu).append(divRunJob);
+
+  		$(evt.currentTarget).append(divMenu);
+  	}
+  	else {
+  		var menu = $("#" + menuName);
+  		$(menu).remove();
+  	}
+  },
+  jobRunOptions: function(evt) {
+    var projectName = evt.currentTarget.projectName;
+  	var flowId = evt.currentTarget.flowId;
+  	var jobName = evt.currentTarget.jobName;
+  	console.log("job run options " + projectName + ":" + flowId + ":" + jobName);
+  	
+  	var hover = evt.type == "mouseover";
+  	
+  	var menuName = flowId + "-" + jobName + "-hover-menu";
+  	if (hover) {
+  		var divMenu = document.createElement("div");
+  		$(divMenu).attr("id", menuName);
+  		$(divMenu).addClass("job-hover-menu");
+
+  		var divRunJob = document.createElement("div");
+  		$(divRunJob).addClass("btn1");
+  		$(divRunJob).addClass("runJob");
+  		$(divRunJob).text("Run Job");
+  		divRunJob.jobName = jobName;
+  		divRunJob.flowId = flowId;
+  		$(divMenu).append(divRunJob);
+  		
+  		var divRunWithDep = document.createElement("div");
+  		$(divRunWithDep).addClass("btn1");
+  		$(divRunWithDep).addClass("runWithDep");
+  		$(divRunWithDep).text("Run With Dependencies");
+  		divRunWithDep.jobName = jobName;
+  		divRunWithDep.flowId = flowId;
+  		$(divMenu).append(divRunWithDep);
+  		
+  		$(evt.currentTarget).append(divMenu);
+  	}
+  	else {
+  		var menu = $("#" + menuName);
+  		$(menu).remove();
+  	}
+  	
+  },
   highlight: function(evt) {
  	var currentTarget = evt.currentTarget;
- 	var dependents = currentTarget.dependents;
+	this.highlightJob(currentTarget);
+  },
+  highlightJob: function(currentTarget) {
+   	var dependents = currentTarget.dependents;
  	var dependencies = currentTarget.dependencies;
  	var flowid = currentTarget.flowid;
  	
@@ -176,8 +252,44 @@ azkaban.FlowTableView= Backbone.View.extend({
 	 		var depId = flowid + "-" + dependencies[i];
 	 		$("#"+depId).toggleClass("dependency");
 	 	}
-
- 	}
+  	}
+  },
+  runJob: function(evt) {
+  	console.log("Run Job");
+  	var jobId = evt.currentTarget.jobName;
+  	var flowId = evt.currentTarget.flowId;
+  	
+  	$("#execute-message").text("Run only job '" + jobId + "' in flow '" + flowId + "'.");
+  	this.executeFlowDialog();
+  },
+  runWithDep: function(evt) {
+   var jobId = evt.currentTarget.jobName;
+  	var flowId = evt.currentTarget.flowId;
+    console.log("Run With Dep");
+    var jobId = evt.currentTarget.jobId;
+    $("#execute-message").text("Run job '" + jobId + "' and all of its ancestors in '" + flowId + "'.");
+    this.executeFlowDialog();
+  },
+  executeFlow: function(evt) {
+    console.log("Execute Flow");
+    var flowId = evt.currentTarget.flowId;
+    $("#execute-message").text("Executing the complete flow '" + flowId + "'.");
+    this.executeFlowDialog();
+  },
+  executeFlowDialog: function(message) {
+ 	$('#flow-execute').modal({
+      closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
+      position: ["20%",],
+      containerId: 'confirm-container',
+      containerCss: {
+        'height': '220px',
+        'width': '565px'
+      },
+      onShow: function (dialog) {
+        var modal = this;
+        $("#errorMsg").hide();
+      }
+    });
   },
   render: function() {
   }
@@ -239,5 +351,4 @@ $(function() {
 	projectSummary = new azkaban.ProjectSummaryView({el:$('#project-summary')});
 	deleteProjectView = new azkaban.DeleteProjectView({el: $('#delete-project')});
 	// Setting up the project tabs
-
 });