AMBARI-11864. Hive View Enhancements (Erik Bergenholtz via rlevas)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ebf56d06 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ebf56d06 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ebf56d06 Branch: refs/heads/branch-2.1 Commit: ebf56d0600f5619a2d4b8b25176a857b35844e91 Parents: f334f09 Author: Erik Bergenholtz <[email protected]> Authored: Thu Jun 11 16:24:51 2015 -0400 Committer: Robert Levas <[email protected]> Committed: Thu Jun 11 16:24:51 2015 -0400 ---------------------------------------------------------------------- contrib/views/hive/pom.xml | 2 +- .../hive/resources/jobs/atsJobs/ATSParser.java | 34 +-- .../hive/resources/jobs/rm/RMParserFactory.java | 52 +---- .../view/hive/resources/jobs/viewJobs/Job.java | 4 + .../hive/resources/jobs/viewJobs/JobImpl.java | 11 + .../src/main/resources/ui/hive-web/Brocfile.js | 3 + .../ui/hive-web/app/adapters/application.js | 4 +- .../ui/hive-web/app/components/job-tr-view.js | 41 ++++ .../ui/hive-web/app/components/modal-widget.js | 6 +- .../ui/hive-web/app/components/navbar-widget.js | 39 ++++ .../ui/hive-web/app/components/notify-widget.js | 1 - .../ui/hive-web/app/controllers/application.js | 26 +++ .../ui/hive-web/app/controllers/columns.js | 104 --------- .../ui/hive-web/app/controllers/databases.js | 210 ++++++----------- .../hive-web/app/controllers/file-resources.js | 22 -- .../ui/hive-web/app/controllers/history.js | 43 ++-- .../ui/hive-web/app/controllers/index.js | 97 ++++---- .../controllers/index/history-query/explain.js | 36 +-- .../app/controllers/index/history-query/logs.js | 91 ++++---- .../ui/hive-web/app/controllers/insert-udfs.js | 2 +- .../ui/hive-web/app/controllers/job-progress.js | 133 +++++++---- .../ui/hive-web/app/controllers/job.js | 48 ---- .../ui/hive-web/app/controllers/loaded-files.js | 65 ------ .../ui/hive-web/app/controllers/messages.js | 14 +- .../ui/hive-web/app/controllers/open-queries.js | 43 ++-- .../ui/hive-web/app/controllers/query-tabs.js | 13 +- .../ui/hive-web/app/controllers/settings.js | 42 +++- .../ui/hive-web/app/controllers/tables.js | 93 -------- .../ui/hive-web/app/controllers/tez-ui.js | 2 +- .../ui/hive-web/app/controllers/udf.js | 6 - .../ui/hive-web/app/controllers/udfs.js | 27 +-- .../hive-web/app/controllers/visual-explain.js | 6 +- .../ui/hive-web/app/initializers/i18n.js | 22 +- .../ui/hive-web/app/initializers/notify.js | 26 --- .../ui/hive-web/app/routes/application.js | 16 +- .../resources/ui/hive-web/app/routes/history.js | 10 +- .../resources/ui/hive-web/app/routes/queries.js | 8 +- .../resources/ui/hive-web/app/routes/udfs.js | 12 +- .../ui/hive-web/app/services/database.js | 227 +++++++++++++++++++ .../resources/ui/hive-web/app/services/file.js | 59 +++++ .../resources/ui/hive-web/app/services/job.js | 41 ++++ .../ui/hive-web/app/services/notify.js | 18 +- .../resources/ui/hive-web/app/styles/app.scss | 39 +++- .../ui/hive-web/app/templates/application.hbs | 4 +- .../templates/components/_typeahead-widget.hbs | 17 -- .../app/templates/components/job-tr-view.hbs | 49 ++++ .../app/templates/components/navbar-widget.hbs | 45 ++++ .../templates/components/typeahead-widget.hbs | 17 -- .../hive-web/app/templates/databases-tree.hbs | 2 +- .../ui/hive-web/app/templates/databases.hbs | 4 +- .../ui/hive-web/app/templates/history.hbs | 48 ++-- .../ui/hive-web/app/templates/index.hbs | 32 ++- .../ui/hive-web/app/templates/insert-udfs.hbs | 2 +- .../ui/hive-web/app/templates/navbar.hbs | 45 ---- .../ui/hive-web/app/templates/queries.hbs | 78 ++++--- .../ui/hive-web/app/templates/query-tabs.hbs | 2 +- .../ui/hive-web/app/templates/udfs.hbs | 6 +- .../ui/hive-web/app/utils/constants.js | 5 +- .../ui/hive-web/app/utils/functions.js | 4 +- .../resources/ui/hive-web/app/views/history.js | 25 -- .../ui/hive-web/app/views/insert-udfs.js | 23 -- .../resources/ui/hive-web/app/views/navbar.js | 38 ---- .../ui/hive-web/app/views/visual-explain.js | 23 +- .../src/main/resources/ui/hive-web/bower.json | 4 +- .../src/main/resources/ui/hive-web/package.json | 7 +- .../src/main/resources/ui/hive-web/testem.json | 1 - .../ui/hive-web/tests/helpers/api-mock.js | 51 ++++- .../ui/hive-web/tests/helpers/start-app.js | 2 +- .../hive-web/tests/integration/database-test.js | 4 +- .../tests/integration/query-editor-test.js | 50 ++-- .../hive-web/tests/integration/tez-ui-test.js | 49 ++++ .../hive-web/tests/unit/adapters/application.js | 2 +- .../unit/components/collapsible-widget-test.js | 4 +- .../components/column-filter-widget-test.js | 2 +- .../unit/components/date-range-widget-test.js | 6 +- .../unit/components/expander-widget-test.js | 5 +- .../unit/components/extended-input-test.js | 12 +- .../tests/unit/components/job-tr-view-test.js | 62 +++++ .../tests/unit/components/modal-widget-test.js | 69 ++++++ .../tests/unit/components/no-bubbling-test.js | 3 +- .../unit/components/number-range-widget-test.js | 4 +- .../unit/components/popover-widget-test.js | 6 +- .../unit/components/progress-widget-test.js | 27 +-- .../tests/unit/components/query-editor-test.js | 8 +- .../tests/unit/components/select-widget-test.js | 6 +- .../tests/unit/components/tabs-wiget-test.js | 2 +- .../unit/components/typeahead-widget-test.js | 3 +- .../hive-web/tests/unit/controllers/columns.js | 32 --- .../tests/unit/controllers/databases-test.js | 56 +++-- .../tests/unit/controllers/history-test.js | 2 +- .../tests/unit/controllers/index-test.js | 26 +-- .../tests/unit/controllers/insert-udfs-test.js | 2 +- .../hive-web/tests/unit/controllers/job-test.js | 62 ----- .../tests/unit/controllers/messages-test.js | 53 +++++ .../tests/unit/controllers/open-queries-test.js | 9 +- .../tests/unit/controllers/settings-test.js | 119 +++++----- .../hive-web/tests/unit/controllers/tables.js | 32 --- .../tests/unit/controllers/tez-ui-test.js | 83 ++++++- .../hive-web/tests/unit/controllers/udf-test.js | 4 +- .../tests/unit/controllers/udfs-test.js | 4 +- .../unit/controllers/visual-explain-test.js | 33 --- .../hive-web/tests/unit/services/notify-test.js | 4 +- .../tests/unit/views/visual-explain-test.js | 84 ++++++- contrib/views/hive/src/main/resources/view.xml | 2 +- .../main/resources/ui/pig-web/vendor/emacs.js | 18 ++ 105 files changed, 1799 insertions(+), 1482 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/pom.xml ---------------------------------------------------------------------- diff --git a/contrib/views/hive/pom.xml b/contrib/views/hive/pom.xml index 8a8ace9..2130c4a 100644 --- a/contrib/views/hive/pom.xml +++ b/contrib/views/hive/pom.xml @@ -19,7 +19,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>org.apache.ambari.contrib.views</groupId> <artifactId>hive</artifactId> - <version>0.4.0-SNAPSHOT</version> + <version>1.0.0-SNAPSHOT</version> <name>Hive</name> <parent> http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSParser.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSParser.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSParser.java index 7482921..1138767 100644 --- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSParser.java +++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/atsJobs/ATSParser.java @@ -131,24 +131,26 @@ public class ATSParser implements IATSParser { parsedJob.duration = lastEventTimestamp - parsedJob.starttime; JSONObject otherinfo = (JSONObject) job.get("otherinfo"); - JSONObject query = (JSONObject) JSONValue.parse((String) otherinfo.get("QUERY")); - - parsedJob.query = (String) query.get("queryText"); - JSONObject stages = (JSONObject) ((JSONObject) query.get("queryPlan")).get("STAGE PLANS"); - - List<String> dagIds = new LinkedList<String>(); - List<JSONObject> stagesList = new LinkedList<JSONObject>(); - - for (Object key : stages.keySet()) { - JSONObject stage = (JSONObject) stages.get(key); - if (stage.get("Tez") != null) { - String dagId = (String) ((JSONObject) stage.get("Tez")).get("DagName:"); - dagIds.add(dagId); + if (otherinfo.get("QUERY") != null) { // workaround for HIVE-10829 + JSONObject query = (JSONObject) JSONValue.parse((String) otherinfo.get("QUERY")); + + parsedJob.query = (String) query.get("queryText"); + JSONObject stages = (JSONObject) ((JSONObject) query.get("queryPlan")).get("STAGE PLANS"); + + List<String> dagIds = new LinkedList<String>(); + List<JSONObject> stagesList = new LinkedList<JSONObject>(); + + for (Object key : stages.keySet()) { + JSONObject stage = (JSONObject) stages.get(key); + if (stage.get("Tez") != null) { + String dagId = (String) ((JSONObject) stage.get("Tez")).get("DagName:"); + dagIds.add(dagId); + } + stagesList.add(stage); } - stagesList.add(stage); + parsedJob.dagNames = dagIds; + parsedJob.stages = stagesList; } - parsedJob.dagNames = dagIds; - parsedJob.stages = stagesList; return parsedJob; } http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/rm/RMParserFactory.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/rm/RMParserFactory.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/rm/RMParserFactory.java index 596d1d1..260b464 100644 --- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/rm/RMParserFactory.java +++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/rm/RMParserFactory.java @@ -28,60 +28,22 @@ public class RMParserFactory { protected final static Logger LOG = LoggerFactory.getLogger(RMParserFactory.class); - public static final String HTTPS_ONLY = "HTTPS_ONLY"; - public static final String HTTP_ONLY = "HTTP_ONLY"; - public static final String YARN_SITE = "yarn-site"; - public static final String YARN_HTTP_POLICY = "yarn.http.policy"; - - private ViewContext context; + private final ViewContext context; + private final AmbariApi ambariApi; public RMParserFactory(ViewContext context) { this.context = context; + this.ambariApi = new AmbariApi(context); } public RMParser getRMParser() { - RMRequestsDelegate delegate = new RMRequestsDelegateImpl(context, getRMUrl()); + String rmUrl = getRMUrl(); + + RMRequestsDelegate delegate = new RMRequestsDelegateImpl(context, rmUrl); return new RMParser(delegate); } public String getRMUrl() { - String url; - - AmbariApi ambariApi = new AmbariApi(context); - - if (ambariApi.isClusterAssociated()) { - String httpPolicy = ambariApi.getCluster().getConfigurationValue("yarn-site", "yarn.http.policy"); - if (httpPolicy.equals(HTTPS_ONLY)) { - url = ambariApi.getCluster().getConfigurationValue("yarn-site", "yarn.resourcemanager.webapp.https.address"); - } else { - url = ambariApi.getCluster().getConfigurationValue("yarn-site", "yarn.resourcemanager.webapp.address"); - if (!httpPolicy.equals(HTTP_ONLY)) - LOG.error(String.format("R040 Unknown value %s of yarn-site/yarn.http.policy. HTTP_ONLY assumed.", httpPolicy)); - } - - } else { - url = context.getProperties().get("yarn.resourcemanager.url"); - } - return addProtocolIfMissing(url); - } - - public String addProtocolIfMissing(String url) { - if (!url.matches("^[^:]+://.*$")) { - AmbariApi ambariApi = new AmbariApi(context); - if (!ambariApi.isClusterAssociated()) { - throw new ServiceFormattedException( - "R030 View is not cluster associated. Resource Manager URL should contain protocol."); - } - - String httpPolicy = ambariApi.getCluster().getConfigurationValue(YARN_SITE, YARN_HTTP_POLICY); - if (httpPolicy.equals(HTTPS_ONLY)) { - url = "https://" + url; - } else { - url = "http://" + url; - if (!httpPolicy.equals(HTTP_ONLY)) - LOG.error(String.format("R050 Unknown value %s of yarn-site/yarn.http.policy. HTTP_ONLY assumed.", httpPolicy)); - } - } - return url; + return ambariApi.getServices().getRMUrl(); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/Job.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/Job.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/Job.java index 44a338c..9afb21a 100644 --- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/Job.java +++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/Job.java @@ -116,4 +116,8 @@ public interface Job extends Serializable,Indexed,PersonalResource { String getReferrer(); void setReferrer(String referrer); + + String getGlobalSettings(); + + void setGlobalSettings(String globalSettings); } http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobImpl.java ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobImpl.java b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobImpl.java index ac1c3da..317b791 100644 --- a/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobImpl.java +++ b/contrib/views/hive/src/main/java/org/apache/ambari/view/hive/resources/jobs/viewJobs/JobImpl.java @@ -47,6 +47,7 @@ public class JobImpl implements Job { private String sessionTag; private String referrer; + private String globalSettings; private String id = null; private String owner = null; @@ -283,4 +284,14 @@ public class JobImpl implements Job { public void setReferrer(String referrer) { this.referrer = referrer; } + + @Override + public String getGlobalSettings() { + return globalSettings; + } + + @Override + public void setGlobalSettings(String globalSettings) { + this.globalSettings = globalSettings; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/Brocfile.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/Brocfile.js b/contrib/views/hive/src/main/resources/ui/hive-web/Brocfile.js index 8a367c9..318d1f8 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/Brocfile.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/Brocfile.js @@ -21,6 +21,9 @@ var EmberApp = require('ember-cli/lib/broccoli/ember-app'); var app = new EmberApp({ + autoprefixer: { + browsers: ['last 3 version'] + }, 'ember-cli-selectize': { //valid values are `default`, `bootstrap2`, `bootstrap3` or false 'theme': 'bootstrap3' http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/application.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/application.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/application.js index 5e7a05b..34caa8a 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/application.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/adapters/application.js @@ -22,8 +22,8 @@ import constants from 'hive/utils/constants'; export default DS.RESTAdapter.extend({ headers: { 'X-Requested-By': 'ambari', - 'Content-Type': 'application/json', - // 'Authorization': 'Basic YWRtaW46YWRtaW4=' + 'Content-Type': 'application/json' + //,'Authorization': 'Basic YWRtaW46YWRtaW4=' }, buildURL: function () { http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/components/job-tr-view.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/components/job-tr-view.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/components/job-tr-view.js new file mode 100644 index 0000000..f439ca2 --- /dev/null +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/components/job-tr-view.js @@ -0,0 +1,41 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; +import constants from 'hive/utils/constants'; +import utils from 'hive/utils/functions'; + +export default Ember.Component.extend({ + tagName: '', + + canStop: function () { + return utils.insensitiveCompare(this.get('job.status'), constants.statuses.running, constants.statuses.initialized, constants.statuses.pending); + }.property('job.status'), + + actions: { + requestFile: function () { + this.toggleProperty('expanded'); + + this.sendAction('onFileRequested', this.get('job')); + }, + + stopJob: function () { + this.sendAction('onStopJob', this.get('job')); + } + } +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/components/modal-widget.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/components/modal-widget.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/components/modal-widget.js index 5172664..ce25bf1 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/components/modal-widget.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/components/modal-widget.js @@ -20,9 +20,11 @@ import Ember from 'ember'; export default Ember.Component.extend(Ember.I18n.TranslateableProperties, { show: function () { + var self = this; + this.$('.modal').modal().on('hidden.bs.modal', function () { - this.sendAction('close'); - }.bind(this)); + self.sendAction('close'); + }); }.on('didInsertElement'), keyPress: function (e) { http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/components/navbar-widget.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/components/navbar-widget.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/components/navbar-widget.js new file mode 100644 index 0000000..c3659cf --- /dev/null +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/components/navbar-widget.js @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; +import constants from 'hive/utils/constants'; + +export default Ember.Component.extend({ + tagName: 'navigation-bar', + title: constants.appTitle, + + items: Ember.A([ + Ember.Object.create({text: 'menus.query', + path: constants.namingConventions.routes.index}), + + Ember.Object.create({text: 'menus.savedQueries', + path: constants.namingConventions.routes.queries}), + + Ember.Object.create({text: 'menus.history', + path: constants.namingConventions.routes.history}), + + Ember.Object.create({text: 'menus.udfs', + path: constants.namingConventions.routes.udfs}) + ]) +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/components/notify-widget.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/components/notify-widget.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/components/notify-widget.js index 25ae1b3..ba0f080 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/components/notify-widget.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/components/notify-widget.js @@ -18,7 +18,6 @@ import Ember from 'ember'; - export default Ember.Component.extend({ tagName: 'notifications', classNames: [ 'notifications-container' ], http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/application.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/application.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/application.js new file mode 100644 index 0000000..9a01d53 --- /dev/null +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/application.js @@ -0,0 +1,26 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; +import constants from 'hive/utils/constants'; + +export default Ember.Controller.extend({ + notifyService: Ember.inject.service(constants.namingConventions.notify), + + notifications: Ember.computed.alias('notifyService.notifications'), +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/columns.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/columns.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/columns.js deleted file mode 100644 index 38d1b95..0000000 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/columns.js +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import Ember from 'ember'; -import constants from 'hive/utils/constants'; - -export default Ember.ObjectController.extend({ - pageCount: 10, - - init: function () { - this._super(); - - var databaseAdapter = this.container.lookup('adapter:database'); - var baseUrl = databaseAdapter.buildURL() + '/' + - databaseAdapter.pathForType(constants.namingConventions.database) + '/'; - - this.set('baseUrl', baseUrl); - }, - - getColumnsPage: function (databaseName, table, searchTerm, firstSearchPage) { - var defer = Ember.RSVP.defer(); - - var url = this.get('baseUrl') + - databaseName + - '/table/' + - table.get('name'); - - url += '.page?searchId&count=' + this.get('pageCount'); - url += '&columns=3,5'; - - if (searchTerm) { - url += '&searchId=searchColumns' + '&like=' + searchTerm; - - if (firstSearchPage) { - url += '&first=true'; - } - } else if (!table.get('columns.length')) { - url += '&first=true'; - } - - Ember.$.getJSON(url).then(function (data) { - Ember.run(function () { - var columns; - - columns = data.rows.map(function (row) { - return Ember.Object.create({ - name: row[0], - type: row[1] - }); - }); - - defer.resolve({ - columns: columns, - hasNext: data.hasNext - }); - }); - }, function (err) { - defer.reject(err); - }); - - return defer.promise; - }, - - getColumns: function (databaseName, tableName) { - var defer = Ember.RSVP.defer(); - - var url = this.get('baseUrl') + - databaseName + - '/table/' + - tableName; - - Ember.$.getJSON(url).then(function (data) { - Ember.run(function () { - var columns = data.columns.map(function (column) { - return Ember.Object.create({ - name: column[0], - type: column[1] - }); - }); - - defer.resolve(columns); - }); - }, function (err) { - defer.reject(err); - }); - - return defer.promise; - } -}); http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/databases.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/databases.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/databases.js index 742657c..e6bc7f1 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/databases.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/databases.js @@ -19,48 +19,48 @@ import Ember from 'ember'; import constants from 'hive/utils/constants'; -export default Ember.ArrayController.extend({ +export default Ember.Controller.extend({ + databaseService: Ember.inject.service(constants.namingConventions.database), + notifyService: Ember.inject.service(constants.namingConventions.notify), + pageCount: 10, - needs: [ constants.namingConventions.tables, - constants.namingConventions.columns, - constants.namingConventions.openQueries ], + selectedDatabase: Ember.computed.alias('databaseService.selectedDatabase'), + databases: Ember.computed.alias('databaseService.databases'), - openQueries: Ember.computed.alias('controllers.' + constants.namingConventions.openQueries), - dbTables: Ember.computed.alias('controllers.' + constants.namingConventions.tables), - dbColumns: Ember.computed.alias('controllers.' + constants.namingConventions.columns), + tableSearchResults: Ember.Object.create(), - _handleTablesError: function (error) { - this.notify.error(error.responseJSON.message, error.responseJSON.trace); - this.set('isLoading', false); - }, + tableControls: [ + { + icon: 'fa-list', + action: 'loadSampleData', + tooltip: Ember.I18n.t('tooltips.loadSample') + } + ], - _handleColumnsError: function (error) { - this.notify.error(error.responseJSON.message, error.responseJSON.trace); - this.set('isLoading', false); - }, + panelIconActions: [ + { + icon: 'fa-refresh', + action: 'refreshDatabaseExplorer', + tooltip: Ember.I18n.t('tooltips.refresh') + } + ], + + tabs: [ + Ember.Object.create({ + name: Ember.I18n.t('titles.explorer'), + visible: true, + view: constants.namingConventions.databaseTree + }), + Ember.Object.create({ + name: Ember.I18n.t('titles.results'), + view: constants.namingConventions.databaseSearch + }) + ], - init: function () { - this._super(); - - var databaseAdapter = this.container.lookup('adapter:database'); - var baseUrl = databaseAdapter.buildURL() + '/' + - databaseAdapter.pathForType(constants.namingConventions.database) + '/'; - - this.set('baseUrl', baseUrl); - this.set('tableSearchResults', Ember.Object.create()); - - this.set('tabs', Ember.ArrayProxy.create({ content: Ember.A([ - Ember.Object.create({ - name: Ember.I18n.t('titles.explorer'), - visible: true, - view: constants.namingConventions.databaseTree - }), - Ember.Object.create({ - name: Ember.I18n.t('titles.results'), - view: constants.namingConventions.databaseSearch - }) - ])})); + _handleError: function (error) { + this.get('notifyService').error(error); + this.set('isLoading', false); }, setTablePageAvailability: function (database) { @@ -90,31 +90,14 @@ export default Ember.ArrayController.extend({ }, selectedDatabaseChanged: function () { - var self = this, - database = this.get('selectedDatabase'); - - //if no selected database or database has already fully loaded tables - if (!database || (database.tables && !database.get('hasNext'))) { - return; - } + var self = this; this.set('isLoading', true); - this.get('dbTables').getTables(database.get('name')).then(function (tables) { - var mappedTables = {}; - - //don't use Ember.Object.set since it can be very expensive for large collections (e.g. 15000 tables), - //thus we should not do any bindings directly on the 'tables' collection. - database.tables = tables; - - tables.forEach(function (table) { - mappedTables[table.name] = []; - }); - - self.set('openQueries.selectedTables', mappedTables); + this.get('databaseService').getAllTables().then(function () { self.set('isLoading', false); }, function (err) { - self._handleTablesError(err); + self._handleError(err); }); }.observes('selectedDatabase'), @@ -128,7 +111,7 @@ export default Ember.ArrayController.extend({ table.set('visibleColumns', []); } - this.get('dbColumns').getColumnsPage(database.get('name'), table).then(function (result) { + this.get('databaseService').getColumnsPage(database.get('name'), table).then(function (result) { table.columns.pushObjects(result.columns); table.get('visibleColumns').pushObjects(result.columns); table.set('hasNext', result.hasNext); @@ -136,7 +119,7 @@ export default Ember.ArrayController.extend({ self.setColumnPageAvailability(table); self.set('isLoading', false); }, function (err) { - self._handleColumnsError(err); + self._handleError(err); }); }, @@ -150,7 +133,7 @@ export default Ember.ArrayController.extend({ database.set('visibleTables', []); } - this.get('dbTables').getTablesPage(database).then(function (result) { + this.get('databaseService').getTablesPage(database).then(function (result) { database.tables.pushObjects(result.tables); database.get('visibleTables').pushObjects(result.tables); database.set('hasNext', result.hasNext); @@ -158,86 +141,26 @@ export default Ember.ArrayController.extend({ self.setTablePageAvailability(database); self.set('isLoading', false); }, function (err) { - self._handleTablesError(err); + self._handleError(err); }); }, - getAllColumns: function (tableName) { - var defer = Ember.RSVP.defer(); + getDatabases: function () { var self = this; - var database = this.get('selectedDatabase'); - var table = database.get('tables').findBy('name', tableName); - - //if all the columns were already loaded for this table, do not get them again. - if (!table || (table.columns && !table.get('hasNext'))) { - defer.resolve(); - } else { - this.set('isLoading', true); - - this.get('dbColumns').getColumns(database.get('name'), tableName).then(function (columns) { - table.columns = columns; - table.set('hasNext', false); + var selectedDatabase = this.get('selectedDatabase'); - self.get('openQueries.selectedTables')[tableName] = columns.mapProperty('name'); - self.set('isLoading', false); - - defer.resolve(); - }, function (err) { - self._handleColumnsError(err); - defer.reject(err); - }); - } - - return defer.promise; - }, + this.set('isLoading', true); - tableControls: Ember.A([ - Ember.Object.create({ - icon: 'fa-list', - action: 'loadSampleData', - tooltip: Ember.I18n.t('tooltips.loadSample') - }) - ]), - - panelIconActions: function () { - return [ - Ember.Object.create({ - icon: 'fa-refresh', - action: 'refreshDatabaseExplorer', - tooltip: Ember.I18n.t('tooltips.refresh') - }) - ]; - }.property(), + this.get('databaseService').getDatabases().then(function (databases) { + self.set('isLoading'); + }).catch(function (error) { + self._handleError(error); + }); + }.on('init'), actions: { refreshDatabaseExplorer: function () { - var self = this; - var selectedDatabase = this.get('selectedDatabase'); - - this.set('isLoading', true); - - this.store.unloadAll('database'); - this.store.fetchAll('database').then(function (databases) { - var database; - - self.set('model', databases); - - //if a database was previously selected, check if it still exists - if (selectedDatabase) { - database = databases.findBy('id', selectedDatabase.get('id')); - - if (!database) { - self.set('selectedDatabase', databases.objectAt(0)); - } - } else if (self.get('model.length')) { - self.set('selectedDatabase', databases.objectAt(0)); - } - - self.set('isLoading'); - }).catch(function (response) { - self.notify.error(response.responseJSON.message, response.responseJSON.trace); - self.set('isLoading'); - }); + this.getDatabases(); }, loadSampleData: function (tableName, database) { @@ -248,15 +171,12 @@ export default Ember.ArrayController.extend({ var query = constants.sampleDataQuery.fmt(tableName); self.set('selectedDatabase', database); - self.get('openQueries.currentQuery') - .set('fileContent', query); - - self.send('executeQuery', constants.jobReferrer.sample); + self.send('executeQuery', constants.jobReferrer.sample, query); }); }, getTables: function (dbName) { - var database = this.findBy('name', dbName), + var database = this.get('databases').findBy('name', dbName), tables = database.tables, pageCount = this.get('pageCount'); @@ -328,13 +248,13 @@ export default Ember.ArrayController.extend({ this.set('columnSearchTerm', ''); this.set('isLoading', true); - this.get('dbTables').getTablesPage(this.get('selectedDatabase'), searchTerm, true).then(function (result) { + this.get('databaseService').getTablesPage(this.get('selectedDatabase'), searchTerm, true).then(function (result) { tableSearchResults.set('tables', result.tables); tableSearchResults.set('hasNext', result.hasNext); self.set('isLoading', false); }, function (err) { - self._handleTablesError(err); + self._handleError(err); }); }, @@ -351,7 +271,7 @@ export default Ember.ArrayController.extend({ this.set('isLoading', true); tables.forEach(function (table) { - self.get('dbColumns').getColumnsPage(database.get('name'), table, searchTerm, true).then(function (result) { + self.get('databaseService').getColumnsPage(database.get('name'), table, searchTerm, true).then(function (result) { table.set('columns', result.columns); table.set('hasNext', result.hasNext); @@ -359,7 +279,7 @@ export default Ember.ArrayController.extend({ self.set('isLoading', false); } }, function (err) { - self._handleColumnsError(err); + self._handleError(err); }); }); }, @@ -372,7 +292,7 @@ export default Ember.ArrayController.extend({ this.set('isLoading', true); - this.get('dbTables').getTablesPage(database, searchTerm).then(function (tablesResult) { + this.get('databaseService').getTablesPage(database, searchTerm).then(function (tablesResult) { var tables = tableSearchResults.get('tables'); var shouldGetColumns = tables.any(function (table) { return table.get('columns.length') > 0; @@ -385,7 +305,7 @@ export default Ember.ArrayController.extend({ //load the columns search results for the newly loaded tables. if (shouldGetColumns) { tablesResult.tables.forEach(function (table) { - self.get('dbColumns').getColumnsPage(database.get('name'), table, self.get('columnSearchTerm'), true).then(function (result) { + self.get('databaseService').getColumnsPage(database.get('name'), table, self.get('columnSearchTerm'), true).then(function (result) { table.set('columns', result.columns); table.set('hasNext', result.hasNext); @@ -393,14 +313,14 @@ export default Ember.ArrayController.extend({ self.set('isLoading', false); } }, function (err) { - self._handleColumnsError(err); + self._handleError(err); }); }); } else { self.set('isLoading', false); } }, function (err) { - self._handleTablesError(err); + self._handleError(err); }); }, @@ -409,13 +329,13 @@ export default Ember.ArrayController.extend({ this.set('isLoading', true); - this.get('dbColumns').getColumnsPage(this.get('selectedDatabase.name'), table, this.get('columnSearchTerm')).then(function (result) { + this.get('databaseService').getColumnsPage(this.get('selectedDatabase.name'), table, this.get('columnSearchTerm')).then(function (result) { table.get('columns').pushObjects(result.columns); table.set('hasNext', result.hasNext); self.set('isLoading', false); }, function (err) { - self._handleColumnsError(err); + self._handleError(err); }); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/file-resources.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/file-resources.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/file-resources.js deleted file mode 100644 index 578fa67..0000000 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/file-resources.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 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.ArrayController.extend({ -}); http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/history.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/history.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/history.js index c19b131..e63362a 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/history.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/history.js @@ -21,7 +21,8 @@ import FilterableMixin from 'hive/mixins/filterable'; import constants from 'hive/utils/constants'; export default Ember.ArrayController.extend(FilterableMixin, { - itemController: constants.namingConventions.job, + jobService: Ember.inject.service('job'), + fileService: Ember.inject.service('file'), sortAscending: false, sortProperties: ['dateSubmittedTimestamp'], @@ -76,13 +77,12 @@ export default Ember.ArrayController.extend(FilterableMixin, { return column.get('caption') === 'columns.duration'; }); - minDuration = Math.min.apply(Math, this.get('history').map(function (item) { + var items = this.get('history').map(function (item) { return item.get(durationColumn.get('property')); - })); + }); - maxDuration = Math.max.apply(Math, this.get('history').map(function (item) { - return item.get(durationColumn.get('property')); - })); + minDuration = items.length ? Math.min.apply(Math, items) : 0; + maxDuration = items.length ? Math.max.apply(Math, items) : 0; durationColumn.set('numberRange.min', minDuration); durationColumn.set('numberRange.max', maxDuration); @@ -99,13 +99,12 @@ export default Ember.ArrayController.extend(FilterableMixin, { return column.get('caption') === 'columns.date'; }); - minDate = Math.min.apply(Math, this.get('history').map(function (item) { + var items = this.get('history').map(function (item) { return item.get(dateColumn.get('property')); - })); + }); - maxDate = Math.max.apply(Math, this.get('history').map(function (item) { - return item.get(dateColumn.get('property')); - })); + minDate = items.length ? Math.min.apply(Math, items) : new Date(); + maxDate = items.length ? Math.max.apply(Math, items) : new Date(); dateColumn.set('dateRange.min', minDate); dateColumn.set('dateRange.max', maxDate); @@ -136,22 +135,12 @@ export default Ember.ArrayController.extend(FilterableMixin, { }, interruptJob: function (job) { - var self = this; - var id = job.get('id'); - var url = this.container.lookup('adapter:application').buildURL(); - url += "/jobs/" + id; - - job.set('isCancelling', true); - - Ember.$.ajax({ - url: url, - type: 'DELETE', - headers: { - 'X-Requested-By': 'ambari', - }, - success: function () { - job.reload(); - } + this.get('jobService').stopJob(job); + }, + + loadFile: function (job) { + this.get('fileService').loadFile(job.get('queryFile')).then(function (file) { + job.set('file', file); }); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index.js index a31e984..ea2ed5d 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index.js @@ -1,5 +1,4 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one +/** * 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 @@ -21,8 +20,11 @@ import constants from 'hive/utils/constants'; import utils from 'hive/utils/functions'; export default Ember.Controller.extend({ + jobService: Ember.inject.service(constants.namingConventions.job), + databaseService: Ember.inject.service(constants.namingConventions.database), + notifyService: Ember.inject.service(constants.namingConventions.notify), + needs: [ constants.namingConventions.openQueries, - constants.namingConventions.databases, constants.namingConventions.udfs, constants.namingConventions.jobLogs, constants.namingConventions.jobResults, @@ -34,7 +36,6 @@ export default Ember.Controller.extend({ ], openQueries: Ember.computed.alias('controllers.' + constants.namingConventions.openQueries), - databases: Ember.computed.alias('controllers.' + constants.namingConventions.databases), udfs: Ember.computed.alias('controllers.' + constants.namingConventions.udfs + '.udfs'), logs: Ember.computed.alias('controllers.' + constants.namingConventions.jobLogs), results: Ember.computed.alias('controllers.' + constants.namingConventions.jobResults), @@ -44,6 +45,8 @@ export default Ember.Controller.extend({ tezUI: Ember.computed.alias('controllers.' + constants.namingConventions.tezUI), jobProgress: Ember.computed.alias('controllers.' + constants.namingConventions.jobProgress), + selectedDatabase: Ember.computed.alias('databaseService.selectedDatabase'), + isDatabaseExplorerVisible: true, init: function () { @@ -125,7 +128,7 @@ export default Ember.Controller.extend({ job = this.store.createRecord(constants.namingConventions.job, { title: originalModel.get('title'), sessionTag: originalModel.get('sessionTag'), - dataBase: this.get('databases.selectedDatabase.name'), + dataBase: this.get('selectedDatabase.name'), referrer: referrer }); @@ -152,9 +155,7 @@ export default Ember.Controller.extend({ if (!query) { originalModel.set('isRunning', false); defer.reject({ - responseJSON: { - message: 'Running multiple queries is not supported.' - } + message: 'Running multiple queries is not supported.' }); return defer.promise; @@ -196,6 +197,7 @@ export default Ember.Controller.extend({ openQueries = this.get('openQueries'); var handleError = function (err) { + self.set('jobSaveSucceeded'); originalModel.set('isRunning', undefined); defer.reject(err); }; @@ -203,6 +205,8 @@ export default Ember.Controller.extend({ job.save().then(function () { //convert tab for current model since the execution will create a new job, and navigate to the new job route. openQueries.convertTabToJob(originalModel, job).then(function () { + self.set('jobSaveSucceeded', true); + //reset flag on the original model originalModel.set('isRunning', undefined); @@ -258,20 +262,11 @@ export default Ember.Controller.extend({ } queries = queryComponents.queryString.split(';'); - queries = queries.map(function (s) { - return s.trim(); - }); queries = queries.filter(Boolean); - // return false if multiple queries are selected - // @FIXME: Remove this to support multiple queries - // if (queries.length > 1) { - // return false; - // } - queries = queries.map(function (query) { if (shouldExplain) { - query = query.replace(/explain|formatted/gi, '').trim(); + query = query.replace(/explain formatted|explain/gi, ''); if (shouldGetVisualExplain) { return constants.namingConventions.explainFormattedPrefix + query; @@ -279,7 +274,7 @@ export default Ember.Controller.extend({ return constants.namingConventions.explainPrefix + query; } } else { - return query.replace(/explain|formatted/gi, '').trim(); + return query.replace(/explain formatted|explain/gi, ''); } }); @@ -293,7 +288,7 @@ export default Ember.Controller.extend({ finalQuery += queries.join(";"); finalQuery += ";"; - return finalQuery; + return finalQuery.trim(); }, bindQueryParams: function (query) { @@ -312,18 +307,24 @@ export default Ember.Controller.extend({ displayJobTabs: function () { return this.get('content.constructor.typeKey') === constants.namingConventions.job && - utils.isInteger(this.get('content.id')); - }.property('content'), + utils.isInteger(this.get('content.id')) && + this.get('jobSaveSucceeded'); + }.property('content', 'jobSaveSucceeded'), + + databasesOrModelChanged: function () { + this.get('databaseService').setDatabaseByName(this.get('content.dataBase')); + }.observes('databaseService.databases', 'content'), + + selectedDatabaseChanged: function () { + this.set('content.dataBase', this.get('selectedDatabase.name')); + }.observes('selectedDatabase'), modelChanged: function () { var self = this; var content = this.get('content'); var openQueries = this.get('openQueries'); - var database = this.get('databases').findBy('name', this.get('content.dataBase')); - if (database) { - this.set('databases.selectedDatabase', database); - } + this.set('jobSaveSucceeded', true); //update open queries list when current query model changes openQueries.update(content).then(function (isExplainedQuery) { @@ -350,10 +351,6 @@ export default Ember.Controller.extend({ }); }.observes('content'), - selectedDatabaseChanged: function () { - this.set('content.dataBase', this.get('databases.selectedDatabase.name')); - }.observes('databases.selectedDatabase'), - csvUrl: function () { if (this.get('content.constructor.typeKey') !== constants.namingConventions.job) { return; @@ -425,8 +422,8 @@ export default Ember.Controller.extend({ file: file }).then(function (response) { self.pollSaveToHDFS(response); - }, function (response) { - self.notify.error(response.responseJSON.message, response.responseJSON.trace); + }, function (error) { + self.get('notifyService').error(error); }); }, @@ -442,8 +439,8 @@ export default Ember.Controller.extend({ } else { self.set('content.isRunning', false); } - }, function (response) { - self.notify.error(response.responseJSON.message, response.responseJSON.trace); + }, function (error) { + self.get('notifyService').error(error); }); }, 2000); }, @@ -461,6 +458,10 @@ export default Ember.Controller.extend({ }.property('content.status'), actions: { + stopCurrentJob: function () { + this.get('jobService').stopJob(this.get('model')); + }, + saveToHDFS: function () { var self = this, defer = Ember.RSVP.defer(); @@ -530,7 +531,7 @@ export default Ember.Controller.extend({ return function (workSheetName) { var model = this.store.createRecord(constants.namingConventions.savedQuery, { - dataBase: this.get('databases.selectedDatabase.name'), + dataBase: this.get('selectedDatabase.name'), title: workSheetName ? workSheetName : Ember.I18n.t('titles.query.tab'), queryFile: '', id: 'fixture_' + idCounter @@ -556,7 +557,7 @@ export default Ember.Controller.extend({ defer = Ember.RSVP.defer(), currentQuery = this.get('openQueries.currentQuery'); - this.set('model.dataBase', this.get('databases.selectedDatabase.name')); + this.set('model.dataBase', this.get('selectedDatabase.name')); this.send('openModal', 'modal-save-query', { heading: 'modals.save.heading', @@ -567,16 +568,19 @@ export default Ember.Controller.extend({ }); defer.promise.then(function (result) { - currentQuery.set('fileContent', self.prependQuerySettings(currentQuery.get('fileContent'))); // we need to update the original model // because when this is executed // it sets the title from the original model self.set('model.title', result.get('text')); if (result.get('overwrite')) { - self.get('openQueries').save(self.get('content'), null, true, result.get('text')); + self.get('openQueries').save(self.get('content'), null, true, result.get('text')).then(function () { + self.get('notifyService').success(Ember.I18n.t('alerts.success.query.update')); + }); } else { self.get('openQueries').save(self.get('content'), null, false, result.get('text')).then(function (newId) { + self.get('notifyService').success(Ember.I18n.t('alerts.success.query.save')); + if (self.get('model.constructor.typeKey') !== constants.namingConventions.job) { self.transitionToRoute(constants.namingConventions.subroutes.savedQuery, newId); } @@ -585,10 +589,14 @@ export default Ember.Controller.extend({ }); }, - executeQuery: function (referrer) { + executeQuery: function (referrer, query) { var self = this; var subroute; + if (query) { + this.set('openQueries.currentQuery.fileContent', query); + } + referrer = referrer || constants.jobReferrer.job; this._executeQuery(referrer).then(function (job) { @@ -599,11 +607,10 @@ export default Ember.Controller.extend({ } self.get('openQueries').updateTabSubroute(job, subroute); - + self.get('notifyService').success(Ember.I18n.t('alerts.success.query.execution')); self.transitionToRoute(constants.namingConventions.subroutes.historyQuery, job.get('id')); - }, function (err) { - var errorBody = err.responseJSON.trace ? err.responseJSON.trace : false; - self.notify.error(err.responseJSON.message, errorBody); + }, function (error) { + self.get('notifyService').error(error); }); }, @@ -614,8 +621,8 @@ export default Ember.Controller.extend({ self.get('openQueries').updateTabSubroute(job, constants.namingConventions.subroutes.jobExplain); self.transitionToRoute(constants.namingConventions.subroutes.historyQuery, job.get('id')); - }, function (err) { - self.notify.error(err.responseJSON.message, err.responseJSON.trace); + }, function (error) { + self.get('notifyService').error(error); }); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index/history-query/explain.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index/history-query/explain.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index/history-query/explain.js index 2f3e78d..20092e2 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index/history-query/explain.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index/history-query/explain.js @@ -52,27 +52,29 @@ export default Ember.ObjectController.extend({ url += '?first=true'; } - Ember.$.getJSON(url).then(function (data) { - var explainSet; + this.get('content').reload().then(function () { + Ember.$.getJSON(url).then(function (data) { + var explainSet; - //if rows from a previous page read exist, prepend them - if (rows) { - data.rows.unshiftObjects(rows); - } + //if rows from a previous page read exist, prepend them + if (rows) { + data.rows.unshiftObjects(rows); + } - if (!data.hasNext) { - explainSet = self.get('cachedExplains').pushObject(Ember.Object.create({ - id: self.get('content.id'), - explain: data - })); + if (!data.hasNext) { + explainSet = self.get('cachedExplains').pushObject(Ember.Object.create({ + id: self.get('content.id'), + explain: data + })); - self.set('content.explain', explainSet); + self.set('content.explain', explainSet); - self.formatExplainResults(explainSet); - } else { - self.getExplain(false, data.rows); - } - }); + self.formatExplainResults(explainSet); + } else { + self.getExplain(false, data.rows); + } + }); + }) }, formatExplainResults: function (explainSet) { http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index/history-query/logs.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index/history-query/logs.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index/history-query/logs.js index 3c710d3..43c7a7e 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index/history-query/logs.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/index/history-query/logs.js @@ -21,25 +21,24 @@ import constants from 'hive/utils/constants'; import utils from 'hive/utils/functions'; export default Ember.ObjectController.extend({ + fileService: Ember.inject.service(constants.namingConventions.file), + notifyService: Ember.inject.service(constants.namingConventions.notify), + needs: [ constants.namingConventions.queryTabs, - constants.namingConventions.loadedFiles ], + constants.namingConventions.index, + constants.namingConventions.openQueries ], queryTabs: Ember.computed.alias('controllers.' + constants.namingConventions.queryTabs), - files: Ember.computed.alias('controllers.' + constants.namingConventions.loadedFiles), + index: Ember.computed.alias('controllers.' + constants.namingConventions.index), + openQueries: Ember.computed.alias('controllers.' + constants.namingConventions.openQueries), reloadJobLogs: function (job) { - var self = this, - defer = Ember.RSVP.defer(), - handleError = function (error) { - job.set('isRunning', false); - - if (typeof error === "string") { - self.notify.error(error); - } else { - self.notify.error(error.responseJSON.message, error.responseJSON.trace); - } - defer.reject(); - }; + var self = this; + var handleError = function (error) { + job.set('isRunning', false); + + self.get('notifyService').error(error); + }; job.reload().then(function () { if (utils.insensitiveCompare(job.get('status'), constants.statuses.error) || @@ -47,46 +46,40 @@ export default Ember.ObjectController.extend({ handleError(job.get('statusMessage')); } - self.get('files').reload(job.get('logFile')).then(function (file) { + self.get('fileService').reloadFile(job.get('logFile')).then(function (file) { var fileContent = file.get('fileContent'); + var stillRunning = self.isJobRunning(job); + var currentIndexModelId = self.get('index.model.id'); + var currentActiveTab = self.get('queryTabs.activeTab.name'); if (fileContent) { job.set('log', fileContent); } - defer.resolve(); - },function (err) { - handleError(err); - }); - }, function (err) { - handleError(err); - }); - - return defer.promise; - }, - - listenForUpdates: function (job) { - Ember.run.later(this, function () { - var self = this; - - this.reloadJobLogs(job).then(function () { - var stillRunning = self.isJobRunning(job); - var currentContentId = self.get('content.id'); - var currentActiveTab = self.get('queryTabs.activeTab.name'); - //if the current model is the same with the one displayed, continue reloading job - if (stillRunning && job.get('id') === currentContentId) { - self.listenForUpdates(job); + if (stillRunning) { + Ember.run.later(self, function () { + this.reloadJobLogs(job); + }, 10000); } else if (!stillRunning) { job.set('isRunning', undefined); + job.set('retrievingLogs', false); - if (job.get('id') === currentContentId && - currentActiveTab === constants.namingConventions.index) { - self.transitionToRoute(constants.namingConventions.subroutes.jobResults); + if (utils.insensitiveCompare(job.get('status'), constants.statuses.succeeded)) { + self.get('openQueries').updateTabSubroute(job, constants.namingConventions.subroutes.jobResults); + + if (job.get('id') === currentIndexModelId && currentActiveTab === constants.namingConventions.index) { + self.transitionToRoute(constants.namingConventions.subroutes.historyQuery, job.get('id')); + } } } + + },function (err) { + handleError(err); }); - }, 10000); + }, function (err) { + handleError(err); + }); }, isJobRunning: function (job) { @@ -98,14 +91,18 @@ export default Ember.ObjectController.extend({ }, getLogs: function () { - var self = this, - job = this.get('content'); + var job = this.get('content'); if (this.isJobRunning(job)) { - job.set('isRunning', true); - this.reloadJobLogs(job).then(function () { - self.listenForUpdates(job); - }); + if (!job.get('retrievingLogs')) { + job.set('retrievingLogs', true); + job.set('isRunning', true); + this.reloadJobLogs(job); + } + } else if (utils.insensitiveCompare(job.get('status'), constants.statuses.succeeded) && !job.get('dagId')) { + //if a job that never polled for logs is succeeded, jump straight to results tab. + this.get('openQueries').updateTabSubroute(job, constants.namingConventions.subroutes.jobResults); + this.transitionToRoute(constants.namingConventions.subroutes.historyQuery, job.get('id')); } }.observes('content') }); http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/insert-udfs.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/insert-udfs.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/insert-udfs.js index fcfd113..09f17c3 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/insert-udfs.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/insert-udfs.js @@ -20,7 +20,7 @@ import Ember from 'ember'; import constants from 'hive/utils/constants'; export default Ember.ArrayController.extend({ - needs: [ constants.namingConventions.udfs, constants.namingConventions.fileResources ], + needs: [ constants.namingConventions.udfs ], model: Ember.A(), http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/job-progress.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/job-progress.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/job-progress.js index c80ae81..3181f90 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/job-progress.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/job-progress.js @@ -22,71 +22,108 @@ import constants from 'hive/utils/constants'; export default Ember.Controller.extend({ needs: [ constants.namingConventions.index ], + jobs: [], + index: Ember.computed.alias('controllers.' + constants.namingConventions.index), - listenForProgress: function () { - var self = this; - var url = this.container.lookup('adapter:application').buildURL(); - var stages = []; - var job = this.get('index.model'); + modelChanged: function () { + var model = this.get('index.model'); + var job; - var reloadProgress = function () { - Ember.run.later(function () { - Ember.$.getJSON(url).then(function (data) { - var total = 0; - var length = Object.keys(data.vertexProgresses).length; + if (!this.isJob(model)) { + return; + } - if (!self.get('stages.length')) { - data.vertexProgresses.forEach(function (vertexProgress) { - var progress = vertexProgress.progress * 100; + job = this.jobs.findBy('model', model); - stages.pushObject(Ember.Object.create({ - name: vertexProgress.name, - value: progress - })); + if (!job) { + job = this.jobs.pushObject(Ember.Object.create({ + model: model, + stages: [], + totalProgress: 0, + retrievingProgress: false, + })); + } - total += progress; - }); + this.set('currentJob', job); + }.observes('index.model'), - self.set('stages', stages); - } else { - data.vertexProgresses.forEach(function (vertexProgress) { - var progress = vertexProgress.progress * 100; + updateProgress: function () { + var job = this.get('currentJob'); - self.get('stages').findBy('name', vertexProgress.name).set('value', progress); + if (!job.get('model.dagId')) { + return; + } - total += progress; - }); - } + if (this.get('totalProgress') < 100 && !job.get('retrievingProgress')) { + this.reloadProgress(job); + } + }.observes('currentJob.model.dagId'), - total /= length; + totalProgress: function () { + if (!this.isJob(this.get('index.model'))) { + return; + } - self.set('totalProgress', total); + return this.get('currentJob.totalProgress'); + }.property('index.model', 'currentJob.totalProgress'), - if (job.get('isRunning') && total < 100) { - reloadProgress(); - } + stages: function () { + if (!this.isJob(this.get('index.model'))) { + return; + } - }, function (err) { - reloadProgress(); + return this.get('currentJob.stages'); + }.property('index.model', '[email protected]'), + + reloadProgress: function (job) { + var self = this; + var url = '%@/%@/%@/progress'.fmt(this.container.lookup('adapter:application').buildURL(), + constants.namingConventions.jobs, + job.get('model.id')); + + job.set('retrievingProgress', true); + + Ember.$.getJSON(url).then(function (data) { + var total = 0; + var length = Object.keys(data.vertexProgresses).length; + + if (!job.get('stages.length')) { + data.vertexProgresses.forEach(function (vertexProgress) { + var progress = vertexProgress.progress * 100; + + job.get('stages').pushObject(Ember.Object.create({ + name: vertexProgress.name, + value: progress + })); + + total += progress; }); - }, 1000); - }; + } else { + data.vertexProgresses.forEach(function (vertexProgress) { + var progress = vertexProgress.progress * 100; - //reset stages - this.set('stages', []); - this.set('totalProgress', 0); + job.get('stages').findBy('name', vertexProgress.name).set('value', progress); - if (!job.get('dagId')) { - return; - } + total += progress; + }); + } + + total /= length; - url += '/' + constants.namingConventions.jobs + '/' + job.get('id') + '/progress'; + job.set('totalProgress', total); - reloadProgress(); - }.observes('index.model', 'index.model.dagId'), + if (job.get('model.isRunning') && total < 100) { + Ember.run.later(function () { + self.reloadProgress(job); + }, 1000); + } else { + job.set('retrievingProgress'); + } + }); + }, - displayProgress: function () { - return this.get('index.model.constructor.typeKey') === constants.namingConventions.job; - }.property('index.model') + isJob: function (model) { + return model.get('constructor.typeKey') === constants.namingConventions.job; + } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/job.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/job.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/job.js deleted file mode 100644 index 2d53524..0000000 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/job.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import Ember from 'ember'; -import constants from 'hive/utils/constants'; -import utils from 'hive/utils/functions'; - -export default Ember.ObjectController.extend({ - needs: [ constants.namingConventions.history, constants.namingConventions.loadedFiles ], - - files: Ember.computed.alias('controllers.' + constants.namingConventions.loadedFiles), - - canStop: function () { - return utils.insensitiveCompare(this.get('status'), constants.statuses.running, constants.statuses.initialized, constants.statuses.pending); - }.property('status'), - - actions: { - loadFile: function () { - var self = this; - if (!this.get('file')) { - this.get('files').loadFile(this.get('model.queryFile')).then(function (file) { - self.set('file', file); - }); - } - - this.set('expanded', !this.get('expanded')); - }, - - stop: function () { - this.send('interruptJob', this.get('model')); - } - } -}); http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/loaded-files.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/loaded-files.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/loaded-files.js deleted file mode 100644 index 3a11171..0000000 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/loaded-files.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import Ember from 'ember'; -import constants from 'hive/utils/constants'; - -export default Ember.ArrayController.extend({ - contains: function (obj) { - if (typeof obj === 'string') { - return this.findBy('id', obj); - } - - return this._super(obj); - }, - - loadFile: function (path) { - var self = this; - var defer = Ember.RSVP.defer(); - var file = this.contains(path); - - if (file) { - defer.resolve(file); - } else { - this.store.find(constants.namingConventions.file, path).then(function (file) { - self.pushObject(file); - defer.resolve(file); - }, function (err) { - defer.reject(err); - }); - } - - return defer.promise; - }, - - reload: function (path) { - var defer = Ember.RSVP.defer(); - - this.store.find(constants.namingConventions.file, path).then(function (file) { - file.reload().then(function (reloadedFile) { - defer.resolve(reloadedFile); - }, function (err) { - defer.reject(err); - }); - }, function (err) { - defer.reject(err); - }); - - return defer.promise; - } -}); http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/messages.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/messages.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/messages.js index db8e0b5..11295d8 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/messages.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/messages.js @@ -15,23 +15,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import Ember from 'ember'; +import constants from 'hive/utils/constants'; export default Ember.Controller.extend({ - messages: Ember.computed.alias('notify.messages'), - count: Ember.computed.alias('notify.unseenMessages.length'), + notifyService: Ember.inject.service(constants.namingConventions.notify), + + messages: Ember.computed.alias('notifyService.messages'), + count: Ember.computed.alias('notifyService.unseenMessages.length'), actions: { removeMessage: function (message) { - this.notify.removeMessage(message); + this.get('notifyService').removeMessage(message); }, removeAllMessages: function () { - this.notify.removeAllMessages(); + this.get('notifyService').removeAllMessages(); }, markMessagesAsSeen: function () { - this.notify.markMessagesAsSeen(); + this.get('notifyService').markMessagesAsSeen(); } } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/open-queries.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/open-queries.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/open-queries.js index 722ea0a..484df16 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/open-queries.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/open-queries.js @@ -21,27 +21,23 @@ import constants from 'hive/utils/constants'; import utils from 'hive/utils/functions'; export default Ember.ArrayController.extend({ - needs: [ constants.namingConventions.databases, - constants.namingConventions.loadedFiles, - constants.namingConventions.jobResults, + fileService: Ember.inject.service(constants.namingConventions.file), + databaseService: Ember.inject.service(constants.namingConventions.database), + + needs: [ constants.namingConventions.jobResults, constants.namingConventions.jobExplain, - constants.namingConventions.columns, constants.namingConventions.index, constants.namingConventions.settings ], - databases: Ember.computed.alias('controllers.' + constants.namingConventions.databases), - - files: Ember.computed.alias('controllers.' + constants.namingConventions.loadedFiles), - jobResults: Ember.computed.alias('controllers.' + constants.namingConventions.jobResults), - jobExplain: Ember.computed.alias('controllers.' + constants.namingConventions.jobExplain), - index: Ember.computed.alias('controllers.' + constants.namingConventions.index), - settings: Ember.computed.alias('controllers.' + constants.namingConventions.settings), + selectedTables: Ember.computed.alias('databaseService.selectedTables'), + selectedDatabase: Ember.computed.alias('databaseService.selectedDatabase'), + init: function () { this._super(); @@ -132,14 +128,14 @@ export default Ember.ArrayController.extend({ defer.resolve(); } else { - this.get('files').loadFile(model.get('queryFile')).then(function (file) { + this.get('fileService').loadFile(model.get('queryFile')).then(function (file) { self.set('currentQuery', self.pushObject(file)); updateSubroute(); }); if (model.get('logFile') && !model.get('log')) { - this.get('files').loadFile(model.get('logFile')).then(function (file) { + this.get('fileService').loadFile(model.get('logFile')).then(function (file) { model.set('log', file.get('fileContent')); }); } @@ -175,7 +171,7 @@ export default Ember.ArrayController.extend({ //if current query it's a job, convert it to a savedQuery before saving if (model.get('constructor.typeKey') === constants.namingConventions.job) { model = this.store.createRecord(constants.namingConventions.savedQuery, { - dataBase: this.get('databases.selectedDatabase.name'), + dataBase: this.get('selectedDatabase.name'), title: newTitle, queryFile: model.get('queryFile'), owner: model.get('owner') @@ -187,7 +183,7 @@ export default Ember.ArrayController.extend({ //if saving a new query from an existing one create a new record and save it if (!isUpdating && !model.get('isNew') && model.get('constructor.typeKey') !== constants.namingConventions.job) { model = this.store.createRecord(constants.namingConventions.savedQuery, { - dataBase: this.get('databases.selectedDatabase.name'), + dataBase: this.get('selectedDatabase.name'), title: newTitle, owner: model.get('owner') }); @@ -201,12 +197,17 @@ export default Ember.ArrayController.extend({ tab.set('isDirty', false); var content = query.get('fileContent'); + content = self.get('index').buildQuery(query); + content = self.get('index').bindQueryParams(content); + content = self.get('index').prependQuerySettings(content); + //update query tab path with saved model id if its a new record if (wasNew) { self.get('settings').updateSettingsId(originalId, updatedModel.get('id')); tab.set('id', updatedModel.get('id')); - self.get('files').loadFile(updatedModel.get('queryFile')).then(function (file) { + self.get('fileService').loadFile(updatedModel.get('queryFile')).then(function (file) { + file.set('blockSettingsParser', true); file.set('fileContent', content); file.save().then(function (updatedFile) { self.removeObject(query); @@ -214,6 +215,8 @@ export default Ember.ArrayController.extend({ self.set('currentQuery', updatedFile); defer.resolve(updatedModel.get('id')); + self.get('settings').parseQuerySettings(false); + query.set('blockSettingsParser', false); }, function (err) { defer.reject(err); }); @@ -221,10 +224,14 @@ export default Ember.ArrayController.extend({ defer.reject(err); }); } else { + query.set('blockSettingsParser', true); query.set('fileContent', content); query.save().then(function () { self.toggleProperty('tabUpdated'); defer.resolve(updatedModel.get('id')); + + self.get('settings').parseQuerySettings(false); + query.set('blockSettingsParser', false); }, function (err) { defer.reject(err); }); @@ -247,7 +254,7 @@ export default Ember.ArrayController.extend({ tab.set('type', constants.namingConventions.job); tab.set('path', constants.namingConventions.subroutes.historyQuery); - this.get('files').loadFile(job.get('queryFile')).then(function (file) { + this.get('fileService').loadFile(job.get('queryFile')).then(function (file) { //replace old model representing file to reflect model update to job if (self.keepOriginalQuery(jobId)) { file.set('fileContent', oldQuery.get('fileContent')); @@ -373,7 +380,7 @@ export default Ember.ArrayController.extend({ }, getColumnsForAutocomplete: function (tableName, callback) { - this.get('databases').getAllColumns(tableName).then(function () { + this.get('databaseService').getAllColumns(tableName).then(function () { callback(); }); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/ebf56d06/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/query-tabs.js ---------------------------------------------------------------------- diff --git a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/query-tabs.js b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/query-tabs.js index 4c50c2e..7b6c222 100644 --- a/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/query-tabs.js +++ b/contrib/views/hive/src/main/resources/ui/hive-web/app/controllers/query-tabs.js @@ -20,10 +20,6 @@ import Ember from 'ember'; import constants from 'hive/utils/constants'; export default Ember.Controller.extend({ - needs: [ constants.namingConventions.index], - - index: Ember.computed.alias('controllers' + constants.namingConventions.index), - tabClassNames : "fa queries-icon query-context-tab", tabs: [ @@ -148,6 +144,15 @@ export default Ember.Controller.extend({ } }, + flashSettings: function() { + var settingsTab = this.get('tabs').findBy('id', 'settings-icon'); + settingsTab.set('flash', true); + + Ember.run.later(function() { + settingsTab.set('flash', false); + }, 1000); + }, + actions: { toggleOverlay: function (tab) { if (tab !== this.get('default') && tab.get('active')) {
