You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sr...@apache.org on 2014/01/31 22:13:08 UTC
git commit: AMBARI-4493. Jobs: Implement the linear Tez Vertices
table. (srimanth)
Updated Branches:
refs/heads/trunk 969800287 -> 5d4959c85
AMBARI-4493. Jobs: Implement the linear Tez Vertices table. (srimanth)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5d4959c8
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5d4959c8
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5d4959c8
Branch: refs/heads/trunk
Commit: 5d4959c854f329bb12ec9328e9752626bda10300
Parents: 9698002
Author: Srimanth Gunturi <sg...@hortonworks.com>
Authored: Fri Jan 31 12:02:38 2014 -0800
Committer: Srimanth Gunturi <sg...@hortonworks.com>
Committed: Fri Jan 31 13:13:02 2014 -0800
----------------------------------------------------------------------
ambari-web/app/controllers.js | 2 +
.../main/jobs/hive_job_details_controller.js | 43 +++++++
ambari-web/app/mappers/jobs/hive_job_mapper.js | 25 ++--
ambari-web/app/messages.js | 9 ++
ambari-web/app/models/jobs/tez_dag.js | 26 ++++-
ambari-web/app/routes/main.js | 38 +++++--
ambari-web/app/styles/application.less | 29 +++++
ambari-web/app/templates/main/jobs.hbs | 4 +-
.../templates/main/jobs/hive_job_details.hbs | 107 +++++++++++++++++
ambari-web/app/utils/ajax.js | 4 +-
ambari-web/app/utils/jobs.js | 12 +-
ambari-web/app/views.js | 1 +
.../views/main/jobs/hive_job_details_view.js | 114 +++++++++++++++++++
13 files changed, 384 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/controllers.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers.js b/ambari-web/app/controllers.js
index 4248fcb..02bcbf4 100644
--- a/ambari-web/app/controllers.js
+++ b/ambari-web/app/controllers.js
@@ -109,6 +109,8 @@ require('controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_memstoresi
require('controllers/main/charts/heatmap');
require('controllers/main/apps_controller');
require('controllers/main/jobs_controller');
+require('controllers/main/jobs/hive_job_details_controller');
+require('controllers/main/apps_controller');
require('controllers/main/apps/item_controller');
require('controllers/main/mirroring_controller');
require('controllers/main/mirroring/edit_dataset_controller');
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/controllers/main/jobs/hive_job_details_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/jobs/hive_job_details_controller.js b/ambari-web/app/controllers/main/jobs/hive_job_details_controller.js
new file mode 100644
index 0000000..3714f18
--- /dev/null
+++ b/ambari-web/app/controllers/main/jobs/hive_job_details_controller.js
@@ -0,0 +1,43 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+App.MainHiveJobDetailsController = Em.Controller.extend({
+ name : 'mainHiveJobDetailsController',
+ content : null,
+
+ /**
+ * path to page visited before
+ */
+ referer : '',
+ /**
+ * open dashboard page
+ */
+ routeHome : function() {
+ App.router.transitionTo('main.dashboard');
+ },
+
+ /**
+ * open jobs page
+ *
+ * @param event
+ */
+ routeToJobs : function() {
+ App.router.transitionTo('main.jobs.index');
+ }
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/mappers/jobs/hive_job_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/jobs/hive_job_mapper.js b/ambari-web/app/mappers/jobs/hive_job_mapper.js
index 32a4881..5f2b2f1 100644
--- a/ambari-web/app/mappers/jobs/hive_job_mapper.js
+++ b/ambari-web/app/mappers/jobs/hive_job_mapper.js
@@ -62,7 +62,7 @@ App.hiveJobMapper = App.QuickDataMapper.create({
var vertex = stageValue.Tez["Vertices:"][vertexName];
var vertexObj = {
id : dagName + "/" + vertexName,
- name : vertexName,
+ name : vertexName
};
vertexIds.push(vertexObj.id);
var operatorExtractor = function(obj) {
@@ -82,13 +82,13 @@ App.hiveJobMapper = App.QuickDataMapper.create({
return ops;
}
if (vertex["Map Operator Tree:"] != null) {
- vertexObj.isMap = true;
+ vertexObj.is_map = true;
vertexObj.operations = operatorExtractor(vertex["Map Operator Tree:"]);
- vertexObj.operationPlan = JSON.stringify(vertex["Map Operator Tree:"]);
+ vertexObj.operation_plan = JSON.stringify(vertex["Map Operator Tree:"], undefined, " ");
} else if (vertex["Reduce Operator Tree:"] != null) {
- vertexObj.isMap = false;
+ vertexObj.is_map = false;
vertexObj.operations = operatorExtractor(vertex["Reduce Operator Tree:"]);
- vertexObj.operationPlan = JSON.stringify(vertex["Reduce Operator Tree:"]);
+ vertexObj.operation_plan = JSON.stringify(vertex["Reduce Operator Tree:"], undefined, " ");
}
vertices.push(vertexObj);
}
@@ -96,20 +96,25 @@ App.hiveJobMapper = App.QuickDataMapper.create({
var edges = [];
var edgeIds = [];
for ( var childVertex in stageValue.Tez["Edges:"]) {
- stageValue.Tez["Edges:"][childVertex].forEach(function(e) {
+ var childVertices = stageValue.Tez["Edges:"][childVertex];
+ if (!$.isArray(childVertices)) {
+ // Single edge given as object instead of array
+ childVertices = [ childVertices ];
+ }
+ childVertices.forEach(function(e) {
var parentVertex = e.parent;
var edgeObj = {
id : dagName + "/" + parentVertex + "-" + childVertex,
- fromVertex : dagName + "/" + parentVertex,
- toVertex : dagName + "/" + childVertex
+ from_vertex : dagName + "/" + parentVertex,
+ to_vertex : dagName + "/" + childVertex
};
edgeIds.push(edgeObj.id);
switch (e.type) {
case "BROADCAST_EDGE":
- edgeObj.edgeType = App.TezDagVertexType.BROADCAST;
+ edgeObj.edge_type = App.TezDagVertexType.BROADCAST;
break;
case "SIMPLE_EDGE":
- edgeObj.edgeType = App.TezDagVertexType.SCATTER_GATHER;
+ edgeObj.edge_type = App.TezDagVertexType.SCATTER_GATHER;
break;
default:
break;
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 468a3b1..7b3ffee 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1829,6 +1829,15 @@ Em.I18n.translations = {
'menu.item.jobs':'Jobs',
'menu.item.admin':'Admin',
+ 'jobs.hive.tez.tasks':'Tez Tasks',
+ 'jobs.hive.tez.hdfs':'HDFS',
+ 'jobs.hive.tez.localFiles':'Local Files',
+ 'jobs.hive.tez.records':'Records',
+ 'jobs.hive.tez.reads':'{0} reads',
+ 'jobs.hive.tez.writes':'{0} writes',
+ 'jobs.hive.tez.records.count':'{0} Records',
+ 'jobs.hive.tez.operatorPlan':'Operator Plan',
+
'number.validate.empty': 'cannot be empty',
'number.validate.notValidNumber': 'not a valid number',
'number.validate.lessThanMinumum': 'value less than {0}',
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/models/jobs/tez_dag.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/jobs/tez_dag.js b/ambari-web/app/models/jobs/tez_dag.js
index 7ea2329..a3ddb82 100644
--- a/ambari-web/app/models/jobs/tez_dag.js
+++ b/ambari-web/app/models/jobs/tez_dag.js
@@ -17,13 +17,14 @@
var App = require('app');
var dateUtils = require('utils/date');
+var numberUtils = require('utils/number_utils');
App.TezDag = DS.Model.extend({
id : DS.attr('string'),
/**
* When DAG is actually running on server, a unique ID is assigned.
*/
- insanceId : DS.attr('string'),
+ instanceId : DS.attr('string'),
name : DS.attr('string'),
stage : DS.attr('string'),
vertices : DS.hasMany('App.TezDagVertex'),
@@ -32,7 +33,7 @@ App.TezDag = DS.Model.extend({
App.TezDagEdge = DS.Model.extend({
id : DS.attr('string'),
- insanceId : DS.attr('string'),
+ instanceId : DS.attr('string'),
fromVertex : DS.belongsTo('App.TezDagVertex'),
toVertex : DS.belongsTo('App.TezDagVertex'),
/**
@@ -47,7 +48,7 @@ App.TezDagVertex = DS.Model.extend({
/**
* When DAG vertex is actually running on server, a unique ID is assigned.
*/
- insanceId : DS.attr('string'),
+ instanceId : DS.attr('string'),
name : DS.attr('string'),
/**
@@ -88,8 +89,10 @@ App.TezDagVertex = DS.Model.extend({
* Each Tez vertex can perform arbitrary application specific computations
* inside. The application can provide a list of operations it has provided in
* this vertex.
+ *
+ * Array of strings. [{string}]
*/
- operations : DS.hasMany('string'),
+ operations : [],
/**
* Provides additional information about the 'operations' performed in this
@@ -122,7 +125,20 @@ App.TezDagVertex = DS.Model.extend({
* Record metrics for this vertex
*/
recordReadCount : DS.attr('number'),
- recordWriteCount : DS.attr('number')
+ recordWriteCount : DS.attr('number'),
+
+ totalReadBytesDisplay : function() {
+ return numberUtils.bytesToSize(this.get('fileReadBytes') + this.get('hdfsReadBytes'));
+ }.property('fileReadBytes', 'hdfsReadBytes'),
+
+ totalWriteBytesDisplay : function() {
+ return numberUtils.bytesToSize(this.get('fileWriteBytes') + this.get('hdfsWriteBytes'));
+ }.property('fileWriteBytes', 'hdfsWriteBytes'),
+
+ durationDisplay : function() {
+ var duration = this.get('duration');
+ return dateUtils.timingFormat(duration, true);
+ }.property('duration')
});
App.TezDagVertexState = {
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/routes/main.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js
index e6a4a99..487514d 100644
--- a/ambari-web/app/routes/main.js
+++ b/ambari-web/app/routes/main.js
@@ -18,6 +18,7 @@
var App = require('app');
var stringUtils = require('utils/string_utils');
+var jobsUtils = require('utils/jobs');
module.exports = Em.Route.extend({
route: '/main',
@@ -111,17 +112,34 @@ module.exports = Em.Route.extend({
}
}),
- jobs: Em.Route.extend({
- route: '/jobs',
- connectOutlets: function (router) {
- if (!App.get('isHadoop2Stack')) {
- Em.run.next(function () {
- router.transitionTo('main.dashboard');
- });
- } else {
- router.get('mainJobsController').loadJobs();
- router.get('mainController').connectOutlet('mainJobs');
+ jobs : Em.Route.extend({
+ route : '/jobs',
+ index: Ember.Route.extend({
+ route: '/',
+ connectOutlets : function(router) {
+ if (!App.get('isHadoop2Stack')) {
+ Em.run.next(function() {
+ router.transitionTo('main.dashboard');
+ });
+ } else {
+ router.get('mainJobsController').loadJobs();
+ router.get('mainController').connectOutlet('mainJobs');
+ }
}
+ }),
+ jobDetails : Em.Route.extend({
+ route : '/:job_id',
+ connectOutlets : function(router, job) {
+ if (job) {
+ jobsUtils.refreshJobDetails(job);
+ if (job.get('jobType') === App.JobType.HIVE) {
+ router.get('mainController').connectOutlet('mainHiveJobDetails', job);
+ }
+ }
+ },
+ }),
+ showJobDetails : function(router, event) {
+ router.transitionTo('jobDetails', event.context);
}
}),
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index 77b5d48..48c8776 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -5341,3 +5341,32 @@ i.icon-asterisks {
background-color: #848484;
color: #FFF;
}
+
+#hive-job-details {
+ .sections {
+ margin-top: 10px;
+ }
+ #tez-vertices-table-section {
+ display: block;
+ }
+ #tez-vertices-table-container {
+ max-height: 400px;
+ overflow-y: auto;
+ }
+ #tez-vertex-details-section-body {
+ table {
+ margin-bottom: 5px;
+ }
+ td {
+ border-top: none;
+ }
+ tr td:first-child {
+ font-weight: bold;
+ width: 20%
+ }
+ textarea {
+ width: 95%;
+ margin-left: 10px;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/templates/main/jobs.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/jobs.hbs b/ambari-web/app/templates/main/jobs.hbs
index e73adf1..d51034d 100644
--- a/ambari-web/app/templates/main/jobs.hbs
+++ b/ambari-web/app/templates/main/jobs.hbs
@@ -53,8 +53,8 @@
{{else}}
{{#each job in content}}
<tr>
- <td width="40%">
- {{job.name}}
+ <td>
+ <a title="{{unbound job.name}}" href="#" {{action "showJobDetails" job}}>{{unbound job.name}}</a>
</td>
<td>
{{job.user}}
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/templates/main/jobs/hive_job_details.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/jobs/hive_job_details.hbs b/ambari-web/app/templates/main/jobs/hive_job_details.hbs
new file mode 100644
index 0000000..bd5d6ce
--- /dev/null
+++ b/ambari-web/app/templates/main/jobs/hive_job_details.hbs
@@ -0,0 +1,107 @@
+{{!
+* 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.
+}}
+
+<div id="hive-job-details">
+ <!-- Top Bar -->
+ <div class="top-bar">
+ <a {{action "routeToJobs" target="controller"}} href="#">{{t menu.item.jobs}}</a> > {{view.content.name}}
+ <div class="pull-right">Job Type: <span class="label label-info">{{view.content.jobType}}</span></div>
+ </div>
+
+ <!-- Sections -->
+ <div class="row-fluid">
+ <div class="span12 sections">
+ <!-- Section LHS -->
+ <div class="span6 sections-lhs">
+ </div>
+
+ <!-- Section RHS -->
+ <div class="span6 sections-rhs">
+
+ <!-- Section RHS Vertices -->
+ <div id="tez-vertices-table-section">
+ <div id="tez-vertices-table-container" class="section">
+ <table class="table table-hover table-bordered table-striped">
+ <thead>
+ <tr>
+ <th>{{t common.name}}</th>
+ <th>{{t common.tasks}}</th>
+ <th>{{t apps.item.dag.input}}</th>
+ <th>{{t apps.item.dag.output}}</th>
+ <th>{{t apps.item.dag.duration}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#each vertex in view.content.tezDag.vertices}}
+ <tr {{bindAttr class="vertex.isSelected:info"}}>
+ <td>
+ <a title="{{vertex.name}}" href="#" {{action "doSelectVertex" vertex target="view"}}>{{vertex.name}}</a>
+ </td>
+ <td>{{vertex.tasksCount}}</td>
+ <td>{{vertex.totalReadBytesDisplay}}</td>
+ <td>{{vertex.totalWriteBytesDisplay}}</td>
+ <td>{{vertex.durationDisplay}}</td>
+ </tr>
+ {{/each}}
+ </tbody>
+ </table>
+ </div>
+ </div>
+
+ <!-- Section RHS Vertex -->
+ {{#if view.selectedVertex}}
+ <div id="section tez-vertex-details-section">
+ <div class="box">
+ <div class="box-header">
+ <h4>{{view.selectedVertex.name}}</h4>
+ </div>
+ <div id="tez-vertex-details-section-body">
+ <table class="table">
+ <tr>
+ <td>{{t jobs.hive.tez.tasks}}</td>
+ <td>{{view.selectedVertex.tasksCount}}</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>{{t jobs.hive.tez.hdfs}}</td>
+ <td>{{view.selectedVertexIODisplay.hdfs.read.ops}} / {{view.selectedVertexIODisplay.hdfs.read.bytes}}</td>
+ <td>{{view.selectedVertexIODisplay.hdfs.write.ops}} / {{view.selectedVertexIODisplay.hdfs.write.bytes}}</td>
+ </tr>
+ <tr>
+ <td>{{t jobs.hive.tez.localFiles}}</td>
+ <td>{{view.selectedVertexIODisplay.file.read.ops}} / {{view.selectedVertexIODisplay.file.read.bytes}}</td>
+ <td>{{view.selectedVertexIODisplay.file.write.ops}} / {{view.selectedVertexIODisplay.file.write.bytes}}</td>
+ </tr>
+ <tr>
+ <td>{{t jobs.hive.tez.records}}</td>
+ <td>{{view.selectedVertexIODisplay.records.read}}</td>
+ <td>{{view.selectedVertexIODisplay.records.write}}</td>
+ </tr>
+ <td>{{t jobs.hive.tez.operatorPlan}}</td>
+ <td></td>
+ <td></td>
+ </tr>
+ </table>
+ {{view Ember.TextArea valueBinding="view.selectedVertex.operationPlan" rows="15"}}
+ </div>
+ </div>
+ {{/if}}
+ </div>
+ </div>
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/utils/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax.js b/ambari-web/app/utils/ajax.js
index 6188371..f08e317 100644
--- a/ambari-web/app/utils/ajax.js
+++ b/ambari-web/app/utils/ajax.js
@@ -1577,11 +1577,11 @@ var urls = {
'mock': '/data/jobs/tezDag-name-to-id.json'
},
'jobs.tezDag.tezDagId': {
- 'real': '/proxy?url=http://{historyServerHostName}:8188/ws/v1/apptimeline/TEZ_DAG_ID/{tezDagId}',
+ 'real': '/proxy?url=http://{historyServerHostName}:8188/ws/v1/apptimeline/TEZ_DAG_ID/{tezDagId}?fields=relatedentities',
'mock': '/data/jobs/tezDag.json'
},
'jobs.tezDag.tezDagVertexId': {
- 'real': '/proxy?url=http://{historyServerHostName}:8188/ws/v1/apptimeline/TEZ_VERTEX_ID/{tezDagVertexId}',
+ 'real': '/proxy?url=http://{historyServerHostName}:8188/ws/v1/apptimeline/TEZ_VERTEX_ID/{tezDagVertexId}?fields=otherinfo',
'mock': '/data/jobs/tezDagVertex.json'
}
};
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/utils/jobs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/jobs.js b/ambari-web/app/utils/jobs.js
index 1cb6283..c63975f 100644
--- a/ambari-web/app/utils/jobs.js
+++ b/ambari-web/app/utils/jobs.js
@@ -49,7 +49,7 @@ module.exports = {
var hiveJobId = hiveJob.get('id');
// First refresh query
var hiveQueriesUrl = App.testMode ? "/data/jobs/hive-query-2.json" :
- App.apiPrefix + "/proxy?url=http://"+historyServerHostName+":8188/ws/v1/apptimeline/HIVE_QUERY_ID/" + hiveJob.get('id');
+ App.apiPrefix + "/proxy?url=http://"+historyServerHostName+":8188/ws/v1/apptimeline/HIVE_QUERY_ID/" + hiveJob.get('id')+"?fields=otherinfo";
App.HttpClient.get(hiveQueriesUrl, App.hiveJobMapper, {
complete : function(jqXHR, textStatus) {
// Now get the Tez DAG ID from the DAG name
@@ -145,6 +145,16 @@ module.exports = {
vertexRecord.set('tasksCount', data.otherinfo.numTasks);
vertexRecord.set('state', data.otherinfo.status);
// TODO Need additional vertex metrics
+ vertexRecord.set('fileReadBytes', 0);
+ vertexRecord.set('fileReadOps', 0);
+ vertexRecord.set('fileWriteOps', 0);
+ vertexRecord.set('fileWriteBytes', 0);
+ vertexRecord.set('hdfsReadOps', 0);
+ vertexRecord.set('hdfsReadBytes', 0);
+ vertexRecord.set('hdfsWriteOps', 0);
+ vertexRecord.set('hdfsWriteBytes', 0);
+ vertexRecord.set('recordReadCount', 0);
+ vertexRecord.set('recordWriteCount', 0);
}
}
},
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 697005c..8d6d86a 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -212,6 +212,7 @@ require('views/main/charts/heatmap/heatmap_host');
require('views/main/charts/heatmap/heatmap_host_detail');
require('views/main/apps_view');
require('views/main/jobs_view');
+require('views/main/jobs/hive_job_details_view');
require('views/main/apps/item_view');
require('views/main/apps/item/bar_view');
require('views/main/apps/item/dag_view');
http://git-wip-us.apache.org/repos/asf/ambari/blob/5d4959c8/ambari-web/app/views/main/jobs/hive_job_details_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/jobs/hive_job_details_view.js b/ambari-web/app/views/main/jobs/hive_job_details_view.js
new file mode 100644
index 0000000..7e2f280
--- /dev/null
+++ b/ambari-web/app/views/main/jobs/hive_job_details_view.js
@@ -0,0 +1,114 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var date = require('utils/date');
+var numberUtils = require('utils/number_utils');
+
+App.MainHiveJobDetailsView = Em.View.extend({
+ templateName : require('templates/main/jobs/hive_job_details'),
+
+ selectedVertex : null,
+
+ content : function() {
+ return this.get('controller.content');
+ }.property('controller.content'),
+
+ jobObserver : function() {
+ var content = this.get('content');
+ var selectedVertex = this.get('selectedVertex');
+ if (selectedVertex == null && content != null) {
+ var vertices = content.get('tezDag.vertices');
+ if (vertices) {
+ vertices.setEach('isSelected', false);
+ this.doSelectVertex({context:vertices.objectAt(0)});
+ }
+ }
+ }.observes('selectedVertex', 'content.tezDag.vertices.@each.id'),
+
+ doSelectVertex : function(event) {
+ var newVertex = event.context;
+ var currentVertex = this.get('selectedVertex');
+ if (currentVertex != null) {
+ currentVertex.set('isSelected', false);
+ }
+ newVertex.set('isSelected', true);
+ this.set('selectedVertex', newVertex);
+ },
+
+ /**
+ * Provides display information for vertex I/O.
+ *
+ * {
+ * 'file': {
+ * 'read': {
+ * 'ops': '100 reads',
+ * 'bytes': '10 MB'
+ * }
+ * 'write: {
+ * 'ops': '200 writes',
+ * 'bytes': '20 MB'
+ * }
+ * },
+ * 'hdfs': {
+ * 'read': {
+ * 'ops': '100 reads',
+ * 'bytes': '10 MB'
+ * }
+ * 'write: {
+ * 'ops': '200 writes',
+ * 'bytes': '20 MB'
+ * }
+ * },
+ * 'records': {
+ * 'read': '100 records',
+ * 'write': '123 records'
+ * }
+ * }
+ */
+ selectedVertexIODisplay : function() {
+ var v = this.get('selectedVertex');
+ return {
+ file : {
+ read : {
+ ops : Em.I18n.t('jobs.hive.tez.reads').format(v.get('fileReadOps')),
+ bytes : numberUtils.bytesToSize(v.get('fileReadBytes'))
+ },
+ write : {
+ ops : Em.I18n.t('jobs.hive.tez.writes').format(v.get('fileWriteOps')),
+ bytes : numberUtils.bytesToSize(v.get('fileWriteBytes'))
+ }
+ },
+ hdfs : {
+ read : {
+ ops : Em.I18n.t('jobs.hive.tez.reads').format(v.get('hdfsReadOps')),
+ bytes : numberUtils.bytesToSize(v.get('hdfsReadBytes'))
+ },
+ write : {
+ ops : Em.I18n.t('jobs.hive.tez.writes').format(v.get('hdfsWriteOps')),
+ bytes : numberUtils.bytesToSize(v.get('hdfsWriteBytes'))
+ }
+ },
+ records : {
+ read : Em.I18n.t('jobs.hive.tez.records.count').format(v.get('recordReadCount')),
+ write : Em.I18n.t('jobs.hive.tez.records.count').format(v.get('recordWriteCount')),
+ }
+ };
+ }.property('selectedVertex.fileReadOps', 'selectedVertex.fileWriteOps', 'selectedVertex.hdfsReadOps', 'selectedVertex.hdfdWriteOps',
+ 'selectedVertex.fileReadBytes', 'selectedVertex.fileWriteBytes', 'selectedVertex.hdfsReadBytes', 'selectedVertex.hdfdWriteBytes',
+ 'selectedVertex.recordReadCount', 'selectedVertes.recordWriteCount')
+});