Repository: tez Updated Branches: refs/heads/TEZ-2980 231c4d157 -> 480ea0785
TEZ-3062. Tez UI 2: Integrate graphical view (sree) Project: http://git-wip-us.apache.org/repos/asf/tez/repo Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/480ea078 Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/480ea078 Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/480ea078 Branch: refs/heads/TEZ-2980 Commit: 480ea0785ac4963b9773ae0df51b92022bf912a3 Parents: 231c4d1 Author: Sreenath Somarajapuram <s...@apache.org> Authored: Mon Feb 1 15:49:31 2016 +0530 Committer: Sreenath Somarajapuram <s...@apache.org> Committed: Mon Feb 1 15:49:31 2016 +0530 ---------------------------------------------------------------------- TEZ-2980-CHANGES.txt | 1 + tez-ui2/src/main/webapp/app/controllers/dag.js | 3 + .../webapp/app/controllers/dag/graphical.js | 165 +++++++++++++++++++ tez-ui2/src/main/webapp/app/entities/entity.js | 1 + tez-ui2/src/main/webapp/app/models/dag.js | 5 + tez-ui2/src/main/webapp/app/router.js | 1 + .../src/main/webapp/app/routes/dag/graphical.js | 79 +++++++++ tez-ui2/src/main/webapp/app/routes/pollster.js | 1 + tez-ui2/src/main/webapp/app/serializers/dag.js | 4 + .../main/webapp/app/templates/dag/graphical.hbs | 14 ++ tez-ui2/src/main/webapp/config/environment.js | 3 +- tez-ui2/src/main/webapp/package.json | 1 + .../unit/controllers/dag/graphical-test.js | 46 ++++++ .../tests/unit/routes/dag/graphical-test.js | 38 +++++ 14 files changed, 361 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/TEZ-2980-CHANGES.txt ---------------------------------------------------------------------- diff --git a/TEZ-2980-CHANGES.txt b/TEZ-2980-CHANGES.txt index 0457cb0..653899c 100644 --- a/TEZ-2980-CHANGES.txt +++ b/TEZ-2980-CHANGES.txt @@ -29,3 +29,4 @@ ALL CHANGES: TEZ-3060. Tez UI 2: Activate auto-refresh TEZ-3061. Tez UI 2: Display in-progress vertex table in DAG details TEZ-3069. Tez UI 2: Make error bar fully functional + TEZ-3062. Tez UI 2: Integrate graphical view http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/app/controllers/dag.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/controllers/dag.js b/tez-ui2/src/main/webapp/app/controllers/dag.js index 4c8ec1a..2ef4fac 100644 --- a/tez-ui2/src/main/webapp/app/controllers/dag.js +++ b/tez-ui2/src/main/webapp/app/controllers/dag.js @@ -38,6 +38,9 @@ export default ParentController.extend({ text: "DAG Counters", routeName: "dag.counters" }, { + text: "Graphical View", + routeName: "dag.graphical" + }, { text: "All Vertices", routeName: "dag.vertices" }, { http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js b/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js new file mode 100644 index 0000000..a6e42c3 --- /dev/null +++ b/tez-ui2/src/main/webapp/app/controllers/dag/graphical.js @@ -0,0 +1,165 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +import MultiTableController from '../multi-table'; +import ColumnDefinition from 'em-table/utils/column-definition'; + +export default MultiTableController.extend({ + + columnSelectorTitle: 'Customize vertex tooltip', + + breadcrumbs: [{ + text: "Graphical View", + routeName: "dag.graphical", + }], + + columns: ColumnDefinition.make([{ + id: 'name', + headerTitle: 'Vertex Name', + contentPath: 'name', + cellComponentName: 'em-table-linked-cell', + getCellContent: function (row) { + return { + routeName: "vertex", + model: row.get("entityID"), + text: row.get("name") + }; + } + },{ + id: 'entityID', + headerTitle: 'Vertex Id', + contentPath: 'entityID' + },{ + id: 'status', + headerTitle: 'Status', + contentPath: 'status', + cellComponentName: 'em-table-status-cell', + observePath: true + },{ + id: 'progress', + headerTitle: 'Progress', + contentPath: 'progress', + cellComponentName: 'em-table-progress-cell', + observePath: true + },{ + id: 'startTime', + headerTitle: 'Start Time', + contentPath: 'startTime', + cellDefinition: { + type: 'date' + } + },{ + id: 'endTime', + headerTitle: 'End Time', + contentPath: 'endTime', + cellDefinition: { + type: 'date' + } + },{ + id: 'duration', + headerTitle: 'Duration', + contentPath: 'duration', + cellDefinition: { + type: 'duration' + } + },{ + id: 'firstTaskStartTime', + headerTitle: 'First Task Start Time', + contentPath: 'firstTaskStartTime', + cellDefinition: { + type: 'date' + } + },{ + id: 'totalTasks', + headerTitle: 'Tasks', + contentPath: 'totalTasks', + },{ + id: 'processorClassName', + headerTitle: 'Processor Class', + contentPath: 'processorClassName', + }]), + + redirect: function (details) { + switch(details.type) { + case 'vertex': + this.transitionToRoute('vertex.index', details.d.get('data.entityID')); + break; + case 'task': + this.transitionToRoute('vertex.tasks', details.d.get('data.entityID')); + break; + case 'io': + break; + case 'input': + break; + case 'output': + break; + } + }, + + actions: { + entityClicked: function (details) { + + /** + * In IE 11 under Windows 7, mouse events are not delivered to the page + * anymore at all after a SVG use element that was under the mouse is + * removed from the DOM in the event listener in response to a mouse click. + * See https://connect.microsoft.com/IE/feedback/details/796745 + * + * This condition and related actions must be removed once the bug is fixed + * in all supported IE versions + */ + if(this.get("env.ENV.isIE")) { + var pageType = details.type === "io" ? "additionals" : details.type, + message = `You will be redirected to ${pageType} page`; + + alert(message); + } + this.redirect(details); + } + }, + + viewData: Ember.computed("model", function () { + var model = this.get("model"), + dag, vertices, entities; + + if(!model) { + return {}; + } + + dag = this.get('model.firstObject.dag'); + vertices = this.get('model.firstObject.dag.vertices') || []; + entities = {}; + + model.forEach(function (vertexData) { + entities[vertexData.get('name')] = vertexData; + }); + + vertices.forEach(function (vertex) { + vertex.data = entities[vertex.vertexName]; + }); + + return { + vertices: vertices, + edges: dag.get('edges'), + vertexGroups: dag.get('vertexGroups') + }; + }) + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/app/entities/entity.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/entities/entity.js b/tez-ui2/src/main/webapp/app/entities/entity.js index 6f98097..f763dcf 100644 --- a/tez-ui2/src/main/webapp/app/entities/entity.js +++ b/tez-ui2/src/main/webapp/app/entities/entity.js @@ -100,6 +100,7 @@ var Entity = Ember.Object.extend(NameMixin, { needLoader.then(function (model) { parentModel.refreshLoadTime(); parentModel.set(needOptions.name, model); + return model; }); if(needOptions.silent) { http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/app/models/dag.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/models/dag.js b/tez-ui2/src/main/webapp/app/models/dag.js index bb4c5df..4c4cd96 100644 --- a/tez-ui2/src/main/webapp/app/models/dag.js +++ b/tez-ui2/src/main/webapp/app/models/dag.js @@ -46,6 +46,11 @@ export default AMTimelineModel.extend({ submitter: DS.attr("string"), contextID: DS.attr("string"), + // Serialize when required + vertices: DS.attr('object'), + edges: DS.attr('object'), + vertexGroups: DS.attr('object'), + domain: DS.attr("string"), containerLogs: DS.attr("object"), queue: Ember.computed("app", function () { http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/app/router.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/router.js b/tez-ui2/src/main/webapp/app/router.js index 1f54580..eb3afb3 100644 --- a/tez-ui2/src/main/webapp/app/router.js +++ b/tez-ui2/src/main/webapp/app/router.js @@ -31,6 +31,7 @@ Router.map(function() { this.route('attempts'); this.route('counters'); this.route('index', function() {}); + this.route('graphical'); }); this.route('vertex', {path: '/vertex/:vertex_id'}, function() { this.route('tasks'); http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/app/routes/dag/graphical.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/routes/dag/graphical.js b/tez-ui2/src/main/webapp/app/routes/dag/graphical.js new file mode 100644 index 0000000..3d9550f --- /dev/null +++ b/tez-ui2/src/main/webapp/app/routes/dag/graphical.js @@ -0,0 +1,79 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; +import MultiAmPollsterRoute from '../multi-am-pollster'; + +export default MultiAmPollsterRoute.extend({ + title: "Graphical View", + + loaderNamespace: "dag", + + setupController: function (controller, model) { + this._super(controller, model); + Ember.run.later(this, "startCrumbBubble"); + }, + + load: function (value, query, options) { + return this.get("loader").query('vertex', { + dagID: this.modelFor("dag").get("id") + }, options); + }, + + _loadedValueObserver: Ember.observer("loadedValue", function () { + var loadedValue = this.get("loadedValue"), + records = []; + + loadedValue.forEach(function (record) { + records.push(record); + }); + + this.set("polledRecords", records); + Ember.run.later(this, "setViewHeight", 100); + }), + + setViewHeight: function () { + var container = Ember.$('#graphical-view-component-container'), + offset; + + if(container) { + offset = container.offset(); + container.height( + Math.max( + // 50 pixel is left at the bottom + offset ? Ember.$(window).height() - offset.top - 70 : 0, + 500 // Minimum dag view component container height + ) + ); + } + }, + + actions: { + didTransition: function () { + Ember.$(window).on('resize', this.setViewHeight); + this._super(); + return true; + }, + willTransition: function () { + Ember.$(window).off('resize', this.setViewHeight); + this._super(); + return true; + }, + } + +}); http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/app/routes/pollster.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/routes/pollster.js b/tez-ui2/src/main/webapp/app/routes/pollster.js index 7d62c39..9e1e40d 100644 --- a/tez-ui2/src/main/webapp/app/routes/pollster.js +++ b/tez-ui2/src/main/webapp/app/routes/pollster.js @@ -22,6 +22,7 @@ import AbstractRoute from './abstract'; export default AbstractRoute.extend({ polling: Ember.inject.service("pollster"), + // Todo - Change name to recordsToPoll polledRecords: null, // Must be implemented by inheriting classes http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/app/serializers/dag.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/serializers/dag.js b/tez-ui2/src/main/webapp/app/serializers/dag.js index 9da7bb5..f7d2f21 100644 --- a/tez-ui2/src/main/webapp/app/serializers/dag.js +++ b/tez-ui2/src/main/webapp/app/serializers/dag.js @@ -116,6 +116,10 @@ export default TimelineSerializer.extend({ endTime: getEndTime, // duration + vertices: 'otherinfo.dagPlan.vertices', + edges: 'otherinfo.dagPlan.edges', + vertexGroups: 'otherinfo.dagPlan.vertexGroups', + // appID domain: 'domain', // queue http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs b/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs new file mode 100644 index 0000000..fcb7e86 --- /dev/null +++ b/tez-ui2/src/main/webapp/app/templates/dag/graphical.hbs @@ -0,0 +1,14 @@ +{{#if loaded}} + <br/> + <div id="graphical-view-component-container"> + {{em-tgraph + data=viewData + vertexProperties=visibleColumns + entityClicked='entityClicked' + configure='openColumnSelector' + }} + <div class="dag-view-legend">Refresh updates only the tooltip values. When sources & sinks are hidden, double click green bubble to toggle visibility locally.</div> + </div> +{{else}} + {{partial "loading"}} +{{/if}} http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/config/environment.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/config/environment.js b/tez-ui2/src/main/webapp/config/environment.js index b102c8f..e5fc8ac 100644 --- a/tez-ui2/src/main/webapp/config/environment.js +++ b/tez-ui2/src/main/webapp/config/environment.js @@ -37,7 +37,8 @@ module.exports = function(environment) { contentSecurityPolicy: { 'connect-src': "* 'self'", - 'style-src': "'self' 'unsafe-inline'" + 'style-src': "'self' 'unsafe-inline'", + 'script-src': "'self' 'unsafe-inline'" } }; http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/package.json ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/package.json b/tez-ui2/src/main/webapp/package.json index 9cb055b..e30d5bc 100644 --- a/tez-ui2/src/main/webapp/package.json +++ b/tez-ui2/src/main/webapp/package.json @@ -23,6 +23,7 @@ "devDependencies": { "bower": "^1.7.1", "broccoli-asset-rev": "^2.2.0", + "em-tgraph": "0.0.3", "ember-bootstrap": "0.5.1", "ember-cli": "1.13.13", "ember-cli-app-version": "^1.0.0", http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js new file mode 100644 index 0000000..cb9ab66 --- /dev/null +++ b/tez-ui2/src/main/webapp/tests/unit/controllers/dag/graphical-test.js @@ -0,0 +1,46 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:dag/graphical', 'Unit | Controller | dag/graphical', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +test('Basic creation test', function(assert) { + let controller = this.subject({ + send: Ember.K, + initVisibleColumns: Ember.K, + getCounterColumns: function () { + return []; + } + }); + + assert.ok(controller); + + assert.ok(controller.columnSelectorTitle); + assert.ok(controller.breadcrumbs); + assert.ok(controller.columns); + + assert.ok(controller.redirect); + assert.ok(controller.actions.entityClicked); + assert.ok(controller.viewData); +}); http://git-wip-us.apache.org/repos/asf/tez/blob/480ea078/tez-ui2/src/main/webapp/tests/unit/routes/dag/graphical-test.js ---------------------------------------------------------------------- diff --git a/tez-ui2/src/main/webapp/tests/unit/routes/dag/graphical-test.js b/tez-ui2/src/main/webapp/tests/unit/routes/dag/graphical-test.js new file mode 100644 index 0000000..ab838c5 --- /dev/null +++ b/tez-ui2/src/main/webapp/tests/unit/routes/dag/graphical-test.js @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:dag/graphical', 'Unit | Route | dag/graphical', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +test('Basic creation test', function(assert) { + let route = this.subject(); + + assert.ok(route); + assert.ok(route.title); + assert.ok(route.loaderNamespace); + assert.ok(route.setupController); + assert.ok(route.load); + assert.ok(route._loadedValueObserver); + assert.ok(route.setViewHeight); + assert.ok(route.actions.didTransition); + assert.ok(route.actions.willTransition); +});