YARN-5153. Add a toggle button to switch between timeline view / table view for containers and application-attempts in new YARN UI. Contributed by Akhil PB.
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/bef6b2f0 Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/bef6b2f0 Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/bef6b2f0 Branch: refs/heads/YARN-3368_branch2 Commit: bef6b2f030c1b85025f5a09e9316aef95034fbcf Parents: deef8d5 Author: Sunil G <sun...@apache.org> Authored: Mon Apr 10 13:35:08 2017 +0530 Committer: Varun Saxena <varunsax...@apache.org> Committed: Wed Oct 18 02:06:48 2017 +0530 ---------------------------------------------------------------------- .../webapp/app/components/app-attempt-table.js | 7 - .../main/webapp/app/components/timeline-view.js | 199 ++++++++++++++++++- .../main/webapp/app/helpers/prepend-protocol.js | 29 +++ .../templates/components/app-attempt-table.hbs | 36 ++-- .../templates/components/container-table.hbs | 22 +- .../app/templates/components/timeline-view.hbs | 61 ++++-- .../tests/unit/helpers/prepend-protocol-test.js | 28 +++ 7 files changed, 331 insertions(+), 51 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/bef6b2f0/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.js index 3c43037..8828275 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/app-attempt-table.js @@ -19,11 +19,4 @@ import Ember from 'ember'; export default Ember.Component.extend({ - nodeHttpAddressFormatted: Ember.computed('attempt.nodeHttpAddress', function() { - var nodeHttpAddress = this.get('attempt.nodeHttpAddress'); - if (nodeHttpAddress && nodeHttpAddress.indexOf('://') < 0) { - nodeHttpAddress = 'http://' + nodeHttpAddress; - } - return nodeHttpAddress; - }) }); http://git-wip-us.apache.org/repos/asf/hadoop/blob/bef6b2f0/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js index d730a43..4a33d5b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/timeline-view.js @@ -18,6 +18,7 @@ import Ember from 'ember'; import Converter from 'yarn-ui/utils/converter'; +import ColumnDef from 'em-table/utils/column-definition'; export default Ember.Component.extend({ canvas: { @@ -31,6 +32,8 @@ export default Ember.Component.extend({ modelArr: [], colors: d3.scale.category10().range(), _selected: undefined, + gridColumns: [], + gridRows: [], selected: function() { return this._selected; @@ -276,5 +279,199 @@ export default Ember.Component.extend({ if (this.modelArr.length > 0) { this.setSelected(this.modelArr[0]); } + + if (this.get('attemptModel')) { + this.setAttemptsGridColumnsAndRows(); + } else { + this.setContainersGridColumnsAndRows(); + } + }, + + setAttemptsGridColumnsAndRows: function() { + var self = this; + var columns = []; + + columns.push({ + id: 'id', + headerTitle: 'Attempt ID', + contentPath: 'id', + cellComponentName: 'em-table-linked-cell', + minWidth: '300px', + getCellContent: function(row) { + return { + displayText: row.get('id'), + routeName: 'yarn-app-attempt', + id: row.get('id') + }; + } + }, { + id: 'attemptStartedTime', + headerTitle: 'Started Time', + contentPath: 'attemptStartedTime' + }, { + id: 'finishedTime', + headerTitle: 'Finished Time', + contentPath: 'finishedTime', + getCellContent: function(row) { + if (row.get('finishedTs')) { + return row.get('finishedTime'); + } + return 'N/A'; + } + }, { + id: 'elapsedTime', + headerTitle: 'Elapsed Time', + contentPath: 'elapsedTime' + }, { + id: 'appMasterContainerId', + headerTitle: 'AM Container ID', + contentPath: 'appMasterContainerId', + minWidth: '300px' + }, { + id: 'amNodeId', + headerTitle: 'AM Node ID', + contentPath: 'amNodeId' + }, { + id: 'attemptState', + headerTitle: 'State', + contentPath: 'attemptState', + getCellContent: function(row) { + var state = row.get('attemptState'); + if (state) { + return state; + } else { + return 'N/A'; + } + } + }, { + id: 'nodeHttpAddress', + headerTitle: 'NodeManager Web UI', + contentPath: 'nodeHttpAddress', + cellComponentName: 'em-table-html-cell', + getCellContent: function(row) { + var address = self.checkHttpProtocol(row.get('nodeHttpAddress')); + if (address) { + return `<a href="${address}" target="_blank">${address}</a>`; + } else { + return 'N/A'; + } + } + }, { + id: 'logsLink', + headerTitle: 'Logs', + contentPath: 'logsLink', + cellComponentName: 'em-table-html-cell', + getCellContent: function(row) { + var logUrl = self.checkHttpProtocol(row.get('logsLink')); + if (logUrl) { + return `<a href="${logUrl}" target="_blank">Link</a>`; + } else { + return 'N/A'; + } + } + }); + + var gridCols = ColumnDef.make(columns); + this.set('gridColumns', gridCols); + this.set('gridRows', this.modelArr); + }, + + setContainersGridColumnsAndRows: function() { + var self = this; + var columns = []; + + columns.push({ + id: 'id', + headerTitle: 'Container ID', + contentPath: 'id', + minWidth: '300px' + }, { + id: 'startedTime', + headerTitle: 'Started Time', + contentPath: 'startedTime' + }, { + id: 'finishedTime', + headerTitle: 'Finished Time', + contentPath: 'finishedTime', + getCellContent: function(row) { + if (row.get('finishedTs')) { + return row.get('finishedTime'); + } + return 'N/A'; + } + }, { + id: 'elapsedTime', + headerTitle: 'Elapsed Time', + contentPath: 'elapsedTime' + }, { + id: 'priority', + headerTitle: 'Priority', + contentPath: 'priority' + }, { + id: 'containerExitStatus', + headerTitle: 'Exit Status', + contentPath: 'containerExitStatus', + getCellContent: function(row) { + var status = row.get('containerExitStatus'); + if (status) { + return status; + } else { + return 'N/A'; + } + } + }, { + id: 'containerState', + headerTitle: 'State', + contentPath: 'containerState', + getCellContent: function(row) { + var state = row.get('containerState'); + if (state) { + return state; + } else { + return 'N/A'; + } + } + }, { + id: 'logUrl', + headerTitle: 'Logs', + contentPath: 'logUrl', + cellComponentName: 'em-table-html-cell', + getCellContent: function(row) { + var url = self.checkHttpProtocol(row.get('logUrl')); + if (url) { + return `<a href="${url}" target="_blank">${url}</a>`; + } else { + return 'N/A'; + } + } + }, { + id: 'nodeHttpAddress', + headerTitle: 'Node Manager UI', + contentPath: 'nodeHttpAddress', + cellComponentName: 'em-table-html-cell', + getCellContent: function(row) { + var address = self.checkHttpProtocol(row.get('nodeHttpAddress')); + if (address) { + return `<a href="${address}" target="_blank">${address}</a>`; + } else { + return 'N/A'; + } + } + }); + + var gridCols = ColumnDef.make(columns); + this.set('gridColumns', gridCols); + this.set('gridRows', this.modelArr); }, -}); \ No newline at end of file + + checkHttpProtocol: function(prop) { + if (prop && prop.indexOf('://') < 0) { + prop = 'http://' + prop; + } + return prop; + }, + + isDataEmpty: Ember.computed(function() { + return this.modelArr.length === 0; + }) +}); http://git-wip-us.apache.org/repos/asf/hadoop/blob/bef6b2f0/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/prepend-protocol.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/prepend-protocol.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/prepend-protocol.js new file mode 100644 index 0000000..e8d18c4 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/prepend-protocol.js @@ -0,0 +1,29 @@ +/** + * 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'; + +export function prependProtocol(params/*, hash*/) { + let address = params[0]; + if (address && address.indexOf('://') < 0) { + address = 'http://' + address; + } + return address; +} + +export default Ember.Helper.helper(prependProtocol); http://git-wip-us.apache.org/repos/asf/hadoop/blob/bef6b2f0/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-attempt-table.hbs ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-attempt-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-attempt-table.hbs index fcd076b..c3a9e32 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-attempt-table.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/app-attempt-table.hbs @@ -23,39 +23,43 @@ <td>{{attempt.id}}</td> </tr> <tr> - <td>Start Time</td> + <td>Started Time</td> <td>{{attempt.attemptStartedTime}}</td> </tr> + {{#if attempt.validatedFinishedTs}} <tr> - <td>AM Container Id</td> - <td>{{attempt.appMasterContainerId}}</td> + <td>Finished Time</td> + <td>{{attempt.validatedFinishedTs}}</td> </tr> - {{#if attempt.IsAmNodeUrl}} + {{/if}} <tr> - <td>AM Node Web UI</td> - <td><a href="{{nodeHttpAddressFormatted}}" target="_blank">{{nodeHttpAddressFormatted}}</a></td> + <td>Elapsed Time</td> + <td>{{attempt.elapsedTime}}</td> </tr> - {{/if}} <tr> - <td>AM Node Id</td> - <td>{{attempt.amNodeId}}</td> + <td>AM Container Id</td> + <td>{{attempt.appMasterContainerId}}</td> </tr> - {{#if attempt.IsLinkAvailable}} <tr> - <td>Log</td> - <td><a href="{{attempt.logsLink}}" target="_blank">Link</a></td> + <td>AM Node Id</td> + <td>{{attempt.amNodeId}}</td> </tr> - {{/if}} {{#if attempt.attemptState}} <tr> <td>Attempt State</td> <td>{{attempt.attemptState}}</td> </tr> {{/if}} - {{#if attempt.elapsedTime}} + {{#if attempt.nodeHttpAddress}} <tr> - <td>Elapsed Time</td> - <td>{{attempt.elapsedTime}}</td> + <td>AM Node Web UI</td> + <td><a href="{{prepend-protocol attempt.nodeHttpAddress}}" target="_blank">{{attempt.nodeHttpAddress}}</a></td> + </tr> + {{/if}} + {{#if attempt.logsLink}} + <tr> + <td>Log</td> + <td><a href="{{prepend-protocol attempt.logsLink}}" target="_blank">Link</a></td> </tr> {{/if}} </tbody> http://git-wip-us.apache.org/repos/asf/hadoop/blob/bef6b2f0/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs index 586f128..ab353d2 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/container-table.hbs @@ -19,13 +19,15 @@ <table id="container-table" class="table table-striped table-bordered" cellspacing="0" width="100%" height="100%"> <tbody> <tr> - <td>Start Time</td> + <td>Started Time</td> <td>{{container.startedTime}}</td> </tr> + {{#if container.validatedFinishedTs}} <tr> <td>Finished Time</td> <td>{{container.validatedFinishedTs}}</td> </tr> + {{/if}} <tr> <td>Elapsed Time</td> <td>{{container.elapsedTime}}</td> @@ -34,21 +36,29 @@ <td>Priority</td> <td>{{container.priority}}</td> </tr> - <tr> - <td>Log</td> - <td><a href="{{container.logUrl}}" target="_blank">Link</a></td> - </tr> + {{#if container.containerExitStatus}} <tr> <td>Exit Status</td> <td>{{container.containerExitStatus}}</td> </tr> + {{/if}} + {{#if container.containerState}} <tr> <td>State</td> <td>{{container.containerState}}</td> </tr> + {{/if}} + {{#if container.nodeHttpAddress}} <tr> <td>NodeManager UI</td> - <td><a href="{{container.nodeHttpAddress}}" target="_blank">{{container.nodeHttpAddress}}</a></td> + <td><a href="{{prepend-protocol container.nodeHttpAddress}}" target="_blank">{{container.nodeHttpAddress}}</a></td> + </tr> + {{/if}} + {{#if container.logUrl}} + <tr> + <td>Log</td> + <td><a href="{{prepend-protocol container.logUrl}}" target="_blank">Link</a></td> </tr> + {{/if}} </tbody> </table> http://git-wip-us.apache.org/repos/asf/hadoop/blob/bef6b2f0/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs index b110268..7856194 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/timeline-view.hbs @@ -25,30 +25,49 @@ Containers {{/if}} </div> - <div class="panel-body"> - <br/><br/> - <div class="col-md-8 container-fluid" id={{parent-id}}> - </div> - - <!-- diag info --> - <div class="col-md-4 container-fluid"> - <div class="panel panel-default add-ellipsis"> - <div class="panel-heading"> - {{#if selected.link}} - {{#link-to selected.linkname selected.id}}{{selected.id}}{{/link-to}} - {{else}} - {{selected.id}} - {{/if}} + {{#if isDataEmpty}} + <ul class="nav nav-tabs" role="tablist"> + <li class="active"> + <a href="#graphViewTab" role="tab" data-toggle="tab">Graph View</a> + </li> + <li class=""> + <a href="#gridViewTab" role="tab" data-toggle="tab">Grid View</a> + </li> + </ul> + <div class="panel-body"> + <div class="tab-content"> + <div role="tabpanel" class="tab-pane active" id="graphViewTab"> + <br/><br/> + <div class="col-md-8 container-fluid" id={{parent-id}}></div> + <!-- diag info --> + <div class="col-md-4 container-fluid"> + <div class="panel panel-default add-ellipsis"> + <div class="panel-heading"> + {{#if selected.link}} + {{#link-to selected.linkname selected.id}}{{selected.id}}{{/link-to}} + {{else}} + {{selected.id}} + {{/if}} + </div> + {{#if attemptModel}} + {{app-attempt-table attempt=selected}} + {{else}} + {{container-table container=selected}} + {{/if}} + </div> + </div> + </div> + <div role="tabpanel" class="tab-pane" id="gridViewTab"> + {{em-table columns=gridColumns rows=gridRows}} </div> - {{#if attemptModel}} - {{app-attempt-table attempt=selected}} - {{else}} - {{container-table container=selected}} - {{/if}} </div> </div> - </div> + {{else}} + <div class="panel-body"> + <h4 class="text-center">No data available!</h4> + </div> + {{/if}} </div> </div> -{{outlet}} \ No newline at end of file +{{outlet}} http://git-wip-us.apache.org/repos/asf/hadoop/blob/bef6b2f0/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/helpers/prepend-protocol-test.js ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/helpers/prepend-protocol-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/helpers/prepend-protocol-test.js new file mode 100644 index 0000000..6dc8137 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/helpers/prepend-protocol-test.js @@ -0,0 +1,28 @@ +/** + * 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 { prependProtocol } from '../../../helpers/prepend-protocol'; +import { module, test } from 'qunit'; + +module('Unit | Helper | prepend protocol'); + +// Replace this with your real tests. +test('it works', function(assert) { + let result = prependProtocol(42); + assert.ok(result); +}); --------------------------------------------------------------------- To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org For additional commands, e-mail: common-commits-h...@hadoop.apache.org