You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2017/02/21 16:39:36 UTC

[05/25] ambari git commit: AMBARI-20076. Hive View 2: Results of one query reflected in other (pallavkul)

AMBARI-20076. Hive View 2: Results of one query reflected in other (pallavkul)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/316d33a9
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/316d33a9
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/316d33a9

Branch: refs/heads/branch-feature-AMBARI-12556
Commit: 316d33a9b7f95610dc2f603c3140e1dda695ed04
Parents: fad8f27
Author: pallavkul <pa...@gmail.com>
Authored: Mon Feb 20 14:30:52 2017 +0530
Committer: pallavkul <pa...@gmail.com>
Committed: Mon Feb 20 14:30:52 2017 +0530

----------------------------------------------------------------------
 .../src/main/resources/ui/app/adapters/query.js |   6 +-
 .../ui/app/components/query-result-table.js     |   8 +-
 .../resources/ui/app/configs/result-tabs.js     |  48 ++
 .../main/resources/ui/app/models/worksheet.js   |   8 +-
 .../hive20/src/main/resources/ui/app/router.js  |   6 +-
 .../resources/ui/app/routes/queries/query.js    | 450 ++++++++++---------
 .../ui/app/routes/queries/query/loading.js      |  24 +
 .../ui/app/routes/queries/query/log.js          | 104 +++++
 .../ui/app/routes/queries/query/results.js      |  59 +++
 .../ui/app/routes/queries/query/tez-ui.js       |  45 ++
 .../app/routes/queries/query/visual-explain.js  |  56 +++
 .../src/main/resources/ui/app/services/query.js |   4 +-
 .../templates/components/query-result-table.hbs |  20 +-
 .../app/templates/components/visual-explain.hbs |   1 -
 .../ui/app/templates/queries/query.hbs          |  64 +--
 .../ui/app/templates/queries/query/loading.hbs  |  21 +
 .../ui/app/templates/queries/query/log.hbs      |  29 ++
 .../ui/app/templates/queries/query/results.hbs  |  49 ++
 .../ui/app/templates/queries/query/tez-ui.hbs   |  19 +
 .../templates/queries/query/visual-explain.hbs  |  33 ++
 .../src/main/resources/ui/config/environment.js |   2 +-
 21 files changed, 743 insertions(+), 313 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/adapters/query.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/adapters/query.js b/contrib/views/hive20/src/main/resources/ui/app/adapters/query.js
