AMBARI-7626. Slider View: UI should not use view parameters. (onechiporenko via srimanth)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/659682d8 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/659682d8 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/659682d8 Branch: refs/heads/branch-alerts-dev Commit: 659682d86f1013af114132b1647a8a6bff046441 Parents: 8cc65e3 Author: Srimanth Gunturi <[email protected]> Authored: Fri Oct 3 01:20:20 2014 -0700 Committer: Srimanth Gunturi <[email protected]> Committed: Fri Oct 3 01:20:20 2014 -0700 ---------------------------------------------------------------------- .../data/resource/slider-properties-2.json | 8 +++ .../ui/app/controllers/slider_controller.js | 53 +++++--------------- .../src/main/resources/ui/app/helpers/ajax.js | 20 ++++++++ .../src/main/resources/ui/app/initialize.js | 11 ++-- .../resources/ui/app/models/slider_config.js | 14 +----- .../src/main/resources/ui/app/routes/main.js | 18 +------ .../main/resources/ui/app/styles/common.less | 11 ++++ .../resources/ui/app/templates/application.hbs | 25 ++++++--- .../ui/app/templates/slider_app/summary.hbs | 7 --- .../ui/app/views/slider_app/summary_view.js | 7 --- .../ui/test/integration/pages/index_test.js | 2 +- .../integration/pages/slider_errors_test.js | 46 +++++++++++++++++ 12 files changed, 123 insertions(+), 99 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/659682d8/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/slider-properties-2.json ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/slider-properties-2.json b/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/slider-properties-2.json new file mode 100644 index 0000000..3ec0e66 --- /dev/null +++ b/contrib/views/slider/src/main/resources/ui/app/assets/data/resource/slider-properties-2.json @@ -0,0 +1,8 @@ +{ + "version": "1.0.0", + "validation": [], + "parameters": { + "gangliaHost": "c6401.ambari.apache.org", + "gangliaClusters": "App1:8881,App2:8882" + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/659682d8/contrib/views/slider/src/main/resources/ui/app/controllers/slider_controller.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_controller.js b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_controller.js index 6af6f58..6251a23 100644 --- a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_controller.js +++ b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_controller.js @@ -21,7 +21,7 @@ * After this set <code>App.sliderConfig</code>-models and enable/disable Slider * @type {Ember.Controller} */ -App.SliderController = Ember.Controller.extend({ +App.SliderController = Ember.Controller.extend(App.RunPeriodically, { /** * Load resources on controller initialization @@ -39,10 +39,9 @@ App.SliderController = Ember.Controller.extend({ */ getParametersFromViewProperties: function () { return App.ajax.send({ - name: 'slider.getViewParams', + name: 'slider.getViewParams.v2', sender: this, - success: 'getParametersFromViewPropertiesSuccessCallback', - error: 'finishSliderConfiguration' + success: 'getParametersFromViewPropertiesSuccessCallback' }); }, @@ -54,17 +53,14 @@ App.SliderController = Ember.Controller.extend({ * @method getParametersFromViewPropertiesSuccessCallback */ getParametersFromViewPropertiesSuccessCallback: function (data) { - var properties = Em.get(data, 'ViewInstanceInfo.properties'), - initialValuesToLoad = this.get('initialValuesToLoad'), - sliderConfigs = App.SliderApp.store.all('sliderConfig'), - self = this; - App.set('label', Em.get(data, 'ViewInstanceInfo.label') || App.get('instance')); + var properties = Em.get(data, 'parameters'), + sliderConfigs = App.SliderApp.store.all('sliderConfig'); sliderConfigs.forEach(function (model) { var key = model.get('viewConfigName'); model.set('value', properties[key]); }); - self.finishSliderConfiguration(); - self.initGangliaProperties(); + this.initGangliaProperties(); + this.finishSliderConfiguration(data); }, /** @@ -72,8 +68,8 @@ App.SliderController = Ember.Controller.extend({ */ initGangliaProperties: function () { var sliderConfigs = App.SliderApp.store.all('sliderConfig'), - gangliaClusters = sliderConfigs.findBy('viewConfigName', 'ganglia.additional.clusters'), - gangliaHost = sliderConfigs.findBy('viewConfigName', 'ganglia.server.hostname'); + gangliaClusters = sliderConfigs.findBy('viewConfigName', 'gangliaClusters'), + gangliaHost = sliderConfigs.findBy('viewConfigName', 'gangliaHost'); App.set('gangliaClusters', this.formatGangliaClusters(gangliaClusters.get('value'))); App.set('gangliaHost', gangliaHost.get('value')); }, @@ -103,36 +99,13 @@ App.SliderController = Ember.Controller.extend({ /** * After all Slider-configs are loaded, application should check self status - * If config <code>required</code>-property is true, its value shouldn't be empty - * If config depends on some other config (see <code>requireDependsOn</code>-property) - * and referenced config-value is not-false, current config should have not-empty value + * @param {object} data - received from server information about current Slider-status * @method finishSliderConfiguration */ - finishSliderConfiguration: function () { - //check if all services exist - var errors = []; - App.SliderApp.store.all('sliderConfig').forEach(function (model) { - if (model.get('required')) { - if (Em.isEmpty(model.get('value'))) { - errors.push(Em.I18n.t('error.config_is_empty').format(model.get('viewConfigName'))); - } - } - else { - var dependenceConfig = model.get('requireDependsOn'); - if (!Em.isNone(dependenceConfig)) { - var depValue = dependenceConfig.get('value').toLowerCase(); - if (depValue == "true") { - if (Em.isEmpty(model.get('value'))) { - errors.push(Em.I18n.t('error.config_is_empty_2').format(model.get('viewConfigName'), dependenceConfig.get('viewConfigName'))); - } - } - } - } - }); - errors.uniq(); + finishSliderConfiguration: function (data) { App.setProperties({ - viewErrors: errors, - viewEnabled: errors.length === 0, + viewErrors: data.validations, + viewEnabled: data.validations.length === 0, mapperTime: new Date().getTime() }); } http://git-wip-us.apache.org/repos/asf/ambari/blob/659682d8/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js b/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js index 5c6146f..c4864c2 100644 --- a/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js +++ b/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js @@ -47,6 +47,26 @@ var urls = { } }, + 'slider.getViewParams.v2': { + real: 'resources/status', + mock: '/data/resource/slider-properties-2.json', + headers: { + "Accept": "application/json; charset=utf-8", + "Content-Type": "text/plain; charset=utf-8" + }, + schema: { + required: ['version', 'validation', 'parameters'], + properties: { + validation: { + type: 'array' + }, + parameters: { + type : 'object' + } + } + } + }, + 'mapper.applicationTypes': { real: 'apptypes?fields=*', mock: '/data/apptypes/all_fields.json', http://git-wip-us.apache.org/repos/asf/ambari/blob/659682d8/contrib/views/slider/src/main/resources/ui/app/initialize.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/initialize.js b/contrib/views/slider/src/main/resources/ui/app/initialize.js index 2f53e10..56449cd 100755 --- a/contrib/views/slider/src/main/resources/ui/app/initialize.js +++ b/contrib/views/slider/src/main/resources/ui/app/initialize.js @@ -67,7 +67,7 @@ App.initializer({ /** * @type {string} */ - label: '', + label: instanceName, /** * API url for Slider @@ -92,12 +92,6 @@ App.initializer({ viewErrors: [], /** - * Host with Nagios Server - * @type {string|null} - */ - nagiosHost: null, - - /** * Host with Ganglia Server * @type {string|null} */ @@ -117,7 +111,8 @@ App.initializer({ }); if(!window.QUnit) { - application.SliderController.proto().initResources(); + var sliderController = application.__container__.lookup('controller:Slider'); + sliderController.run('initResources'); application.ApplicationTypeMapper.load(); application.SliderAppsMapper.run('load'); } http://git-wip-us.apache.org/repos/asf/ambari/blob/659682d8/contrib/views/slider/src/main/resources/ui/app/models/slider_config.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/models/slider_config.js b/contrib/views/slider/src/main/resources/ui/app/models/slider_config.js index d8b2be6..b1b2129 100644 --- a/contrib/views/slider/src/main/resources/ui/app/models/slider_config.js +++ b/contrib/views/slider/src/main/resources/ui/app/models/slider_config.js @@ -38,19 +38,7 @@ App.SliderConfig = DS.Model.extend({ /** * @type {null|string} */ - value: null, - - /** - * Is property required - * @type {bool} - */ - required: DS.attr('bool'), - - /** - * If provided config has not-false value current config shouldn't be empty - * @type {App.SliderConfig} - */ - requireDependsOn: DS.belongsTo('sliderConfig') + value: null }); http://git-wip-us.apache.org/repos/asf/ambari/blob/659682d8/contrib/views/slider/src/main/resources/ui/app/routes/main.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/routes/main.js b/contrib/views/slider/src/main/resources/ui/app/routes/main.js index bef5faa..64510fa 100644 --- a/contrib/views/slider/src/main/resources/ui/app/routes/main.js +++ b/contrib/views/slider/src/main/resources/ui/app/routes/main.js @@ -52,22 +52,8 @@ App.SliderAppsRoute = Ember.Route.extend({ // Load sliderConfigs to storage App.SliderApp.store.pushMany('sliderConfig', Em.A([ - Em.Object.create({id: 1, required: true, viewConfigName: 'hdfs.url', displayName: 'hdfsAddress', linkedService: 'HDFS'}), - Em.Object.create({id: 2, required: true, viewConfigName: 'yarn.rm.url', displayName: 'yarnResourceManager', linkedService: 'YARN'}), - Em.Object.create({id: 3, required: true, viewConfigName: 'yarn.rm.webapp.url', displayName: 'yarnResourceManagerWebapp', linkedService: 'YARN'}), - Em.Object.create({id: 4, required: true, viewConfigName: 'yarn.rm.scheduler.url', displayName: 'yarnResourceManagerScheduler'}), - Em.Object.create({id: 5, required: true, viewConfigName: 'zookeeper.quorum', displayName: 'zookeeperQuorum', linkedService: 'ZOOKEEPER'}), - Em.Object.create({id: 6, required: false, viewConfigName: 'ganglia.server.hostname', displayName: 'gangliaServer'}), - Em.Object.create({id: 7, required: false, viewConfigName: 'ganglia.additional.clusters', displayName: 'gangliaClusters'}), - Em.Object.create({id: 8, required: false, viewConfigName: 'slider.user', displayName: 'sliderUser'}), - Em.Object.create({id: 9, required: true, viewConfigName: 'slider.security.enabled', displayName: 'sliderSecurityEnabled'}), - Em.Object.create({id: 10, required: false, requireDependsOn: 9, viewConfigName: 'yarn.rm.kerberos.principal', displayName: 'yarnResourceManagerPrincipal'}), - Em.Object.create({id: 11, required: false, requireDependsOn: 9, viewConfigName: 'dfs.namenode.kerberos.principal', displayName: 'dfsNamenodeKerberosPrincipal'}), - Em.Object.create({id: 12, required: false, requireDependsOn: 9, viewConfigName: 'view.kerberos.principal', displayName: 'viewKerberosPrincipal'}), - Em.Object.create({id: 13, required: false, requireDependsOn: 9, viewConfigName: 'view.kerberos.principal.keytab', displayName: 'ViewKerberosPrincipalKeytab'}), - Em.Object.create({id: 14, required: false, viewConfigName: 'yarm.rm.ha.hosts', displayName: 'yarnResourceManagerHighAvailabilityHosts'}), - Em.Object.create({id: 15, required: false, viewConfigName: 'yarn.rm.store.class', displayName: 'yarnResourceManagerStoreClass'}), - Em.Object.create({id: 16, required: false, viewConfigName: 'yarn.rm.ha.automatic-failover.zk-base-path', displayName: 'yarnResourceManagerHighAvailabilityAutoFailoverZooKeeperBasePath'}) + Em.Object.create({id: 1, required: false, viewConfigName: 'gangliaHost', displayName: 'gangliaServer'}), + Em.Object.create({id: 2, required: false, viewConfigName: 'gangliaClusters', displayName: 'gangliaClusters'}) ])); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/659682d8/contrib/views/slider/src/main/resources/ui/app/styles/common.less ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/styles/common.less b/contrib/views/slider/src/main/resources/ui/app/styles/common.less index a3cffbd..4ae44b5 100644 --- a/contrib/views/slider/src/main/resources/ui/app/styles/common.less +++ b/contrib/views/slider/src/main/resources/ui/app/styles/common.less @@ -103,3 +103,14 @@ select { .modal-backdrop.in { opacity:0; } + + +.slider-errors-wrapper { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + padding: 10px; + background-color: #fff; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/659682d8/contrib/views/slider/src/main/resources/ui/app/templates/application.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/templates/application.hbs b/contrib/views/slider/src/main/resources/ui/app/templates/application.hbs index a61b702..bb05287 100755 --- a/contrib/views/slider/src/main/resources/ui/app/templates/application.hbs +++ b/contrib/views/slider/src/main/resources/ui/app/templates/application.hbs @@ -16,6 +16,22 @@ * limitations under the License. }} +{{! + DON'T TRY TO PUT OUTLET INTO CONDITIONAL STATES + https://github.com/emberjs/ember.js/issues/3187 - CLOSED BUT NOT FIXED YET +}} + + +{{#unless App.viewEnabled}} + <div class="slider-errors-wrapper"> + <div class="alert alert-danger"> + {{#each error in App.viewErrors}} + <h3 class="error-message">{{{error.message}}}</h3> + {{/each}} + </div> + </div> +{{/unless}} + <div class="slider-header"> {{#view view.SliderTitleView}} <h3 class="pull-left" id="slider-title"><span class="slider-app-title">{{App.label}}</span></h3> @@ -31,10 +47,5 @@ {{/view}} {{outlet bs-tooltip-box}} </div> -{{#if App.viewEnabled}} - {{outlet}} -{{else}} - {{#each error in App.viewErrors}} - <h3>{{{error}}}</h3> - {{/each}} -{{/if}} + +{{outlet}} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/659682d8/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs b/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs index 42860d6..a00e265 100644 --- a/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs +++ b/contrib/views/slider/src/main/resources/ui/app/templates/slider_app/summary.hbs @@ -61,13 +61,6 @@ <div class="panel-heading"> {{t common.status}} <div class="btn-group pull-right panel-link"> - {{#if App.nagiosHost}} - <a class="btn btn-default btn-sm" target="_blank" rel="tooltip" - {{translateAttr title="sliderApp.summary.go_to_nagios"}} - {{bind-attr href="view.nagiosUrl"}}> - <i class="icon-link"></i> - </a> - {{/if}} </div> </div> <div class="app-alerts"> http://git-wip-us.apache.org/repos/asf/ambari/blob/659682d8/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js b/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js index 1ca8ee8..3c429cb 100644 --- a/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js +++ b/contrib/views/slider/src/main/resources/ui/app/views/slider_app/summary_view.js @@ -96,13 +96,6 @@ App.SliderAppSummaryView = Ember.View.extend({ return 'http://' + App.get('gangliaHost') + '/ganglia'; }.property('App.gangliaHost', '[email protected]'), - /** - * @type {string} - */ - nagiosUrl: function () { - return 'http://' + App.get('nagiosHost') + '/nagios'; - }.property('App.nagiosHost'), - didInsertElement: function() { var self = this; Em.run.next(function() { http://git-wip-us.apache.org/repos/asf/ambari/blob/659682d8/contrib/views/slider/src/main/resources/ui/test/integration/pages/index_test.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/test/integration/pages/index_test.js b/contrib/views/slider/src/main/resources/ui/test/integration/pages/index_test.js index 78766b4..ecd8e6c 100644 --- a/contrib/views/slider/src/main/resources/ui/test/integration/pages/index_test.js +++ b/contrib/views/slider/src/main/resources/ui/test/integration/pages/index_test.js @@ -44,7 +44,7 @@ test('sliderConfigs', function () { visit('/'); // configs count may be changed by adding new slider-configs - equal(App.SliderApp.store.all('sliderConfig').content.length, 16, 'slider configs should be set'); + equal(App.SliderApp.store.all('sliderConfig').content.length, 2, 'slider configs should be set'); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/659682d8/contrib/views/slider/src/main/resources/ui/test/integration/pages/slider_errors_test.js ---------------------------------------------------------------------- diff --git a/contrib/views/slider/src/main/resources/ui/test/integration/pages/slider_errors_test.js b/contrib/views/slider/src/main/resources/ui/test/integration/pages/slider_errors_test.js new file mode 100644 index 0000000..402ddf1 --- /dev/null +++ b/contrib/views/slider/src/main/resources/ui/test/integration/pages/slider_errors_test.js @@ -0,0 +1,46 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +QUnit.module('integration/pages - index', { + + setup: function () { + Ember.run(App, App.advanceReadiness); + Em.run(function () { + var p = { + validation: [ + {message: 'Some mythical error'}, + {message: 'Error with DNA'} + ], + parameters: {} + }; + App.__container__.lookup('controller:Slider').getParametersFromViewPropertiesSuccessCallback(p); + }); + }, + + teardown: function () { + App.reset(); + } + +}); + +test('Slider has validation errors', function () { + + visit('/'); + equal(find('.slider-errors-wrapper .error-message').length, 2, 'Error-messages exist on the page'); + +}); \ No newline at end of file
