Added support code for JobDetails page in admin console
git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_dev_next@1140 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/Graphs.js b/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/Graphs.js
new file mode 100644
index 0000000..bc3b95b
--- /dev/null
+++ b/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/Graphs.js
@@ -0,0 +1,148 @@
+Graphs = {};
+
+Graphs.DAG = function() {
+ this.nodeMap = {};
+ this.edgeMap = {};
+}
+
+Graphs.DAG.prototype.addNode = function(key, attachment) {
+ var node = new Graphs.Node(this, key, attachment);
+ this.nodeMap[key] = node;
+ return node;
+}
+
+Graphs.DAG.prototype.addEdge = function(key, attachment, sNode, sIndex, tNode, tIndex) {
+ var edge = new Graphs.DirectedEdge(this, key, attachment, sNode, sIndex, tNode, tIndex);
+ this.edgeMap[key] = edge;
+ sNode.outEdges[sIndex] = edge;
+ tNode.inEdges[tIndex] = edge;
+ return edge;
+}
+
+Graphs.DAG.prototype.lookupNode = function(key) {
+ return this.nodeMap[key];
+}
+
+Graphs.DAG.prototype.lookupEdge = function(key) {
+ return this.edgeMap[key];
+}
+
+Graphs.DAG.prototype.walkNodes = function(callback) {
+ for ( var nKey in this.nodeMap) {
+ callback(this.nodeMap[nKey]);
+ }
+}
+
+Graphs.DAG.prototype.walkEdges = function(callback) {
+ for ( var eKey in this.edgeMap) {
+ callback(this.edgeMap[eKey]);
+ }
+}
+
+Graphs.DAG.prototype.findRoots = function() {
+ var roots = [];
+ var callback = function(node) {
+ if (node.inEdges.length == 0) {
+ roots.push(node);
+ }
+ }
+ this.walkNodes(callback);
+ return roots;
+}
+
+Graphs.DAG.prototype.findLeaves = function() {
+ var leaves = [];
+ var callback = function(node) {
+ if (node.outEdges.length == 0) {
+ leaves.push(node);
+ }
+ }
+ this.walkNodes(callback);
+ return leaves;
+}
+
+Graphs.DAG.prototype.tsort = function() {
+ var sortedNodes = [];
+ var nodeState = {};
+
+ function visit(node) {
+ if (!nodeState[node.key]) {
+ nodeState[node.key] = true;
+ for ( var i = 0; i < node.inEdges.length; ++i) {
+ visit(node.inEdges[i].sNode);
+ }
+ sortedNodes.push(node);
+ }
+ }
+
+ var roots = this.findLeaves();
+ for ( var i = 0; i < roots.length; ++i) {
+ visit(roots[i]);
+ }
+ return sortedNodes;
+}
+
+Graphs.DAG.prototype.stratify = function() {
+ var sortedNodes = this.tsort();
+ var stratumMap = {};
+ var strata = [];
+ for ( var i = 0; i < sortedNodes.length; ++i) {
+ var node = sortedNodes[i];
+ var maxParentStratum = -1;
+ for ( var j = 0; j < node.inEdges.length; ++j) {
+ var edge = node.inEdges[j];
+ maxParentStratum = Math.max(maxParentStratum, stratumMap[edge.sNode.key]);
+ }
+ var stratum = maxParentStratum + 1;
+ stratumMap[node.key] = stratum;
+ var stratumList = strata[stratum];
+ if (!stratumList) {
+ stratumList = [];
+ strata[stratum] = stratumList;
+ }
+ stratumList.push(node);
+ }
+ return strata;
+}
+
+Graphs.Node = function(dag, key, attachment) {
+ this.dag = dag;
+ this.key = key;
+ this.attachment = attachment;
+ this.inEdges = [];
+ this.outEdges = [];
+}
+
+Graphs.DirectedEdge = function(dag, key, attachment, sNode, sIndex, tNode, tIndex) {
+ this.dag = dag;
+ this.key = key;
+ this.attachment = attachment;
+ this.sNode = sNode;
+ this.sIndex = sIndex;
+ this.tNode = tNode;
+ this.tIndex = tIndex;
+}
+
+Graphs.JsPlumbRenderer = function(dag, element, options) {
+ this.dag = dag;
+ this.element = element;
+ this.options = options;
+}
+
+Graphs.JsPlumbRenderer.prototype.refresh = function() {
+ var strata = this.dag.stratify();
+
+ while (this.element.hasChildNodes()) {
+ this.element.removeChild(this.element.lastChild);
+ }
+ for ( var i = 0; i < strata.length; ++i) {
+ var stratumList = strata[i];
+ for ( var j = 0; j < stratumList.length; ++j) {
+ var node = stratumList[j];
+ var div = document.createElement('div');
+ div.id = node.key;
+ div.dagNode = node;
+ this.element.appendChild(div);
+ }
+ }
+}
\ No newline at end of file
diff --git a/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/JobDetailsPage.js b/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/JobDetailsPage.js
new file mode 100644
index 0000000..828e310
--- /dev/null
+++ b/hyracks-control-cc/src/main/resources/static/javascript/adminconsole/JobDetailsPage.js
@@ -0,0 +1,85 @@
+$(function() {
+ var jobSpecDAG = new Graphs.DAG();
+ var jobSpecRenderer;
+
+ function drawJobGraph() {
+ var jobGraphDiv = $('#job-graph')[0];
+ jobSpecRenderer = new Graphs.JsPlumbRenderer(jobSpecDAG, jobGraphDiv, null);
+ jobSpecRenderer.refresh();
+ }
+
+ function onJobRunDataReceived(data) {
+ var run = data.result;
+
+ if (run.status != 'TERMINATED' && run.status != 'FAILURE') {
+ setTimeout(fetchJobRun, 10000);
+ }
+ }
+
+ function fetchJobRun() {
+ $.ajax({
+ url : '/rest/jobs/' + $.getURLParam('job-id') + '/job-run',
+ method : 'GET',
+ dataType : 'json',
+ success : onJobRunDataReceived
+ });
+ }
+
+ function onJobActivityGraphDataReceived(data) {
+ var jag = data.result;
+ activityMap = new Object;
+ var activities = jag.activities;
+ for ( var i = 0; i < activities.length; ++i) {
+ var activity = activities[i];
+ }
+
+ drawJobGraph();
+
+ fetchJobRun();
+ }
+
+ function fetchJobActivityGraph() {
+ $.ajax({
+ url : '/rest/jobs/' + $.getURLParam('job-id') + '/job-activity-graph',
+ method : 'GET',
+ dataType : 'json',
+ success : onJobActivityGraphDataReceived
+ });
+ }
+
+ function onJobSpecificationDataReceived(data) {
+ var jobSpec = data.result;
+ var operators = jobSpec.operators;
+ for ( var i = 0; i < operators.length; ++i) {
+ var op = operators[i];
+ jobSpecDAG.addNode(op.id, op);
+ }
+ var connectors = jobSpec.connectors;
+ for ( var i = 0; i < connectors.length; ++i) {
+ var conn = connectors[i];
+ var sNode = jobSpecDAG.lookupNode(conn['in-operator-id']);
+ var sIndex = conn['in-operator-port'];
+ var tNode = jobSpecDAG.lookupNode(conn['out-operator-id']);
+ var tIndex = conn['out-operator-port'];
+ jobSpecDAG.addEdge(conn.id, conn, sNode, sIndex, tNode, tIndex);
+ }
+ fetchJobActivityGraph();
+ }
+
+ function fetchJobSpecification() {
+ $.ajax({
+ url : '/rest/jobs/' + $.getURLParam('job-id') + '/job-specification',
+ method : 'GET',
+ dataType : 'json',
+ success : onJobSpecificationDataReceived
+ });
+ }
+
+ function init() {
+ fetchJobSpecification();
+ }
+
+ jsPlumb.bind("ready", function() {
+ init();
+ });
+});
\ No newline at end of file