azkaban-uncached
Changes
src/java/azkaban/webapp/servlet/ProjectManagerServlet.java 339(+186 -153)
src/tl/flowsummary.tl 12(+6 -6)
src/web/js/azkaban.flow.view.js 50(+24 -26)
Details
src/java/azkaban/webapp/servlet/ProjectManagerServlet.java 339(+186 -153)
diff --git a/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java b/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
index 6099b5c..bee757e 100644
--- a/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
+++ b/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
@@ -30,6 +30,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.HashSet;
import java.util.Set;
import javax.servlet.ServletConfig;
@@ -196,6 +197,11 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
if (handleAjaxPermission(project, user, Type.READ, ret)) {
ajaxFetchFlow(project, ret, req, resp);
}
+ }
+ else if (ajaxName.equals("fetchflowdetails")) {
+ if (handleAjaxPermission(project, user, Type.READ, ret)) {
+ ajaxFetchFlowDetails(project, ret, req);
+ }
}
else if (ajaxName.equals("fetchflowgraph")) {
if (handleAjaxPermission(project, user, Type.READ, ret)) {
@@ -302,7 +308,38 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
ret.put("logData", eventData);
}
+
+ private List<String> getFlowJobTypes(Flow flow) {
+ Set<String> jobTypeSet = new HashSet<String>();
+ for (Node node : flow.getNodes()) {
+ jobTypeSet.add(node.getType());
+ }
+ List<String> jobTypes = new ArrayList<String>();
+ jobTypes.addAll(jobTypeSet);
+ return jobTypes;
+ }
+ private void ajaxFetchFlowDetails(Project project,
+ HashMap<String, Object> ret, HttpServletRequest req)
+ throws ServletException {
+ String projectName = getParam(req, "project");
+ String flowName = getParam(req, "flow");
+
+ Flow flow = null;
+ try {
+ flow = project.getFlow(flowName);
+ if (flow == null) {
+ ret.put("error", "Flow " + flowName + " not found.");
+ return;
+ }
+
+ ret.put("jobTypes", getFlowJobTypes(flow));
+ }
+ catch (AccessControlException e) {
+ ret.put("error", e.getMessage());
+ }
+ }
+
private void ajaxFetchFlowExecutions(Project project, HashMap<String, Object> ret, HttpServletRequest req) throws ServletException {
String flowId = getParam(req, "flow");
int from = Integer.valueOf(getParam(req, "start"));
@@ -918,88 +955,88 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
Flow flow = null;
try {
project = projectManager.getProject(projectName);
-
if (project == null) {
page.add("errorMsg", "Project " + projectName + " not found.");
+ page.render();
+ return;
}
- else {
- if (!hasPermission(project, user, Type.READ)) {
- throw new AccessControlException( "No permission to view project " + projectName + ".");
- }
-
- page.add("project", project);
-
- flow = project.getFlow(flowName);
- if (flow == null) {
- page.add("errorMsg", "Flow " + flowName + " not found.");
- }
- else {
- page.add("flowid", flow.getId());
- Node node = flow.getNode(jobName);
- if (node == null) {
- page.add("errorMsg", "Job " + jobName + " not found.");
- }
- else {
- Props prop = projectManager.getProperties(project, node.getJobSource());
- Props overrideProp = projectManager.getJobOverrideProperty(project, jobName);
- if (overrideProp == null) {
- overrideProp = new Props();
- }
- Props comboProp = new Props(prop);
- for (String key : overrideProp.getKeySet()) {
- comboProp.put(key, overrideProp.get(key));
- }
- page.add("jobid", node.getId());
- page.add("jobtype", node.getType());
-
- ArrayList<String> dependencies = new ArrayList<String>();
- Set<Edge> inEdges = flow.getInEdges(node.getId());
- if (inEdges != null) {
- for (Edge dependency: inEdges) {
- dependencies.add(dependency.getSourceId());
- }
- }
- if (!dependencies.isEmpty()) {
- page.add("dependencies", dependencies);
- }
-
- ArrayList<String> dependents = new ArrayList<String>();
- Set<Edge> outEdges = flow.getOutEdges(node.getId());
- if (outEdges != null) {
- for (Edge dependent: outEdges) {
- dependents.add(dependent.getTargetId());
- }
- }
- if (!dependents.isEmpty()) {
- page.add("dependents", dependents);
- }
-
- // Resolve property dependencies
- ArrayList<String> source = new ArrayList<String>();
- String nodeSource = node.getPropsSource();
- if (nodeSource != null) {
- source.add(nodeSource);
- FlowProps parent = flow.getFlowProps(nodeSource);
- while (parent.getInheritedSource() != null) {
- source.add(parent.getInheritedSource());
- parent = flow.getFlowProps(parent.getInheritedSource());
- }
- }
- if (!source.isEmpty()) {
- page.add("properties", source);
- }
-
- ArrayList<Pair<String,String>> parameters = new ArrayList<Pair<String, String>>();
- // Parameter
- for (String key : comboProp.getKeySet()) {
- String value = comboProp.get(key);
- parameters.add(new Pair<String,String>(key, value));
- }
-
- page.add("parameters", parameters);
- }
- }
- }
+ if (!hasPermission(project, user, Type.READ)) {
+ throw new AccessControlException( "No permission to view project " + projectName + ".");
+ }
+
+ page.add("project", project);
+ flow = project.getFlow(flowName);
+ if (flow == null) {
+ page.add("errorMsg", "Flow " + flowName + " not found.");
+ page.render();
+ return;
+ }
+
+ page.add("flowid", flow.getId());
+ Node node = flow.getNode(jobName);
+ if (node == null) {
+ page.add("errorMsg", "Job " + jobName + " not found.");
+ page.render();
+ return;
+ }
+
+ Props prop = projectManager.getProperties(project, node.getJobSource());
+ Props overrideProp = projectManager.getJobOverrideProperty(project, jobName);
+ if (overrideProp == null) {
+ overrideProp = new Props();
+ }
+ Props comboProp = new Props(prop);
+ for (String key : overrideProp.getKeySet()) {
+ comboProp.put(key, overrideProp.get(key));
+ }
+ page.add("jobid", node.getId());
+ page.add("jobtype", node.getType());
+
+ ArrayList<String> dependencies = new ArrayList<String>();
+ Set<Edge> inEdges = flow.getInEdges(node.getId());
+ if (inEdges != null) {
+ for (Edge dependency: inEdges) {
+ dependencies.add(dependency.getSourceId());
+ }
+ }
+ if (!dependencies.isEmpty()) {
+ page.add("dependencies", dependencies);
+ }
+
+ ArrayList<String> dependents = new ArrayList<String>();
+ Set<Edge> outEdges = flow.getOutEdges(node.getId());
+ if (outEdges != null) {
+ for (Edge dependent: outEdges) {
+ dependents.add(dependent.getTargetId());
+ }
+ }
+ if (!dependents.isEmpty()) {
+ page.add("dependents", dependents);
+ }
+
+ // Resolve property dependencies
+ ArrayList<String> source = new ArrayList<String>();
+ String nodeSource = node.getPropsSource();
+ if (nodeSource != null) {
+ source.add(nodeSource);
+ FlowProps parent = flow.getFlowProps(nodeSource);
+ while (parent.getInheritedSource() != null) {
+ source.add(parent.getInheritedSource());
+ parent = flow.getFlowProps(parent.getInheritedSource());
+ }
+ }
+ if (!source.isEmpty()) {
+ page.add("properties", source);
+ }
+
+ ArrayList<Pair<String,String>> parameters = new ArrayList<Pair<String, String>>();
+ // Parameter
+ for (String key : comboProp.getKeySet()) {
+ String value = comboProp.get(key);
+ parameters.add(new Pair<String,String>(key, value));
+ }
+
+ page.add("parameters", parameters);
}
catch (AccessControlException e) {
page.add("errorMsg", e.getMessage());
@@ -1007,7 +1044,6 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
catch (ProjectManagerException e) {
page.add("errorMsg", e.getMessage());
}
-
page.render();
}
@@ -1023,67 +1059,65 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
Flow flow = null;
try {
project = projectManager.getProject(projectName);
-
if (project == null) {
page.add("errorMsg", "Project " + projectName + " not found.");
+ page.render();
+ return;
}
- else {
- if (!hasPermission(project,user,Type.READ)) {
- throw new AccessControlException( "No permission to view project " + projectName + ".");
- }
-
- page.add("project", project);
-
- flow = project.getFlow(flowName);
- if (flow == null) {
- page.add("errorMsg", "Flow " + flowName + " not found.");
- }
- else {
- page.add("flowid", flow.getId());
- Node node = flow.getNode(jobName);
-
- if (node == null) {
- page.add("errorMsg", "Job " + jobName + " not found.");
- }
- else {
- Props prop = projectManager.getProperties(project, propSource);
-
- page.add("property", propSource);
-
- page.add("jobid", node.getId());
-
- // Resolve property dependencies
- ArrayList<String> inheritProps = new ArrayList<String>();
- FlowProps parent = flow.getFlowProps(propSource);
- while(parent.getInheritedSource() != null) {
- inheritProps.add(parent.getInheritedSource());
- parent = flow.getFlowProps(parent.getInheritedSource());
- }
- if(!inheritProps.isEmpty()) {
- page.add("inheritedproperties", inheritProps);
- }
-
- ArrayList<String> dependingProps = new ArrayList<String>();
- FlowProps child = flow.getFlowProps(flow.getNode(jobName).getPropsSource());
- while(!child.getSource().equals(propSource)) {
- dependingProps.add(child.getSource());
- child = flow.getFlowProps(child.getInheritedSource());
- }
- if(!dependingProps.isEmpty()) {
- page.add("dependingproperties", dependingProps);
- }
-
- ArrayList<Pair<String,String>> parameters = new ArrayList<Pair<String, String>>();
- // Parameter
- for (String key : prop.getKeySet()) {
- String value = prop.get(key);
- parameters.add(new Pair<String,String>(key, value));
- }
-
- page.add("parameters", parameters);
- }
- }
- }
+
+ if (!hasPermission(project,user,Type.READ)) {
+ throw new AccessControlException( "No permission to view project " + projectName + ".");
+ }
+ page.add("project", project);
+
+ flow = project.getFlow(flowName);
+ if (flow == null) {
+ page.add("errorMsg", "Flow " + flowName + " not found.");
+ page.render();
+ return;
+ }
+
+ page.add("flowid", flow.getId());
+ Node node = flow.getNode(jobName);
+ if (node == null) {
+ page.add("errorMsg", "Job " + jobName + " not found.");
+ page.render();
+ return;
+ }
+
+ Props prop = projectManager.getProperties(project, propSource);
+ page.add("property", propSource);
+ page.add("jobid", node.getId());
+
+ // Resolve property dependencies
+ ArrayList<String> inheritProps = new ArrayList<String>();
+ FlowProps parent = flow.getFlowProps(propSource);
+ while (parent.getInheritedSource() != null) {
+ inheritProps.add(parent.getInheritedSource());
+ parent = flow.getFlowProps(parent.getInheritedSource());
+ }
+ if (!inheritProps.isEmpty()) {
+ page.add("inheritedproperties", inheritProps);
+ }
+
+ ArrayList<String> dependingProps = new ArrayList<String>();
+ FlowProps child = flow.getFlowProps(flow.getNode(jobName).getPropsSource());
+ while (!child.getSource().equals(propSource)) {
+ dependingProps.add(child.getSource());
+ child = flow.getFlowProps(child.getInheritedSource());
+ }
+ if (!dependingProps.isEmpty()) {
+ page.add("dependingproperties", dependingProps);
+ }
+
+ ArrayList<Pair<String,String>> parameters = new ArrayList<Pair<String, String>>();
+ // Parameter
+ for (String key : prop.getKeySet()) {
+ String value = prop.get(key);
+ parameters.add(new Pair<String,String>(key, value));
+ }
+
+ page.add("parameters", parameters);
}
catch (AccessControlException e) {
page.add("errorMsg", e.getMessage());
@@ -1104,24 +1138,23 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
Flow flow = null;
try {
project = projectManager.getProject(projectName);
-
if (project == null) {
page.add("errorMsg", "Project " + projectName + " not found.");
+ page.render();
+ return;
}
- else {
- if (!hasPermission(project, user, Type.READ)) {
- throw new AccessControlException( "No permission Project " + projectName + ".");
- }
-
- page.add("project", project);
-
- flow = project.getFlow(flowName);
- if (flow == null) {
- page.add("errorMsg", "Flow " + flowName + " not found.");
- }
-
- page.add("flowid", flow.getId());
- }
+
+ if (!hasPermission(project, user, Type.READ)) {
+ throw new AccessControlException( "No permission Project " + projectName + ".");
+ }
+
+ page.add("project", project);
+ flow = project.getFlow(flowName);
+ if (flow == null) {
+ page.add("errorMsg", "Flow " + flowName + " not found.");
+ }
+
+ page.add("flowid", flow.getId());
}
catch (AccessControlException e) {
page.add("errorMsg", e.getMessage());
diff --git a/src/java/azkaban/webapp/servlet/velocity/style.vm b/src/java/azkaban/webapp/servlet/velocity/style.vm
index 6f65f36..73df059 100644
--- a/src/java/azkaban/webapp/servlet/velocity/style.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/style.vm
@@ -21,7 +21,18 @@
<!-- Bootstrap core CSS -->
<link href="/css/bootstrap.css" rel="stylesheet">
<link href="/css/bootstrap-fileinput.css" rel="stylesheet">
- <link href="/css/bootstrap-azkaban.css" rel="stylesheet">
+ <link href="/css/bootstrap-azkaban.css" rel="stylesheet">
+ <style type="text/css">
+ .navbar-enviro .navbar-enviro-name {
+ color: ${azkaban_color};
+ }
+ .navbar-inverse {
+ border-top: 5px solid ${azkaban_color};
+ }
+ .navbar-inverse .navbar-nav > .active >a {
+ border-bottom: 1px solid ${azkaban_color};
+ }
+ </style>
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
src/tl/flowsummary.tl 12(+6 -6)
diff --git a/src/tl/flowsummary.tl b/src/tl/flowsummary.tl
index 7e42852..e1227ad 100644
--- a/src/tl/flowsummary.tl
+++ b/src/tl/flowsummary.tl
@@ -2,16 +2,16 @@
<table class="table table-striped table-bordered table-condensed table-hover">
<tbody>
<tr>
- <td class="flow-summary-key">Workflow name</td>
- <td class="flow-summary-value">{general.flowId}</td>
+ <td class="flow-summary-key">Flow name</td>
+ <td class="flow-summary-value">{flowName}</td>
<td class="flow-summary-key">Project name</td>
- <td class="flow-summary-value">{general.projectName}</td>
+ <td class="flow-summary-value">{projectName}</td>
</tr>
<tr>
- <td class="flow-summary-key">Workflow Hadoop User Name</td>
- <td class="flow-summary-value">{general.user}</td>
+ <td class="flow-summary-key">Run As</td>
+ <td class="flow-summary-value">{user}</td>
<td class="flow-summary-key">Job Types Used</td>
- <td class="flow-summary-value">{general.apis}</td>
+ <td class="flow-summary-value">{#jobTypes}{.} {/jobTypes}</td>
</tr>
</tbody>
</table>
src/web/js/azkaban.flow.view.js 50(+24 -26)
diff --git a/src/web/js/azkaban.flow.view.js b/src/web/js/azkaban.flow.view.js
index 897f09b..55d26c4 100644
--- a/src/web/js/azkaban.flow.view.js
+++ b/src/web/js/azkaban.flow.view.js
@@ -299,36 +299,34 @@ azkaban.SummaryView = Backbone.View.extend({
initialize: function(settings) {
console.log("summaryView initialize");
- var general = {
- projectName: projectName,
- flowId: flowId
- };
- /*var schedule = {
- scheduleId: "0",
- submitUser: "azkaban",
- firstSchedTime: "1",
- nextExecTime: "2",
- period: "3",
- };
- var lastRun = {
- maxMapSlots: 3,
- maxReduceSlots: 9999,
- totalMapSlots: 3,
- totalReduceSlots: 9999,
- numJobs: 3,
- longestTaskTime: 1111
- };*/
- var lastRun = null;
this.model.bind('change:view', this.handleChangeView, this);
this.model.bind('render', this.render, this);
- this.model.set({'general': general});
- this.fetchSchedule();
+ this.fetchDetails();
+ this.fetchSchedule();
this.fetchLastRun();
this.model.trigger('render');
},
+ fetchDetails: function() {
+ var requestURL = contextURL + "/manager";
+ var requestData = {
+ 'ajax': 'fetchflowdetails',
+ 'project': projectName,
+ 'flow': flowId
+ };
+ var model = this.model;
+ var successHandler = function(data) {
+ console.log(data);
+ model.set({
+ 'jobTypes': data.jobTypes
+ });
+ model.trigger('render');
+ };
+ $.get(requestURL, requestData, successHandler, 'json');
+ },
+
fetchSchedule: function() {
var requestURL = contextURL + "/schedule"
var requestData = {
@@ -338,10 +336,8 @@ azkaban.SummaryView = Backbone.View.extend({
};
var model = this.model;
var successHandler = function(data) {
- if (data.schedule != null) {
- model.set({'schedule': data.schedule});
- model.trigger('render');
- }
+ model.set({'schedule': data.schedule});
+ model.trigger('render');
};
$.get(requestURL, requestData, successHandler, 'json');
},
@@ -357,7 +353,9 @@ azkaban.SummaryView = Backbone.View.extend({
render: function(evt) {
console.log("summaryView render");
var data = {
+ projectName: projectName,
flowName: flowId,
+ jobTypes: this.model.get('jobTypes'),
general: this.model.get('general'),
schedule: this.model.get('schedule'),
lastRun: this.model.get('lastRun')