Repository: ambari Updated Branches: refs/heads/trunk 5b75e7abf -> 841483b9b
AMBARI-8672. Config validations not displaying ERRORs (Buzhor Denys via srimanth) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/841483b9 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/841483b9 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/841483b9 Branch: refs/heads/trunk Commit: 841483b9bf05e7887aa02a60fb2594a3f36d39bd Parents: 5b75e7a Author: Srimanth Gunturi <sgunt...@hortonworks.com> Authored: Thu Dec 11 12:06:29 2014 -0800 Committer: Srimanth Gunturi <sgunt...@hortonworks.com> Committed: Thu Dec 11 12:06:29 2014 -0800 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 1 + .../app/controllers/wizard/step7_controller.js | 3 +- ambari-web/app/mixins/common/serverValidator.js | 28 +++- .../configs/config_recommendation_popup.hbs | 9 +- .../test/mixins/common/serverValidator_test.js | 134 +++++++++++++++++++ 5 files changed, 171 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/841483b9/ambari-web/app/assets/test/tests.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js index 8615b35..2aab326 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -127,6 +127,7 @@ var files = ['test/init_model_test', 'test/mappers/stack_mapper_test', 'test/mixins/common/chart/storm_linear_time_test', 'test/mixins/common/localStorage_test', + 'test/mixins/common/serverValidator_test', 'test/mixins/common/table_server_view_mixin_test', 'test/mixins/main/host/details/host_components/decommissionable_test', 'test/mixins/wizard/addSeccurityConfigs_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/841483b9/ambari-web/app/controllers/wizard/step7_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step7_controller.js b/ambari-web/app/controllers/wizard/step7_controller.js index d004c05..d11e88b 100644 --- a/ambari-web/app/controllers/wizard/step7_controller.js +++ b/ambari-web/app/controllers/wizard/step7_controller.js @@ -242,7 +242,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, { attributeValue: filter.attributeValue, name: this.t(filter.caption), selected: false - }) + }); }, this); }.property('propertyFilters'), @@ -256,6 +256,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, { * @method clearStep */ clearStep: function () { + this.set('configValidationGlobalMessage', []); this.set('submitButtonClicked', false); this.set('isSubmitDisabled', true); this.set('isRecommendedLoaded', false); http://git-wip-us.apache.org/repos/asf/ambari/blob/841483b9/ambari-web/app/mixins/common/serverValidator.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins/common/serverValidator.js b/ambari-web/app/mixins/common/serverValidator.js index 4eccf37..449b1ee 100644 --- a/ambari-web/app/mixins/common/serverValidator.js +++ b/ambari-web/app/mixins/common/serverValidator.js @@ -37,6 +37,11 @@ App.ServerValidatorMixin = Em.Mixin.create({ configValidationFailed: false, /** + * @type {object[]} contains additional message about validation errors + */ + configValidationGlobalMessage: [], + + /** * recommendation configs loaded from server * (used only during install) * @type {Object} @@ -73,7 +78,7 @@ App.ServerValidatorMixin = Em.Mixin.create({ return this.get('content.serviceName') ? [App.StackService.find(this.get('content.serviceName'))] : this.get('content.services').filter(function(s){ - return (s.get('isSelected') || s.get('isInstalled')) + return (s.get('isSelected') || s.get('isInstalled')); }).concat(require("data/service_configs")); }.property('content.serviceName', 'content.services', 'content.services.@each.isSelected', 'content.services.@each.isInstalled', 'content.stacks.@each.isSelected'), @@ -137,6 +142,7 @@ App.ServerValidatorMixin = Em.Mixin.create({ serverSideValidation: function () { var deferred = $.Deferred(); this.set('configValidationFailed', false); + this.set('configValidationGlobalMessage', []); if (this.get('configValidationFailed')) { this.warnUser(deferred); } else { @@ -189,6 +195,8 @@ App.ServerValidatorMixin = Em.Mixin.create({ */ validationSuccess: function(data) { var self = this; + var checkedProperties = []; + var globalWarning = []; self.set('configValidationError', false); self.set('configValidationWarning', false); data.resources.forEach(function(r) { @@ -206,12 +214,28 @@ App.ServerValidatorMixin = Em.Mixin.create({ property.set('warnMessage', item.message); property.set('warn', true); } + // store property data to detect WARN or ERROR messages for missed property + if (["ERROR", "WARN"].contains(item.level)) checkedProperties.push(item['config-type'] + '/' + item['config-name']); } }); - }) + }); + // check if error or warn message detected for property that absent in step configs + if (["ERROR", "WARN"].contains(item.level) && !checkedProperties.contains(item['config-type'] + '/' + item['config-name'])) { + var message = { + propertyName: item['config-name'], + filename: item['config-type'], + warnMessage: item.message, + serviceName: App.StackService.find().filter(function(service) { + return !!service.get('configTypes')[item['config-type']]; + })[0].get('displayName') + }; + self.set(item.level == 'WARN' ? 'configValidationWarning' : 'configValidationError', true); + globalWarning.push(message); + } } }); }); + self.set('configValidationGlobalMessage', globalWarning); }, validationError: function (jqXHR, ajaxOptions, error, opt) { http://git-wip-us.apache.org/repos/asf/ambari/blob/841483b9/ambari-web/app/templates/common/configs/config_recommendation_popup.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/configs/config_recommendation_popup.hbs b/ambari-web/app/templates/common/configs/config_recommendation_popup.hbs index 0a3e231..3c5a0cf 100644 --- a/ambari-web/app/templates/common/configs/config_recommendation_popup.hbs +++ b/ambari-web/app/templates/common/configs/config_recommendation_popup.hbs @@ -57,6 +57,13 @@ {{/if}} {{/each}} {{/each}} + {{#each message in configValidationGlobalMessage}} + <tr> + <td>{{message.serviceName}}</td> + <td>{{message.propertyName}}</td> + <td colspan="2">{{message.warnMessage}} in {{message.filename}}</td> + </tr> + {{/each}} </tbody> </table> -</div> \ No newline at end of file +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/841483b9/ambari-web/test/mixins/common/serverValidator_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/mixins/common/serverValidator_test.js b/ambari-web/test/mixins/common/serverValidator_test.js new file mode 100644 index 0000000..306c54b --- /dev/null +++ b/ambari-web/test/mixins/common/serverValidator_test.js @@ -0,0 +1,134 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var App = require('app'); + +describe('App.ServerValidatorMixin', function() { + var mixinObject = Em.Object.extend(App.ServerValidatorMixin, {}); + describe('#validationSuccess', function() { + var instanceObject; + var genRespItem = function(name, filename, level, message) { + return { + type: 'configuration', + 'config-name': name, + 'config-type': filename, + level: level, + message: message + }; + }; + var genResponse = function(items) { + return { + items: (items.map(function(item) { return genRespItem.apply(undefined, item); })) + }; + }; + var genConfigs = function(configs) { + return Em.Object.create({ + configs: (configs.map(function(item) { + return Em.Object.create({ name: item[0], filename: item[1] }); + })) + }); + }; + var tests = [ + { + stepConfigs: Em.A([ + genConfigs([ + ['prop1', 'some-site.xml'] + ]) + ]), + resources: [ + genResponse([ + ['prop1', 'some-site', 'WARN', 'Some warn'], + ['prop2', 'some-site', 'ERROR', 'Value should be set'] + ]) + ], + expected: [ + { prop: 'configValidationError', value: true }, + { prop: 'configValidationWarning', value: true }, + { prop: 'configValidationGlobalMessage.length', value: 1 }, + { prop: 'configValidationGlobalMessage[0].serviceName', value: 'Some Service' }, + { prop: 'configValidationGlobalMessage[0].propertyName', value: 'prop2' }, + ], + message: 'validation failed on absent property from step configs. global message should be showed.' + }, + { + stepConfigs: Em.A([ + genConfigs([ + ['prop1', 'some-site.xml'], + ['prop2', 'some-site.xml'] + ]) + ]), + resources: [ + genResponse([ + ['prop1', 'some-site', 'WARN', 'Some warn'], + ]) + ], + expected: [ + { prop: 'configValidationError', value: false }, + { prop: 'configValidationWarning', value: true }, + { prop: 'configValidationGlobalMessage.length', value: 0} + ], + message: 'all properties present in step configs. validation failed. Present WARN and ERROR level messages.' + }, + { + stepConfigs: Em.A([ + genConfigs([ + ['prop1', 'some-site.xml'], + ['prop2', 'some-site.xml'] + ]) + ]), + resources: [ + { + items: [] + } + ], + expected: [ + { prop: 'configValidationFailed', value: false }, + { prop: 'configValidationError', value: false }, + { prop: 'configValidationWarning', value: false }, + { prop: 'configValidationGlobalMessage.length', value: 0} + ], + message: 'validation success. no errors flags should be set.' + } + ]; + + beforeEach(function() { + instanceObject = mixinObject.create({}); + sinon.stub(App.StackService, 'find').returns([ + Em.Object.create({ + displayName: 'Some Service', + configTypes: { 'some-site': {} } + }) + ]); + }); + + afterEach(function() { + App.StackService.find.restore(); + }); + + tests.forEach(function(test) { + it(test.message, function() { + instanceObject.set('stepConfigs', test.stepConfigs); + instanceObject.validationSuccess({resources: test.resources}); + test.expected.forEach(function(e) { + expect(instanceObject).to.have.deep.property(e.prop, e.value); + }); + }); + }); + }); +}); +