index e519e64..f878230 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/adapters/query.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/adapters/query.js
@@ -29,13 +29,13 @@ export default ApplicationAdapter.extend({
     let postURL = this.buildURL();
     return this.ajax(postURL , 'POST', { data: {job: payload} });
   },
-  getJob(jobId, dateSubmitted, firstCall){
+  getJob(jobId, firstCall){
 
     let url = '';
     if(firstCall){
-      url = this.buildURL() + jobId + '/results?first=true&_='+ dateSubmitted;
+      url = this.buildURL() + jobId + '/results?first=true';
     }else {
-      url = this.buildURL() + jobId + '/results?_='+ dateSubmitted;
+      url = this.buildURL() + jobId + '/results';
     }
 
     return this.ajax(url, 'GET')

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/components/query-result-table.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/components/query-result-table.js b/contrib/views/hive20/src/main/resources/ui/app/components/query-result-table.js
index 0373f72..ea6dbc9 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/components/query-result-table.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/components/query-result-table.js
@@ -82,11 +82,11 @@ export default Ember.Component.extend({
     onColumnClick(column) {
       //console.log('I am in onColumnClick');
     },
-    goNextPage(){
-      this.sendAction('goNextPage');
+    goNextPage(payloadTitle){
+      this.sendAction('goNextPage', payloadTitle);
     },
-    goPrevPage(){
-      this.sendAction('goPrevPage');
+    goPrevPage(payloadTitle){
+      this.sendAction('goPrevPage', payloadTitle);
     },
     expandQueryResultPanel(){
       this.sendAction('expandQueryResultPanel');

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/configs/result-tabs.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/configs/result-tabs.js b/contrib/views/hive20/src/main/resources/ui/app/configs/result-tabs.js
new file mode 100644
index 0000000..f48dcd8
--- /dev/null
+++ b/contrib/views/hive20/src/main/resources/ui/app/configs/result-tabs.js
@@ -0,0 +1,48 @@
+/**
+ * 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';
+
+let resultsTabs = [
+  Ember.Object.create({
+    name: 'results',
+    label: 'RESULTS',
+    link: 'queries.query.results',
+    faIcon: 'paper-plane'
+  }),
+  Ember.Object.create({
+    name: 'log',
+    label: 'LOG',
+    link: 'queries.query.log',
+    faIcon: 'paper-plane'
+  }),
+  Ember.Object.create({
+    name: 'visual-explain',
+    label: 'VISUAL EXPLAIN',
+    link: 'queries.query.visual-explain',
+    faIcon: 'paper-plane'
+  }),
+  Ember.Object.create({
+    name: 'tez-ui',
+    label: 'TEZ UI',
+    link: 'queries.query.tez-ui',
+    faIcon: 'paper-plane'
+  })
+];
+
+export default resultsTabs;

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/models/worksheet.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/models/worksheet.js b/contrib/views/hive20/src/main/resources/ui/app/models/worksheet.js
index 1787cc7..4b3e1f9 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/models/worksheet.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/models/worksheet.js
@@ -30,13 +30,15 @@ export default DS.Model.extend({
   selected: DS.attr('boolean', {transient: true, defaultValue: false}),
   jobData: DS.attr({defaultValue: []}),
   currentJobData: DS.attr({defaultValue: null}),
-  hidePreviousButton: DS.attr('boolean', { defaultValue: true}),
+  hasNext: DS.attr('boolean', { defaultValue: false}),
+  hasPrevious: DS.attr('boolean', { defaultValue: false}),
   selectedTablesModels: DS.attr(),
   selectedMultiDb: DS.attr(),
   queryFile: DS.attr('string', {defaultValue: ""}),
   logFile: DS.attr('string', {defaultValue: ""}),
   logResults: DS.attr('string', {defaultValue: ""}),
   isQueryRunning: DS.attr('boolean', {defaultValue: false}),
-  isQueryResultContainer: DS.attr('boolean', {defaultValue: false})
-
+  isQueryResultContainer: DS.attr('boolean', {defaultValue: false}),
+  visualExplainJson: DS.attr({defaultValue: null}),
+  lastResultRoute: DS.attr({defaultValue: ""})
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/router.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/router.js b/contrib/views/hive20/src/main/resources/ui/app/router.js
index ffb0f83..250f945 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/router.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/router.js
@@ -66,7 +66,11 @@ Router.map(function() {
   this.route('queries', function() {
     this.route('new');
     this.route('query', {path: '/:worksheetId'}, function() {
-
+      this.route('results');
+      this.route('log');
+      this.route('visual-explain');
+      this.route('tez-ui');
+      this.route('loading');
     });
   });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query.js b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query.js
index 88202ff..04bb1da 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query.js
@@ -17,17 +17,19 @@
  */
 
 import Ember from 'ember';
+import tabs from '../../configs/result-tabs';
+import UILoggerMixin from '../../mixins/ui-logger';
 
-export default Ember.Route.extend({
-
+export default Ember.Route.extend(UILoggerMixin, {
   query: Ember.inject.service(),
   jobs: Ember.inject.service(),
   savedQueries: Ember.inject.service(),
-
   isQueryEdidorPaneExpanded: false,
   isQueryResultPanelExpanded: false,
+  globalSettings: '',
 
-  beforeModel(){
+  beforeModel(params){
+    console.log('worksheetId', params.params['queries.query'].worksheetId);
     let existingWorksheets = this.store.peekAll('worksheet');
     existingWorksheets.setEach('selected', false);
   },
@@ -48,17 +50,36 @@ export default Ember.Route.extend({
         };
         fileResourceList.push(localFileResource);
       });
-
       this.controller.set('fileResourceList', fileResourceList);
+    });
 
+    this.store.findAll('setting').then((data) => {
+      let localStr = '';
+      data.forEach(x => {
+        localStr = localStr + 'set '+ x.get('key')+ '='+ x.get('value') + '\n';
+      });
+      this.set('globalSettings', localStr);
     });
 
+    //lastResultRoute
+    console.log('lastResultRoute:: ', model.get('lastResultRoute'));
+    let lastResultRoute = model.get('lastResultRoute');
 
+    if(Ember.isEmpty(lastResultRoute)){
+      if(model.get('jobData').length > 0){
+        this.transitionTo('queries.query.results');
+      } else {
+        this.transitionTo('queries.query');
+      }
+    } else {
+      this.transitionTo('queries.query' + lastResultRoute);
+    }
 
   },
 
   model(params) {
     let selectedWs = this.store.peekAll('worksheet').filterBy('title', params.worksheetId).get('firstObject');
+
     if(selectedWs) {
       selectedWs.set('selected', true);
       return selectedWs;
@@ -71,13 +92,8 @@ export default Ember.Route.extend({
 
     this._super(...arguments);
 
-    controller.set('showWorksheetModal',false);
-    controller.set('worksheetModalSuccess',false);
-    controller.set('worksheetModalFail',false);
-
     let self = this;
     let alldatabases = this.store.findAll('database');
-
     controller.set('alldatabases',alldatabases);
 
     let selecteDBName = model.get('selectedDb');
@@ -96,14 +112,14 @@ export default Ember.Route.extend({
     selectedMultiDb.pushObject(selecteDBName);
 
     controller.set('worksheet', model);
-    controller.set('selectedTablesModels',model.get('selectedTablesModels') || selectedTablesModels );
 
+    controller.set('selectedTablesModels',model.get('selectedTablesModels') || selectedTablesModels );
     controller.set('selectedMultiDb', model.get('selectedMultiDb') || selectedMultiDb);
+
     controller.set('isQueryRunning', model.get('isQueryRunning'));
     controller.set('currentQuery', model.get('query'));
-    controller.set('queryResult', model.get('queryResult'));
     controller.set('currentJobId', null);
-
+    controller.set('queryResult', model.get('queryResult'));
     controller.set('isJobSuccess', false);
 
     controller.set('isExportResultSuccessMessege', false);
@@ -111,24 +127,36 @@ export default Ember.Route.extend({
     controller.set('showSaveHdfsModal', false);
 
     controller.set('logResults', model.get('logResults') || '');
-    controller.set('showQueryEditorLog', false);
-    controller.set('showQueryEditorResult', !controller.get('showQueryEditorLog'));
 
     controller.set('isVisualExplainQuery', false);
-    controller.set('visualExplainJson', null);
+    controller.set('visualExplainJson', model.get('visualExplainJson'));
 
-  },
+    controller.set('showWorksheetModal',false);
+    controller.set('worksheetModalSuccess',false);
+    controller.set('worksheetModalFail',false);
 
+    controller.set('tabs', tabs);
+
+  },
 
   actions: {
-    createQuery(udfName, udfClassname, fileResourceName, fileResourcePath){
-      let query = "add jar "+ fileResourcePath + ";\ncreate temporary function " + udfName + " as '"+ udfClassname+ "';";
-      this.get('controller').set('currentQuery', query);
-      this.get('controller.model').set('query', query );
+
+    resetDefaultWorksheet(){
+      this.get('controller.model').set('queryResult',{'schema' :[], 'rows' :[]});
+      this.get('controller.model').set('currentPage',0);
+      this.get('controller.model').set('previousPage',-1);
+      this.get('controller.model').set('nextPage',1);
+      //this.get('controller.model').set('selected',false);
+      this.get('controller.model').set('jobData',[]);
+      this.get('controller.model').set('currentJobData',null);
+      this.get('controller.model').set('queryFile',"");
+      this.get('controller.model').set('logFile',"");
+      this.get('controller.model').set('logResults',"");
+      this.get('controller.model').set('isQueryRunning',false);
+      this.get('controller.model').set('isQueryResultContainer',false);
     },
 
     changeDbHandler(selectedDBs){
-
       let self = this;
       let selectedTablesModels =[];
       let selectedMultiDb = [];
@@ -142,7 +170,6 @@ export default Ember.Route.extend({
           }
         )
         selectedMultiDb.pushObject(db);
-
       });
 
       this.get('controller').set('selectedTablesModels', selectedTablesModels );
@@ -150,7 +177,6 @@ export default Ember.Route.extend({
 
       this.get('controller').set('selectedMultiDb', selectedMultiDb );
       this.get('controller.model').set('selectedMultiDb', selectedMultiDb );
-
     },
 
     showQueryResultContainer(){
@@ -159,8 +185,7 @@ export default Ember.Route.extend({
 
     showTables(db){
       let self = this;
-      //should we do this by writing a seperate component.
-      $('#' + db).toggle();
+      Ember.$('#' + db).toggle();
       this.get('controller.model').set('selectedDb', db);
     },
 
@@ -169,51 +194,63 @@ export default Ember.Route.extend({
       this.send('executeQuery');
     },
 
-    executeQuery(isFirstCall){
+    updateQuery(query){
+      this.get('controller').set('currentQuery', query);
+      this.get('controller.model').set('query', query);
+    },
+
+    executeQuery(){
 
       let self = this;
       this.get('controller').set('currentJobId', null);
 
-      //let queryInput = this.get('controller').get('currentQuery');
       let isVisualExplainQuery = this.get('controller').get('isVisualExplainQuery');
-      let queryInput =  (isVisualExplainQuery) ? 'explain formatted ' + this.get('controller').get('currentQuery') : this.get('controller').get('currentQuery') ;
 
+      let queryInput = this.get('controller').get('currentQuery');
+
+      if (isVisualExplainQuery) {
+        queryInput = "";
+        let queries = this.get('controller').get('currentQuery').split(";").filter(function (query) {
+          if (query && query.trim()) return true;
+        });
+
+        for (let i = 0; i < queries.length; i++) {
+          if (i == queries.length - 1) {
+            if(queries[i].toLowerCase().startsWith("explain formatted ")){
+              queryInput += queries[i] + ";";
+            } else{
+              queryInput += "explain formatted " + queries[i] + ";";
+            }
+          } else {
+            queryInput += queries[i] + ";";
+          }
+        }
+      }
 
       this.get('controller.model').set('query', queryInput);
 
       let dbid = this.get('controller.model').get('selectedDb');
       let worksheetTitle = this.get('controller.model').get('title');
 
-      self.get('controller.model').set('jobData', []);
-      self.get('controller.model').set('isQueryRunning', true);
+      this.get('controller.model').set('jobData', []);
+      this.get('controller.model').set('isQueryRunning', true);
+
+      this.get('controller').set('queryResult', self.get('controller').get('queryResult'));
+      this.get('controller.model').set('queryResult', self.get('controller').get('queryResult'));
 
-      //Making the result set emply every time query runs.
-      self.get('controller').set('queryResult', self.get('controller').get('queryResult'));
-      self.get('controller.model').set('queryResult', self.get('controller').get('queryResult'));
+      let globalSettings = this.get('globalSettings');
 
-      self.send('showQueryResultContainer');
+      this.send('showQueryResultContainer');
 
       let payload ={
         "title":worksheetTitle,
-        "hiveQueryId":null,
-        "queryFile":null,
-        "owner":null,
         "dataBase":dbid,
-        "status":null,
-        "statusMessage":null,
-        "dateSubmitted":null,
         "forcedContent":queryInput,
-        "logFile":null,
-        "dagName":null,
-        "dagId":null,
-        "sessionTag":null,
-        "statusDir":null,
         "referrer":"job",
-        "confFile":null,
-        "globalSettings":""};
+        "globalSettings":globalSettings};
 
-      this.get('query').createJob(payload).then(function(data) {
 
+      this.get('query').createJob(payload).then(function(data) {
         self.get('controller.model').set('currentJobData', data);
         self.get('controller.model').set('queryFile', data.job.queryFile);
         self.get('controller.model').set('logFile', data.job.logFile);
@@ -221,116 +258,81 @@ export default Ember.Route.extend({
 
         self.get('jobs').waitForJobToComplete(data.job.id, 2 * 1000, false)
           .then((status) => {
-
-              self.get('controller').set('isJobSuccess', true);
-
-              self.send('getJob', data);
-
-              //Last log
-              self.send('fetchLogs');
-
+            self.get('controller').set('isJobSuccess', true);
+            self.send('getJobResult', data, payload.title);
           }, (error) => {
-            Ember.run.later(() => {
-              // TODO: handle error
-            }, 2 * 1000);
+            console.log('error', error);
+            self.get('logger').danger('Failed to execute query.', self.extractError(error));
+            self.send('resetDefaultWorksheet');
           });
 
-        self.send('getLogsTillJobSuccess', data.job.id);
-
-      }, function(reason) {
-        console.log(reason);
+      }, function(error) {
+        console.log(error);
+        self.get('logger').danger('Failed to execute query.', self.extractError(error));
+        self.send('resetDefaultWorksheet');
       });
     },
 
-    getLogsTillJobSuccess(jobId){
+    getJobResult(data, payloadTitle){
       let self = this;
-      this.get('jobs').waitForJobStatus(jobId)
-        .then((status) => {
-          console.log('status', status);
-          if(status !== "succeeded"){
-            self.send('fetchLogs');
-            Ember.run.later(() => {
-              self.send('getLogsTillJobSuccess',jobId )
-            }, 5 * 1000);
-          } else {
-            self.send('fetchLogs');
-          }
-        }, (error) => {
-          console.log('error',error);
-        });
-    },
-
-    fetchLogs(){
-      let self = this;
-
-      let logFile = this.get('controller.model').get('logFile');
-      this.get('query').retrieveQueryLog(logFile).then(function(data) {
-        self.get('controller.model').set('logResults', data.file.fileContent);
-      }, function(error){
-        console.log('error', error);
-      });
-    },
-
-    showVisualExplain(){
-       let self = this;
-       let jobId = this.get('controller').get('currentJobId');
-       this.get('query').getVisualExplainJson(jobId).then(function(data) {
-          console.log('Successful getVisualExplainJson', data);
-
-          self.get('controller').set('visualExplainJson', data.rows[0][0]);
-
-       }, function(error){
-          console.log('error getVisualExplainJson', error);
-        });
-    },
-
-    getJob(data){
-
-      var self = this;
-      var data = data;
 
       let isVisualExplainQuery = this.get('controller').get('isVisualExplainQuery');
 
       let jobId = data.job.id;
-      let dateSubmitted = data.job.dateSubmitted;
 
       let currentPage = this.get('controller.model').get('currentPage');
       let previousPage = this.get('controller.model').get('previousPage');
       let nextPage = this.get('controller.model').get('nextPage');
 
-      this.get('query').getJob(jobId, dateSubmitted, true).then(function(data) {
-        // on fulfillment
-        console.log('getJob route', data );
+      this.get('query').getJob(jobId, true).then(function(data) {
+
+        let existingWorksheets = self.get('store').peekAll('worksheet');
+        let myWs = null;
+        if(existingWorksheets.get('length') > 0) {
+          myWs = existingWorksheets.filterBy('title', payloadTitle).get('firstObject');
+        }
 
-        self.get('controller').set('queryResult', data);
-        self.get('controller.model').set('queryResult', data);
-        self.get('controller.model').set('isQueryRunning', false);
+        myWs.set('queryResult', data);
+        myWs.set('isQueryRunning', false);
+        myWs.set('hasNext', data.hasNext);
 
-        let localArr = self.get('controller.model').get("jobData");
+        let localArr = myWs.get("jobData");
         localArr.push(data);
-        self.get('controller.model').set('jobData', localArr);
-        self.get('controller.model').set('currentPage', currentPage+1);
-        self.get('controller.model').set('previousPage', previousPage + 1 );
-        self.get('controller.model').set('nextPage', nextPage + 1);
+        myWs.set('jobData', localArr);
+        myWs.set('currentPage', currentPage+1);
+        myWs.set('previousPage', previousPage + 1 );
+        myWs.set('nextPage', nextPage + 1);
 
         if(isVisualExplainQuery){
-          Ember.run.later(() => {
-            self.send('showVisualExplain');
-          }, 500);
+          self.send('showVisualExplain', payloadTitle);
         }
 
-      }, function(reason) {
-        // on rejection
-        console.log('reason' , reason);
+        if( self.paramsFor('queries.query').worksheetId == payloadTitle){
+          self.transitionTo('queries.query.results');
+        }
+
+      }, function(error) {
+        console.log('error' , error);
       });
     },
 
-    updateQuery(query){
-      this.get('controller').set('currentQuery', query);
-      this.get('controller.model').set('query', query);
+    showVisualExplain(payloadTitle){
+       let self = this;
+       let jobId = this.get('controller').get('currentJobId');
+       this.get('query').getVisualExplainJson(jobId).then(function(data) {
+          console.log('Successful getVisualExplainJson', data);
+          self.get('controller.model').set('visualExplainJson', data.rows[0][0]);
+
+          if( self.paramsFor('queries.query').worksheetId == payloadTitle){
+           self.transitionTo('queries.query.visual-explain');
+          }
+
+        }, function(error){
+          console.log('error getVisualExplainJson', error);
+        });
     },
 
-    goNextPage(){
+    goNextPage(payloadTitle){
 
       let currentPage = this.get('controller.model').get('currentPage');
       let previousPage = this.get('controller.model').get('previousPage');
@@ -341,15 +343,12 @@ export default Ember.Route.extend({
         var self = this;
         var data = this.get('controller.model').get('currentJobData');
         let jobId = data.job.id;
-        let dateSubmitted = data.job.dateSubmitted;
 
-        this.get('query').getJob(jobId, dateSubmitted, false).then(function(data) {
-          // on fulfillment
-          console.log('getJob route', data );
-          self.get('controller').set('queryResult', data);
+        this.get('query').getJob(jobId, false).then(function(data) {
           self.get('controller.model').set('queryResult', data);
           self.get('controller.model').set('isQueryRunning', false);
-          self.get('controller.model').set('hidePreviousButton', false);
+          self.get('controller.model').set('hasNext', data.hasNext);
+          self.get('controller.model').set('hasPrevious', true);
 
           let localArr = self.get('controller.model').get("jobData");
           localArr.push(data);
@@ -358,21 +357,33 @@ export default Ember.Route.extend({
           self.get('controller.model').set('currentPage', currentPage+1);
           self.get('controller.model').set('previousPage', previousPage + 1 );
           self.get('controller.model').set('nextPage', nextPage + 1);
-        }, function(reason) {
-          // on rejection
-          console.log('reason' , reason);
+        }, function(error) {
+            console.log('error' , error);
         });
-      } else { //Pages from cache object
+      } else {
+        //Pages from cache object
         this.get('controller.model').set('currentPage', currentPage+1);
         this.get('controller.model').set('previousPage', previousPage + 1 );
         this.get('controller.model').set('nextPage', nextPage + 1);
-        this.get('controller.model').set('hidePreviousButton', false);
-        this.get('controller').set('queryResult', this.get('controller.model').get("jobData")[this.get('controller.model').get('currentPage')-1] );
+        this.get('controller.model').set('hasNext', this.get('controller.model').get('jobData')[this.get('controller.model').get('currentPage')-1].hasNext);
+        this.get('controller.model').set('hasPrevious', (this.get('controller.model').get('currentPage') > 1) ? true : false );
         this.get('controller.model').set('queryResult', this.get('controller.model').get("jobData")[this.get('controller.model').get('currentPage')-1] );
       }
+
+      let existingWorksheets = this.get('store').peekAll('worksheet');
+      let myWs = null;
+      if(existingWorksheets.get('length') > 0) {
+        myWs = existingWorksheets.filterBy('title', payloadTitle).get('firstObject');
+      }
+
+      this.transitionTo('queries.query.loading');
+
+      Ember.run.later(() => {
+        this.transitionTo('queries.query.results', myWs);
+      }, 1 * 1000);
     },
 
-    goPrevPage(){
+    goPrevPage(payloadTitle){
       let currentPage = this.get('controller.model').get('currentPage');
       let previousPage = this.get('controller.model').get('previousPage');
       let nextPage = this.get('controller.model').get('nextPage');
@@ -382,64 +393,25 @@ export default Ember.Route.extend({
         this.get('controller.model').set('currentPage', currentPage-1 );
         this.get('controller.model').set('previousPage', previousPage - 1 );
         this.get('controller.model').set('nextPage', nextPage-1);
-
         this.get('controller').set('queryResult', this.get('controller.model').get("jobData")[this.get('controller.model').get('currentPage') -1 ]);
         this.get('controller.model').set('queryResult', this.get('controller.model').get("jobData")[this.get('controller.model').get('currentPage') -1 ]);
-      } else {
-        this.get('controller.model').set('hidePreviousButton', true);
+        this.get('controller.model').set('hasNext', true);
+        this.get('controller.model').set('hasPrevious', (this.get('controller.model').get('currentPage') > 1) ? true : false );
       }
-    },
-
-    expandQueryEdidorPanel(){
 
-      if(!this.get('isQueryEdidorPaneExpanded')){
-        this.set('isQueryEdidorPaneExpanded', true);
-      } else {
-        this.set('isQueryEdidorPaneExpanded', false);
+      let existingWorksheets = this.get('store').peekAll('worksheet');
+      let myWs = null;
+      if(existingWorksheets.get('length') > 0) {
+        myWs = existingWorksheets.filterBy('title', payloadTitle).get('firstObject');
       }
-      Ember.$('.query-editor-panel').toggleClass('query-editor-full-width');
-      Ember.$('.database-panel').toggleClass("hide");
-
-    },
-
-    expandQueryResultPanel(){
-
-      if(!this.get('isQueryResultPanelExpanded')){
-
-        if(!this.get('isQueryEdidorPaneExpanded')){
-          Ember.$('.query-editor-container').addClass("hide");
-          Ember.$('.database-panel').addClass("hide");
-          Ember.$('.query-editor-panel').addClass('query-editor-full-width');
-        } else {
-
-          Ember.$('.query-editor-container').addClass("hide");
-        }
-        this.set('isQueryResultPanelExpanded', true);
-
-      } else {
 
-        if(!this.get('isQueryEdidorPaneExpanded')){
-          Ember.$('.query-editor-container').removeClass("hide");
-          Ember.$('.database-panel').removeClass("hide");
-          Ember.$('.query-editor-panel').removeClass('query-editor-full-width');
-        } else {
+      this.transitionTo('queries.query.loading');
 
-          Ember.$('.query-editor-container').removeClass("hide");
+      Ember.run.later(() => {
+        this.transitionTo('queries.query.results', myWs);
+      }, 1 * 1000);
 
-        }
-        this.set('isQueryResultPanelExpanded', false);
-
-      }
-
-    },
 
-    adjustPanelSize(){
-      let isFullHeight = ($(window).height() ==(parseInt(Ember.$('.ember-light-table').css('height'), 10)) ) || false;
-      if(!isFullHeight){
-        Ember.$('.ember-light-table').css('height', '100vh');
-      }else {
-        Ember.$('.ember-light-table').css('height', '70vh');
-      }
     },
 
     openWorksheetModal(){
@@ -463,22 +435,27 @@ export default Ember.Route.extend({
         "queryFile" : queryFile,
         "logFile" : logFile};
 
-      this.get('savedQueries').saveQuery(payload)
-        .then((data) => {
-          console.log('Created saved query.', data);
-          this.get('controller.model').set('title', newTitle);
-          this.get('controller').set('worksheetModalSuccess', true);
+      let newSaveQuery = this.get('store').createRecord('saved-query',
+        { dataBase:selectedDb,
+          title:newTitle,
+          queryFile: queryFile,
+          owner: owner,
+          shortQuery: (currentQuery.length > 0) ? currentQuery : ";"
+        });
 
-          Ember.run.later(() => {
-            this.get('controller').set('showWorksheetModal', false);
-          }, 2 * 1000);
 
-        }, (error) => {
-          console.log("Error encountered", error);
-          Ember.run.later(() => {
-            this.get('controller').set('worksheetModalFail', true);
-          }, 2 * 1000);
-        });
+      newSaveQuery.save().then((data) => {
+        console.log('saved query saved');
+
+        this.get('controller.model').set('title', newTitle);
+        this.get('controller').set('worksheetModalSuccess', true);
+
+        Ember.run.later(() => {
+          this.get('controller').set('showWorksheetModal', false);
+        }, 2 * 1000);
+
+      });
+
     },
 
     closeWorksheetModal(){
@@ -524,29 +501,54 @@ export default Ember.Route.extend({
 
     },
 
-    showQueryEditorLog(){
-      this.get('controller').set('showQueryEditorLog', true);
-      this.get('controller').set('showQueryEditorResult', false);
+    expandQueryEdidorPanel(){
+      if(!this.get('isQueryEdidorPaneExpanded')){
+        this.set('isQueryEdidorPaneExpanded', true);
+      } else {
+        this.set('isQueryEdidorPaneExpanded', false);
+      }
+      Ember.$('.query-editor-panel').toggleClass('query-editor-full-width');
+      Ember.$('.database-panel').toggleClass("hide");
+    },
+
+    expandQueryResultPanel(){
+      if(!this.get('isQueryResultPanelExpanded')){
+        if(!this.get('isQueryEdidorPaneExpanded')){
+          Ember.$('.query-editor-container').addClass("hide");
+          Ember.$('.database-panel').addClass("hide");
+          Ember.$('.query-editor-panel').addClass('query-editor-full-width');
+        } else {
 
-      $('.log-list-anchor').addClass('active');
-      $('.log-list').addClass('active');
-      $('.editor-result-list-anchor').removeClass('active');
-      $('.editor-result-list').removeClass('active');
+          Ember.$('.query-editor-container').addClass("hide");
+        }
+        this.set('isQueryResultPanelExpanded', true);
+      } else {
+        if(!this.get('isQueryEdidorPaneExpanded')){
+          Ember.$('.query-editor-container').removeClass("hide");
+          Ember.$('.database-panel').removeClass("hide");
+          Ember.$('.query-editor-panel').removeClass('query-editor-full-width');
+        } else {
+          Ember.$('.query-editor-container').removeClass("hide");
+        }
+        this.set('isQueryResultPanelExpanded', false);
+      }
     },
 
-    showQueryEditorResult(){
-      this.get('controller').set('showQueryEditorLog', false);
-      this.get('controller').set('showQueryEditorResult', true);
+    adjustPanelSize(){
+      let isFullHeight = ($(window).height() ==(parseInt(Ember.$('.ember-light-table').css('height'), 10)) ) || false;
+      if(!isFullHeight){
+        Ember.$('.ember-light-table').css('height', '100vh');
+      }else {
+        Ember.$('.ember-light-table').css('height', '70vh');
+      }
+    },
 
-      $('.log-list-anchor').removeClass('active');
-      $('.log-list').removeClass('active');
-      $('.editor-result-list-anchor').addClass('active');
-      $('.editor-result-list').addClass('active');
+    createQuery(udfName, udfClassname, fileResourceName, fileResourcePath){
+      let query = "add jar "+ fileResourcePath + ";\ncreate temporary function " + udfName + " as '"+ udfClassname+ "';";
+      this.get('controller').set('currentQuery', query);
+      this.get('controller.model').set('query', query );
     }
-  },
 
-  showQueryResultContainer(){
-    this.get('controller.model').set('isQueryResultContainer', true);
   }
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/loading.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/loading.js b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/loading.js
new file mode 100644
index 0000000..b5070bc
--- /dev/null
+++ b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/loading.js
@@ -0,0 +1,24 @@
+/**
+ * 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 default Ember.Route.extend({
+  beforeModel() {
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/log.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/log.js b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/log.js
new file mode 100644
index 0000000..52f8dcc
--- /dev/null
+++ b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/log.js
@@ -0,0 +1,104 @@
+/**
+ * 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 default Ember.Route.extend({
+
+  jobs: Ember.inject.service(),
+  query: Ember.inject.service(),
+
+  model(){
+    return this.modelFor('queries.query');
+  },
+
+  getLogsTillJobSuccess(jobId, model, controller){
+    let self = this;
+    this.get('jobs').waitForJobStatus(jobId)
+      .then((status) => {
+        console.log('status', status);
+        if(status !== "succeeded"){
+
+          self.fetchLogs(model).then((logFileContent) => {
+            controller.set('logResults', logFileContent );
+          }, (error) => {
+            console.log('error',error);
+          });
+
+          Ember.run.later(() => {
+            self.getLogsTillJobSuccess(jobId, model, controller);
+          }, 5 * 1000);
+
+        } else {
+
+          self.fetchLogs(model).then((logFileContent) => {
+            controller.set('logResults', logFileContent );
+          }, (error) => {
+            console.log('error',error);
+          });
+
+        }
+      }, (error) => {
+        console.log('error',error);
+      });
+  },
+
+  fetchLogs(model){
+    let logFile = model.get('logFile');
+    return new Promise( (resolve, reject) => {
+      this.get('query').retrieveQueryLog(logFile).then(function(data) {
+        resolve(data.file.fileContent);
+      }, function(error){
+        reject(error);
+      });
+    });
+  },
+
+  jobStatus(jobId){
+    return new Promise( (resolve, reject) => {
+      this.get('jobs').waitForJobStatus(jobId).then(function(status) {
+        resolve(status);
+      }, function(error){
+        reject(error);
+      });
+    });
+
+  },
+
+  setupController(controller, model){
+    this._super(...arguments);
+
+    model.set('lastResultRoute', ".log");
+
+    if(!Ember.isEmpty(model.get('currentJobData'))){
+      let jobId = model.get('currentJobData').job.id;
+      this.controller.set('jobId', jobId);
+      this.controller.set('logResults', model.get('logResults'));
+      this.getLogsTillJobSuccess(jobId, model, controller);
+      this.controller.set('hasJobAssociated', true);
+
+    } else {
+      this.controller.set('hasJobAssociated', false);
+    }
+  },
+
+  actions:{
+
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/results.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/results.js b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/results.js
new file mode 100644
index 0000000..4b59a13
--- /dev/null
+++ b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/results.js
@@ -0,0 +1,59 @@
+/**
+ * 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 default Ember.Route.extend({
+
+  jobs: Ember.inject.service(),
+  query: Ember.inject.service(),
+
+  beforeModel() {
+  },
+
+  model(){
+    return this.modelFor('queries.query');
+  },
+
+  setupController(controller, model){
+    this._super(...arguments);
+
+    model.set('lastResultRoute', ".results");
+
+    if(!Ember.isEmpty(model.get('currentJobData'))){
+
+      let jobId = model.get('currentJobData').job.id;
+      this.controller.set('jobId', jobId);
+      this.controller.set('payloadTitle',  model.get('currentJobData').job.title);
+      this.controller.set('isQueryRunning', model.get('isQueryRunning'));
+      this.controller.set('previousPage', model.get('previousPage'));
+      this.controller.set('hasNext', model.get('hasNext'));
+      this.controller.set('hasPrevious', model.get('hasPrevious'));
+      this.controller.set('queryResult', model.get('queryResult'));
+      this.controller.set('hasJobAssociated', true);
+    } else {
+      this.controller.set('hasJobAssociated', false);
+    }
+
+  },
+
+  actions:{
+
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/tez-ui.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/tez-ui.js b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/tez-ui.js
new file mode 100644
index 0000000..daf142b
--- /dev/null
+++ b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/tez-ui.js
@@ -0,0 +1,45 @@
+/**
+ * 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 default Ember.Route.extend({
+
+  jobs: Ember.inject.service(),
+  query: Ember.inject.service(),
+
+  beforeModel() {
+  },
+
+  model(){
+    return this.modelFor('queries.query');
+  },
+
+  setupController(controller, model){
+    this._super(...arguments);
+
+    model.set('lastResultRoute', ".tez-ui");
+
+
+  },
+
+  actions:{
+
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/visual-explain.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/visual-explain.js b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/visual-explain.js
new file mode 100644
index 0000000..ff3832d
--- /dev/null
+++ b/contrib/views/hive20/src/main/resources/ui/app/routes/queries/query/visual-explain.js
@@ -0,0 +1,56 @@
+/**
+ * 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 default Ember.Route.extend({
+
+  jobs: Ember.inject.service(),
+  query: Ember.inject.service(),
+
+  beforeModel() {
+  },
+
+  model(){
+    return this.modelFor('queries.query');
+  },
+
+  setupController(controller, model){
+    this._super(...arguments);
+
+    model.set('lastResultRoute', ".visual-explain");
+
+    if(!Ember.isEmpty(model.get('currentJobData'))){
+
+      let jobId = model.get('currentJobData').job.id;
+      this.controller.set('jobId', jobId);
+      this.controller.set('payloadTitle',  model.get('currentJobData').job.title);
+      this.controller.set('isQueryRunning', model.get('isQueryRunning'));
+      this.controller.set('visualExplainJson', model.get('visualExplainJson'));
+
+      this.controller.set('hasJobAssociated', true);
+    } else {
+      this.controller.set('hasJobAssociated', false);
+    }
+  },
+
+  actions:{
+
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/services/query.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/services/query.js b/contrib/views/hive20/src/main/resources/ui/app/services/query.js
index 42d4fb0..3bf10c0 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/services/query.js
+++ b/contrib/views/hive20/src/main/resources/ui/app/services/query.js
@@ -31,10 +31,10 @@ export default Ember.Service.extend({
       });
     });
   },
-  getJob(jobId, dateSubmitted, firstCall){
+  getJob(jobId, firstCall){
     let self = this;
     return new Promise( (resolve, reject) => {
-      this.get('store').adapterFor('query').getJob(jobId, dateSubmitted, firstCall).then(function(data) {
+      this.get('store').adapterFor('query').getJob(jobId, firstCall).then(function(data) {
         resolve(data);
       }, function(err) {
           reject(err);

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/templates/components/query-result-table.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/components/query-result-table.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/components/query-result-table.hbs
index 4d8524e..2590796 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/components/query-result-table.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/components/query-result-table.hbs
@@ -16,17 +16,6 @@
 * limitations under the License.
 }}
 
-
-
-{{#if isQueryRunning}}
-   <div style="position:relative">
-       <div style="margin: auto;position: absolute;top: 0;left: 0;bottom: 0;right: 0;text-align: center">
-         {{fa-icon "spinner fa-2" spin=true}}
-       </div>
-    </div>
-{{/if}}
-
-{{#unless isQueryRunning}}
   <div class="clearfix" style="text-align: right; padding-right:5px">
     <span class="dropdown">
       <button class="btn btn-default dropdown-toggle" title="Actions" data-toggle="dropdown">{{fa-icon "bars"}} </button>
@@ -36,9 +25,10 @@
       </ul>
     </span>&nbsp;
 
-    <button class="btn btn-default" title="Previous Page" {{action "goPrevPage" }}  >{{fa-icon "arrow-left"}} </button>
-    <button class="btn btn-default" title="Next Page" {{action "goNextPage" }}>{{fa-icon "arrow-right"}} </button> &nbsp;
+    <button class="btn btn-default" title="Previous Page" {{action "goPrevPage" payloadTitle }} disabled={{not hasPrevious}} >{{fa-icon "arrow-left"}} </button>
+    <button class="btn btn-default" title="Next Page" {{action "goNextPage" payloadTitle}} disabled={{not hasNext}} >{{fa-icon "arrow-right"}} </button> &nbsp;
     <button class="btn btn-default" title="Expand/Collspse" {{action "expandQueryResultPanel" }}>{{fa-icon "expand"}}</button>
+
   </div>
 
   <div class="clearfix">
@@ -66,10 +56,6 @@
     {{/light-table}}
   </div>
 
-
-{{/unless}}
-
-
 {{#if showSaveHdfsModal}}
   {{export-result
   confirmText="OK"

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/templates/components/visual-explain.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/components/visual-explain.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/components/visual-explain.hbs
index e0ceaa2..905e73c 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/components/visual-explain.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/components/visual-explain.hbs
@@ -29,7 +29,6 @@
   </div>
 {{/if}}
 
-
 {{#unless isQueryRunning}}
   <div id="explain-container" ></div>
 {{/unless}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query.hbs
index 5b2b5c2..d62c781 100644
--- a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query.hbs
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query.hbs
@@ -43,69 +43,19 @@
             </ul>
         </div>
         <button class="btn btn-default" {{action "visualExplainQuery" }}>{{fa-icon "link"}} Visual Explain</button>
+
         {{#if worksheet.isQueryRunning}}
           {{fa-icon "spinner fa-1-5" spin=true}}
         {{/if}}
+
       </div>
     </div>
 
-    {{#if worksheet.isQueryResultContainer}}
-      <div class="query-result-container">
-        <div>
-          <ul class="row nav nav-tabs inverse">
-            <li class="editor-result-list active">
-              <a href="javascript:void(0)" class="editor-result-list-anchor active" {{action 'showQueryEditorResult' }}>
-                {{fa-icon "file-text-o"}}&nbsp;&nbsp;RESULT
-              </a>
-            </li>
-            <li class="log-list">
-              <a href="javascript:void(0)" class="log-list-anchor" {{action 'showQueryEditorLog' }}>
-                {{fa-icon "list"}}&nbsp;&nbsp;LOG
-              </a>
-            </li>
-          </ul>
-        </div>
+    {{#tabs-pane tabs=tabs inverse=true as |tab|}}
+      {{tabs-item tab=tab tabs=tabs}}
+    {{/tabs-pane}}
 
-        {{#if showQueryEditorLog}}
-          <div class="clearfix row query-editor-log">
-            {{query-result-log logResults=worksheet.logResults }}
-          </div>
-        {{/if}}
-        {{#if showQueryEditorResult}}
-          <div class="clearfix row query-editor-results">
-
-            {{#if isVisualExplainQuery}}
-                {{visual-explain
-                expandQueryResultPanel='expandQueryResultPanel'
-                isQueryRunning=worksheet.isQueryRunning
-                visualExplainJson=visualExplainJson
-                }}
-              {{else}}
-              {{query-result-table
-              queryResult=queryResult
-              jobId=currentJobId
-              updateQuery='updateQuery'
-              previousPage=worksheet.previousPage
-              hidePreviousButton=hidePreviousButton
-              goNextPage='goNextPage'
-              goPrevPage='goPrevPage'
-              expandQueryResultPanel='expandQueryResultPanel'
-              saveToHDFS='saveToHDFS'
-              downloadAsCsv='downloadAsCsv'
-              isExportResultSuccessMessege=isExportResultSuccessMessege
-              isExportResultFailureMessege=isExportResultFailureMessege
-              showSaveHdfsModal=showSaveHdfsModal
-              isQueryRunning=worksheet.isQueryRunning
-              }}
-            {{/if}}
-
-
-
-          </div>
-        {{/if}}
-
-      </div>
-    {{/if}}
+    {{outlet}}
   </div>
 </div>
 
@@ -181,4 +131,4 @@
   {{/modal-dialog}}
 {{/if}}
 
-{{outlet}}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/loading.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/loading.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/loading.hbs
new file mode 100644
index 0000000..b1de181
--- /dev/null
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/loading.hbs
@@ -0,0 +1,21 @@
+{{!
+* 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 class="alert alert-info text-center">
+  <p class="lead">Data Loading... Please wait. {{fa-icon "refresh" spin=true}}</p>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs
new file mode 100644
index 0000000..db1cea2
--- /dev/null
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/log.hbs
@@ -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.
+}}
+
+{{#unless hasJobAssociated}}
+  <div>No Log avaiable.</div>
+{{/unless}}
+
+{{#if hasJobAssociated}}
+  <div>
+    <pre class="prettyprint">{{logResults}}</pre>
+  </div>
+
+{{/if}}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs
new file mode 100644
index 0000000..370e3ef
--- /dev/null
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/results.hbs
@@ -0,0 +1,49 @@
+{{!
+* 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.
+}}
+
+{{outlet}}
+
+{{#unless hasJobAssociated}}
+  <div>No Results avaiable.</div>
+{{/unless}}
+
+{{#if hasJobAssociated}}
+  {{query-result-table
+  queryResult=queryResult
+  isQueryRunning=isQueryRunning
+  jobId=jobId
+  payloadTitle=payloadTitle
+  previousPage=previousPage
+  hasNext=hasNext
+  hasPrevious=hasPrevious
+  updateQuery='updateQuery'
+  goNextPage='goNextPage'
+  goPrevPage='goPrevPage'
+  saveToHDFS='saveToHDFS'
+  downloadAsCsv='downloadAsCsv'
+  expandQueryResultPanel='expandQueryResultPanel'
+  isExportResultSuccessMessege=false
+  isExportResultFailureMessege=false
+  showSaveHdfsModal=false
+  }}
+{{/if}}
+
+
+
+
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/tez-ui.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/tez-ui.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/tez-ui.hbs
new file mode 100644
index 0000000..9dfa3fa
--- /dev/null
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/tez-ui.hbs
@@ -0,0 +1,19 @@
+{{!
+* 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>I am in tez-ui route.</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs
new file mode 100644
index 0000000..ef441b5
--- /dev/null
+++ b/contrib/views/hive20/src/main/resources/ui/app/templates/queries/query/visual-explain.hbs
@@ -0,0 +1,33 @@
+{{!
+* 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.
+}}
+
+{{outlet}}
+
+{{#unless hasJobAssociated}}
+  <div>No Visual Explain avaiable.</div>
+{{/unless}}
+
+{{#if hasJobAssociated}}
+  {{#if visualExplainJson}}
+    {{visual-explain
+    expandQueryResultPanel='expandQueryResultPanel'
+    visualExplainJson=visualExplainJson
+    isQueryRunning=isQueryRunning
+    }}
+  {{/if}}
+{{/if}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/316d33a9/contrib/views/hive20/src/main/resources/ui/config/environment.js
----------------------------------------------------------------------
diff --git a/contrib/views/hive20/src/main/resources/ui/config/environment.js b/contrib/views/hive20/src/main/resources/ui/config/environment.js
index 411ee99..c891508 100644
--- a/contrib/views/hive20/src/main/resources/ui/config/environment.js
+++ b/contrib/views/hive20/src/main/resources/ui/config/environment.js
@@ -34,7 +34,7 @@ module.exports = function(environment) {
     APP: {
       // Here you can pass flags/options to your application instance
       // when it is created
-      SHOULD_PERFORM_SERVICE_CHECK: true
+      SHOULD_PERFORM_SERVICE_CHECK: false
     }
   };