Repository: ambari Updated Branches: refs/heads/branch-2.1 75f183184 -> 5e0ee82b1
AMBARI-11779 Customize Services - Config Group issues on the recommendations screen. (ababiichuk) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5e0ee82b Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5e0ee82b Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5e0ee82b Branch: refs/heads/branch-2.1 Commit: 5e0ee82b11e388bf41f878176f37d0707567e7e8 Parents: 75f1831 Author: aBabiichuk <[email protected]> Authored: Mon Jun 8 13:20:14 2015 +0300 Committer: aBabiichuk <[email protected]> Committed: Mon Jun 8 13:22:00 2015 +0300 ---------------------------------------------------------------------- .../controllers/main/service/info/configs.js | 7 +- .../app/controllers/wizard/step7_controller.js | 28 ++- .../configs/stack_config_properties_mapper.js | 40 ++++ ambari-web/app/messages.js | 2 + .../mixins/common/configs/enhanced_configs.js | 218 ++++++++----------- .../service/configs/preload_requests_chain.js | 5 + ambari-web/app/models/config_group.js | 7 + .../models/configs/objects/service_config.js | 8 +- ambari-web/app/models/stack_service.js | 7 + .../templates/common/configs/service_config.hbs | 5 + .../common/configs/services_config.hbs | 5 + .../common/modal_popups/select_groups_popup.hbs | 4 +- .../common/modal_popups/select_groups_popup.js | 85 ++++++-- .../main/service/info/config_test.js | 1 - 14 files changed, 260 insertions(+), 162 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/app/controllers/main/service/info/configs.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/service/info/configs.js b/ambari-web/app/controllers/main/service/info/configs.js index 5c3a27c..e1b8571 100644 --- a/ambari-web/app/controllers/main/service/info/configs.js +++ b/ambari-web/app/controllers/main/service/info/configs.js @@ -337,9 +337,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM loadStep: function () { console.log("TRACE: Loading configure for service"); var serviceName = this.get('content.serviceName'); + this.set('dependentServiceNames', App.StackService.find(serviceName).get('dependentServiceNames')); this.clearStep(); if (App.get('isClusterSupportsEnhancedConfigs')) { - this.setDependentServices(serviceName); this.loadConfigTheme(serviceName).always(function() { App.themesMapper.generateAdvancedTabs([serviceName]); }); @@ -830,6 +830,11 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM var serviceNames = this.get('servicesToLoad'); serviceNames.forEach(function(serviceName) { var serviceConfig = App.config.createServiceConfig(serviceName); + if (serviceName == this.get('content.serviceName')) { + serviceConfig.set('configGroups', this.get('configGroups')); + } else { + serviceConfig.set('configGroups', this.get('dependentConfigGroups').filterProperty('serviceName', serviceName)); + } //Make SecondaryNameNode invisible on enabling namenode HA var configsByService = this.get('allConfigs').filterProperty('serviceName', serviceName); databaseUtils.bootstrapDatabaseProperties(configsByService, serviceName); http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/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 1bab581..b20bec0 100644 --- a/ambari-web/app/controllers/wizard/step7_controller.js +++ b/ambari-web/app/controllers/wizard/step7_controller.js @@ -667,11 +667,14 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E } }, this); //STEP 6: Distribute configs by service and wrap each one in App.ServiceConfigProperty (configs -> serviceConfigs) - var self = this; - if (self.get('securityEnabled') && self.get('wizardController.name') == 'addServiceController') { - self.addKerberosDescriptorConfigs(configs, self.get('wizardController.kerberosDescriptorConfigs') || []); + if (this.get('securityEnabled') && self.get('wizardController.name') == 'addServiceController') { + this.addKerberosDescriptorConfigs(configs, self.get('wizardController.kerberosDescriptorConfigs') || []); } - self.setStepConfigs(configs, storedConfigs); + this.setStepConfigs(configs, storedConfigs); + this.checkHostOverrideInstaller(); + this.activateSpecialConfigs(); + this.selectProperService(); + var self = this; this.loadServerSideConfigsRecommendations().always(function () { // format descriptor configs var serviceConfigProperties = (self.get('content.serviceConfigProperties') || []).mapProperty('name'); @@ -679,7 +682,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E recommendedToDelete.forEach(function (c) { var name = Em.get(c, 'propertyName'); if (serviceConfigProperties.contains(name)) { - Em.set(self.get('_dependentConfigValues').findProperty('propertyName', name), 'toDelete', false); + Em.set(self.get('_dependentConfigValues').findProperty('propertyName', name).findProperty('fileName', serviceConfigProperties.get('filename')), 'toDelete', false); } }); @@ -688,9 +691,6 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E App.config.removeRangerConfigs(self.get('stepConfigs')); } self.updateDependentConfigs(); - self.checkHostOverrideInstaller(); - self.activateSpecialConfigs(); - self.selectProperService(); self.restoreRecommendedConfigs(); self.clearDependentConfigsByService(App.StackService.find().filterProperty('isSelected').mapProperty('serviceName')); self.set('isRecommendedLoaded', true); @@ -1177,20 +1177,26 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E /** * create overriden property and push it into Config group + * @param serviceConfigProperty + * @param group + * @param value + * @param isNotSaved * @param {App.ServiceConfigProperty} serviceConfigProperty * @return {App.ServiceConfigProperty} * @method addOverrideProperty */ - addOverrideProperty: function (serviceConfigProperty) { + addOverrideProperty: function (serviceConfigProperty, group, value, isNotSaved) { var overrides = serviceConfigProperty.get('overrides') || []; var newSCP = App.ServiceConfigProperty.create(serviceConfigProperty); - var group = this.get('selectedService.configGroups').findProperty('name', this.get('selectedConfigGroup.name')); + group = group || this.get('selectedService.configGroups').findProperty('name', this.get('selectedConfigGroup.name')); var valueForOverride = (serviceConfigProperty.get('widget') || serviceConfigProperty.get('displayType') == 'checkbox') ? serviceConfigProperty.get('value') : ''; newSCP.set('group', group); - newSCP.set('value', valueForOverride); + newSCP.set('value', value || valueForOverride); + newSCP.set('recommendedValue', value || valueForOverride); newSCP.set('isOriginalSCP', false); // indicated this is overridden value, newSCP.set('parentSCP', serviceConfigProperty); newSCP.set('isEditable', true); + newSCP.set('isNotSaved', isNotSaved); group.get('properties').pushObject(newSCP); overrides.pushObject(newSCP); newSCP.validate(); http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/app/mappers/configs/stack_config_properties_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/configs/stack_config_properties_mapper.js b/ambari-web/app/mappers/configs/stack_config_properties_mapper.js index 752cebb..1f09343 100644 --- a/ambari-web/app/mappers/configs/stack_config_properties_mapper.js +++ b/ambari-web/app/mappers/configs/stack_config_properties_mapper.js @@ -75,6 +75,10 @@ App.stackConfigPropertiesMapper = App.QuickDataMapper.create({ }, this); }, this); App.store.loadMany(this.get('model'), configs); + + App.StackService.find().filterProperty('id').forEach(function(service) { + this.setDependentServices(service); + }, this); } console.timeEnd('stackConfigMapper execution time'); }, @@ -107,5 +111,41 @@ App.stackConfigPropertiesMapper = App.QuickDataMapper.create({ */ getUIConfig: function(propertyName, siteName) { return App.config.get('preDefinedSiteProperties').filterProperty('filename', siteName).findProperty('name', propertyName); + }, + + /** + * runs <code>setDependentServicesAndFileNames<code> + * for stack properties for current service + * @method loadDependentConfigs + */ + setDependentServices: function(service) { + App.StackConfigProperty.find().filterProperty('serviceName', service.get('serviceName')).forEach(function(stackProperty) { + if (stackProperty.get('propertyDependedBy.length')) { + this._setDependentServices(stackProperty, 'propertyDependedBy', service); + } + }, this); + }, + /** + * defines service names for configs and set them to <code>dependentServiceNames<code> + * @param {App.StackConfigProperty} stackProperty + * @param {String} [key='propertyDependedBy'] - attribute to check dependent configs + * @param service + * @private + */ + _setDependentServices: function(stackProperty, key, service) { + key = key || 'propertyDependedBy'; + if (stackProperty.get(key + '.length') > 0) { + stackProperty.get(key).forEach(function(dependent) { + var tag = App.config.getConfigTagFromFileName(dependent.type); + /** setting dependent serviceNames (without current serviceName) **/ + var dependentProperty = App.StackConfigProperty.find(dependent.name + "_" + tag); + if (dependentProperty) { + if (dependentProperty.get('serviceName') && dependentProperty.get('serviceName') != service.get('serviceName') && !service.get('dependentServiceNames').contains(dependentProperty.get('serviceName'))) { + service.set('dependentServiceNames', service.get('dependentServiceNames').concat([dependentProperty.get('serviceName')])); + } + this._setDependentServices(dependentProperty, key, service); + } + }, this); + } } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index ee2117d..fa3d2e5 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -373,6 +373,8 @@ Em.I18n.translations = { 'popup.dependent.configs.dependencies.service.singular': 'in {0} service', 'popup.dependent.configs.dependencies.service.plural': 'in {0} services', + 'popup.dependent.configs.dependencies.for.groups': 'You are changing not default group, please select config group to which you want to save dependent configs from other services', + 'login.header':'Sign in', 'login.username':'Username', 'login.loginButton':'Sign in', http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/app/mixins/common/configs/enhanced_configs.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins/common/configs/enhanced_configs.js b/ambari-web/app/mixins/common/configs/enhanced_configs.js index 4bab5e0..cd27c61 100644 --- a/ambari-web/app/mixins/common/configs/enhanced_configs.js +++ b/ambari-web/app/mixins/common/configs/enhanced_configs.js @@ -40,8 +40,8 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ * @type {boolean} */ hasChangedDependencies: function() { - return App.get('isClusterSupportsEnhancedConfigs') && this.get('isControllerSupportsEnhancedConfigs') && this.get('_dependentConfigValues.length') > 0; - }.property('_dependentConfigValues.length'), + return App.get('isClusterSupportsEnhancedConfigs') && this.get('isControllerSupportsEnhancedConfigs') && this.get('changedProperties.length') > 0; + }.property('changedProperties.length'), /** * defines is block with changed dependent configs should be shown @@ -63,18 +63,18 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ return ['wizardStep7Controller'].contains(this.get('name')) && !App.Service.find().findProperty('serviceName', serviceName); }, - + dependenciesGroupMessage: Em.I18n.t('popup.dependent.configs.dependencies.for.groups'), /** * message fro alert box for dependent configs * @type {string} */ dependenciesMessage: function() { - var changedServices = this.get('changedProperties').mapProperty('serviceName').uniq(); - var cfgLen = this.get('changedProperties.length') === 1 ? 'singular' : 'plural'; + var changedServices = this.get('changedProperties').filterProperty('saveRecommended', true).mapProperty('serviceName').uniq(); + var cfgLen = this.get('changedProperties').filterProperty('saveRecommended', true).length === 1 ? 'singular' : 'plural'; var sLen = changedServices.length === 1 ? 'singular' : 'plural'; return Em.I18n.t('popup.dependent.configs.dependencies.config.' + cfgLen).format(this.get('changedProperties.length')) + Em.I18n.t('popup.dependent.configs.dependencies.service.' + sLen).format(changedServices.length); - }.property('changedProperties'), + }.property('changedProperties.length'), /** * values for dependent configs @@ -105,34 +105,44 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ * @type {Object[]} */ changedProperties: function() { - return this.get('_dependentConfigValues').filterProperty('saveRecommended', true); - }.property('[email protected]'), - /** - * dependent file names for configs - * @type {string[]} - */ - dependentFileNames: [], - - /** - * dependent service names for configs - * @type {string[]} - */ - dependentServiceNames: [], - - /** - * config groups for dependent services - * @type {App.ConfigGroup[]} - */ - dependentConfigGroups: [], + return this.get('_dependentConfigValues').filter(function(dp) { + return (this.get('selectedConfigGroup.isDefault') && Em.get(dp, 'configGroup').contains('Default')) + || [this.get('selectedConfigGroup.name'), this.get('selectedConfigGroup.dependentConfigGroups')[Em.get(dp, 'serviceName')]].contains(Em.get(dp, 'configGroup')); + }, this); + }.property('[email protected]', 'selectedConfigGroup'), /** - * contains config group name that need to be saved - * { - * serviceName: {String} configGroupName - * } - * @type {Object} + * defines if change dependent group message should be shown + * @type {boolean} */ - groupsToSave: {}, + showSelectGroupsPopup: function() { + return !this.get('selectedConfigGroup.isDefault') && this.get('selectedService.dependentServiceNames.length'); + }.property('selectedConfigGroup.isDefault'), + + /** + * set default values for dependentGroups + * @method setDependentGroups + */ + setDependentGroups: function () { + if (this.get('isControllerSupportsEnhancedConfigs') && !this.get('selectedConfigGroup.isDefault') && this.get('selectedService.dependentServiceNames.length')) { + this.get('selectedService.dependentServiceNames').forEach(function (serviceName) { + if (!this.get('selectedConfigGroup.dependentConfigGroups')[serviceName]) { + var stepConfig = this.get('stepConfigs').findProperty('serviceName', serviceName); + if (stepConfig) { + stepConfig.get('configGroups').filterProperty('isDefault', false).forEach(function (configGroup) { + this.get('selectedService.configGroups').filterProperty('isDefault', false).forEach(function (currentServiceGroup) { + if (currentServiceGroup.get('dependentConfigGroups')[serviceName] != configGroup.get('name')) { + var dependentGroups = $.extend({},this.get('selectedConfigGroup.dependentConfigGroups')); + dependentGroups[serviceName] = configGroup.get('name'); + this.set('selectedConfigGroup.dependentConfigGroups', dependentGroups); + } + }, this); + }, this); + } + } + }, this); + } + }.observes('selectedConfigGroup'), /******************************METHODS THAT WORKS WITH DEPENDENT CONFIGS *************************************/ @@ -143,7 +153,6 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ */ clearDependentConfigs: function() { this.setProperties({ - groupsToSave: {}, _dependentConfigValues: [] }); }, @@ -160,75 +169,33 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ this.set('_dependentConfigValues', cleanDependencies); }, - onConfigGroupChangeForEnhanced: function() { - if (this.get('name') === 'mainServiceInfoConfigsController') { - this.clearDependentConfigs(); - } else { - this.set('groupsToSave', {}); - } - this.get('dependentServiceNames').forEach(function(serviceName) { - var defaultGroup = this.get('dependentConfigGroups').filterProperty('service.serviceName', serviceName).findProperty('isDefault'); - this.get('groupsToSave')[serviceName] = defaultGroup.get('name'); - }, this); - }.observes('selectedConfigGroup'), - - - /** - * runs <code>setDependentServicesAndFileNames<code> - * for stack properties for current service - * @method loadDependentConfigs - */ - setDependentServices: function(serviceName) { - App.StackConfigProperty.find().forEach(function(stackProperty) { - if (stackProperty.get('serviceName') === serviceName && - (stackProperty.get('propertyDependedBy.length') > 0 || - stackProperty.get('propertyDependsOn.length') > 0)) { - this._setDependentServicesAndFileNames(stackProperty, 'propertyDependedBy'); - this._setDependentServicesAndFileNames(stackProperty, 'propertyDependsOn'); - } - }, this); - }, - /** * get config group object for current service * @param serviceName * @returns {App.ConfigGroup|null} */ getGroupForService: function(serviceName) { - if (this.get('stepConfigs.length') === 0) return null; - if (this.get('name') === 'wizardStep7Controller') { - return this.get('stepConfigs').findProperty('serviceName', serviceName).get('selectedConfigGroup'); + if (!this.get('stepConfigs') || this.get('stepConfigs.length') === 0) { + return null; + } + if (this.get('selectedService.serviceName') === serviceName) { + return this.get('selectedConfigGroup'); } else { - if (this.get('content.serviceName') === serviceName) { - return this.get('selectedConfigGroup'); - } else { + var stepConfig = this.get('stepConfigs').findProperty('serviceName', serviceName); + if (stepConfig) { + var groups = stepConfig.get('configGroups'); if (this.get('selectedConfigGroup.isDefault')) { - return this.get('dependentConfigGroups').filterProperty('service.serviceName', serviceName).findProperty('isDefault'); + return groups.length ? groups.findProperty('isDefault', true) : null; } else { - return this.get('dependentConfigGroups').findProperty('name', this.get('groupsToSave')[serviceName]); + return groups.length ? groups.findProperty('name', this.get('selectedConfigGroup.dependentConfigGroups')[serviceName]) : null; } + } else { + return null; } } }, /** - * show popup to select config group for dependent services - * to which dependent configs will ve saved - * @method showSelectGroupsPopup - */ - showSelectGroupPopup: function(event) { - var serviceName = event.context; - if (serviceName !== this.get('content.serviceName')) { - var groups = this.get('dependentConfigGroups').filterProperty('service.serviceName', serviceName).mapProperty('name').uniq(); - if (groups.length) { - var configs = this.get('_dependentConfigValues').filterProperty('serviceName', serviceName); - App.showSelectGroupsPopup(serviceName, groups, this.get('groupsToSave'), configs); - } - } - }, - - - /** * disable saving recommended value for current config * @param config * @param {boolean} saveRecommended @@ -347,7 +314,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ showChangedDependentConfigs: function(event, callback, secondary) { var self = this; if (this.get('_dependentConfigValues.length') > 0) { - App.showDependentConfigsPopup(this.get('_dependentConfigValues'), function() { + App.showDependentConfigsPopup(this.get('changedProperties'), function() { self.updateDependentConfigs(); if (callback) { callback(); @@ -362,6 +329,18 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ /** * + */ + changedDependentGroup: function() { + var dependentServices = this.get('stepConfigs').filter(function(stepConfig) { + return this.get('selectedService.dependentServiceNames').contains(stepConfig.get('serviceName')); + }, this); + App.showSelectGroupsPopup(this.get('selectedService.serviceName'), + this.get('selectedService.configGroups').findProperty('name', this.get('selectedConfigGroup.name')), + dependentServices, this.get('_dependentConfigValues')) + }, + + /** + * * @param jqXHR * @param ajaxOptions * @param error @@ -372,36 +351,6 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ App.ajax.defaultErrorHandler(jqXHR, opt.url, opt.method, jqXHR.status); }, - - /** - * defines file names for configs and set them to <code>dependentFileNames<code> and - * defines service names for configs and set them to <code>dependentServiceNames<code> - * @param {App.StackConfigProperty} stackProperty - * @param {String} [key='propertyDependedBy'] - attribute to check dependent configs - * @private - */ - _setDependentServicesAndFileNames: function(stackProperty, key) { - key = key || 'propertyDependedBy'; - if (stackProperty.get(key + '.length') > 0) { - stackProperty.get(key).forEach(function(dependent) { - var tag = App.config.getConfigTagFromFileName(dependent.type); - /** setting dependent fileNames (without '.xml') **/ - if (!this.get('dependentFileNames').contains(tag)) { - this.get('dependentFileNames').push(tag); - } - /** setting dependent serviceNames (without current serviceName) **/ - var dependentProperty = App.StackConfigProperty.find(dependent.name + "_" + tag); - if (dependentProperty) { - if (dependentProperty.get('serviceName') && !this.get('dependentServiceNames').contains(dependentProperty.get('serviceName')) && dependentProperty.get('serviceName') !== this.get('content.serviceName')) { - this.get('dependentServiceNames').push(dependentProperty.get('serviceName')); - } - this._setDependentServicesAndFileNames(dependentProperty, key); - } - }, this); - } - }, - - /** * saves values from response for dependent config properties to <code>_dependentConfigValues<code> * @param data @@ -448,7 +397,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ for (var propertyName in configObject[key].properties) { - var dependentProperty = this.get('_dependentConfigValues').filterProperty('propertyName', propertyName).findProperty('fileName', key); + var dependentProperty = this.get('_dependentConfigValues').filterProperty('propertyName', propertyName).filterProperty('fileName', key).findProperty('configGroup', group && Em.get(group,'name')); var cp = configProperties.findProperty('name', propertyName); var override = (notDefaultGroup && group && cp && cp.get('overrides')) ? cp.get('overrides').findProperty('group.name', group.get('name')) : null; @@ -488,11 +437,11 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ toAdd: isNewProperty, fileName: key, propertyName: propertyName, - configGroup: group ? group.get('name') : service.get('displayName') + " Default", + configGroup: group ? group.get('name') : "", value: initialValue, parentConfigs: parentPropertiesNames, serviceName: serviceName, - allowChangeGroup: serviceName != this.get('content.serviceName') && !this.get('selectedConfigGroup.isDefault'), + allowChangeGroup: !this.get('selectedService.isDefault') && service.get('serviceName') != stepConfig.get('serviceName') && stepConfig.get('configGroups.length') > 1, serviceDisplayName: service.get('displayName'), recommendedValue: recommendedValue }); @@ -566,7 +515,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ Em.keys(attributes).forEach(function (attributeName) { if (attributeName == 'delete') { if (!updateOnlyBoundaries) { - var dependentProperty = self.get('_dependentConfigValues').filterProperty('propertyName', propertyName).findProperty('fileName', siteName); + var dependentProperty = self.get('_dependentConfigValues').filterProperty('propertyName', propertyName).filterProperty('fileName', siteName).findProperty('configGroup', group && Em.get(group,'name')); if (dependentProperty) { Em.set(dependentProperty, 'toDelete', true); Em.set(dependentProperty, 'toAdd', false); @@ -581,10 +530,10 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ isDeleted: true, fileName: siteName, propertyName: propertyName, - configGroup: group ? group.get('name') : service.get('displayName') + " Default", + configGroup: group ? group.get('name') : "", parentConfigs: parentPropertiesNames, serviceName: service.get('serviceName'), - allowChangeGroup: service.get('serviceName') != self.get('content.serviceName') && !self.get('selectedConfigGroup.isDefault'), + allowChangeGroup: !self.get('selectedService.isDefault') && service.get('serviceName') != stepConfig.get('serviceName') && stepConfig.get('configGroups.length') > 1, serviceDisplayName: service.get('displayName'), recommendedValue: null }); @@ -617,12 +566,13 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ var self = this; this.get('stepConfigs').forEach(function(serviceConfigs) { var selectedGroup = self.getGroupForService(serviceConfigs.get('serviceName')); + if (selectedGroup) { + self._updateRecommendedValues(serviceConfigs, selectedGroup); - self._updateRecommendedValues(serviceConfigs, selectedGroup); + self._addRecommendedProperties(serviceConfigs, selectedGroup); - self._addRecommendedProperties(serviceConfigs, selectedGroup); - - self._removeUnRecommendedProperties(serviceConfigs, selectedGroup); + self._removeUnRecommendedProperties(serviceConfigs, selectedGroup); + } }); this.set('recommendationTimeStamp', (new Date).getTime()); }, @@ -635,7 +585,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ * @private */ _addRecommendedProperties: function(stepConfigs, selectedGroup) { - var propertiesToAdd = this.get('_dependentConfigValues').filterProperty('toAdd').filterProperty('serviceName', stepConfigs.get('serviceName')); + var propertiesToAdd = this.get('_dependentConfigValues').filterProperty('toAdd').filterProperty('serviceName', stepConfigs.get('serviceName')).filterProperty('configGroup', selectedGroup.get('name')); if (propertiesToAdd.length > 0) { propertiesToAdd.forEach(function(propertyToAdd) { if (!selectedGroup || selectedGroup.get('isDefault')) { @@ -661,7 +611,13 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ if (Em.get(propertyToAdd, 'isDeleted')) { this.get('_dependentConfigValues').removeObject(propertyToAdd); } - this.addOverrideProperty(cp, selectedGroup, Em.get(propertyToAdd, 'recommendedValue'), !Em.get(propertyToAdd, 'isDeleted')); + var overriddenProperty = cp.get('overrides') && cp.get('overrides').findProperty('group.name', selectedGroup.get('name')); + if (overriddenProperty) { + overriddenProperty.set('value', Em.get(propertyToAdd, 'recommendedValue')); + overriddenProperty.set('recommendedValue', Em.get(propertyToAdd, 'recommendedValue')); + } else { + this.addOverrideProperty(cp, selectedGroup, Em.get(propertyToAdd, 'recommendedValue'), !Em.get(propertyToAdd, 'isDeleted')); + } } Em.setProperties(propertyToAdd, { isDeleted: Em.get(propertyToAdd, 'isDeleted'), @@ -679,7 +635,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ * @private */ _removeUnRecommendedProperties: function(stepConfigs, selectedGroup) { - var propertiesToDelete = this.get('_dependentConfigValues').filterProperty('toDelete').filterProperty('serviceName', stepConfigs.get('serviceName')); + var propertiesToDelete = this.get('_dependentConfigValues').filterProperty('toDelete').filterProperty('serviceName', stepConfigs.get('serviceName')).filterProperty('configGroup', selectedGroup.get('name')); if (propertiesToDelete.length > 0) { propertiesToDelete.forEach(function(propertyToDelete) { @@ -724,7 +680,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create({ */ _updateRecommendedValues: function(stepConfigs, selectedGroup) { var propertiesToUpdate = this.get('_dependentConfigValues').filter(function(p) { - return !Em.get(p, 'toDelete') && !Em.get(p, 'toAdd') && Em.get(p, 'serviceName') == stepConfigs.get('serviceName'); + return !Em.get(p, 'toDelete') && !Em.get(p, 'toAdd') && Em.get(p, 'serviceName') == stepConfigs.get('serviceName') && Em.get(p, 'configGroup') == selectedGroup.get('name'); }); if (propertiesToUpdate.length > 0) { stepConfigs.get('configs').forEach(function (cp) { http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js b/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js index a6ee169..0a163ff 100644 --- a/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js +++ b/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js @@ -45,6 +45,10 @@ App.PreloadRequestsChainMixin = Em.Mixin.create({ isVersionDefault: Em.required(Function), /** + * temp stores dependent groups + */ + dependentConfigGroups: [], + /** * load all tag versions of cluster-env site * @returns {$.ajax} * @method loadClusterEnvSite @@ -296,6 +300,7 @@ App.PreloadRequestsChainMixin = Em.Mixin.create({ description: item.description, isDefault: false, parentConfigGroup: null, + serviceName: item.tag, service: App.Service.find().findProperty('serviceName', item.tag), hosts: item.hosts.mapProperty('host_name') }); http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/app/models/config_group.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/config_group.js b/ambari-web/app/models/config_group.js index edb3d34..8c19494 100644 --- a/ambari-web/app/models/config_group.js +++ b/ambari-web/app/models/config_group.js @@ -41,6 +41,13 @@ App.ConfigGroup = Ember.Object.extend({ serviceName: null, /** + * list of group names that shows which config + * groups should be updated as dependent when current is changed + * @type { serviceName: {String} } + */ + dependentConfigGroups: {}, + + /** * Parent configuration group for this group. * When {@link #isDefault} is true, this value is <code>null</code> * When {@link #isDefault} is false, this represents the configuration http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/app/models/configs/objects/service_config.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/configs/objects/service_config.js b/ambari-web/app/models/configs/objects/service_config.js index 430d15d..badd1dc 100644 --- a/ambari-web/app/models/configs/objects/service_config.js +++ b/ambari-web/app/models/configs/objects/service_config.js @@ -26,6 +26,7 @@ App.ServiceConfig = Ember.Object.extend({ restartRequiredMessage: '', restartRequiredHostsAndComponents: {}, configGroups: [], + dependentServiceNames: [], initConfigsLength: 0, // configs length after initialization in order to watch changes errorCount: function () { var overrideErrors = 0, @@ -67,7 +68,12 @@ App.ServiceConfig = Ember.Object.extend({ requiredByAgent.someProperty('isNotDefaultValue') || requiredByAgent.someProperty('isOverrideChanged') || this.get('configs.length') !== this.get('initConfigsLength'); - }.property('[email protected]', '[email protected]', 'configs.length', '[email protected]') + }.property('[email protected]', '[email protected]', 'configs.length', '[email protected]'), + + init: function() { + this._super(); + this.set('dependentServiceNames', App.StackService.find(this.get('serviceName')).get('dependentServiceNames') || []); + } }); App.SlaveConfigs = Ember.Object.extend({ http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/app/models/stack_service.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/stack_service.js b/ambari-web/app/models/stack_service.js index e86a312..b14cee0 100644 --- a/ambari-web/app/models/stack_service.js +++ b/ambari-web/app/models/stack_service.js @@ -43,6 +43,13 @@ App.StackService = DS.Model.extend({ configs: DS.attr('array'), requiredServices: DS.attr('array'), + /** + * contains array of serviceNames that have configs that + * depends on configs from current service + * @type {String[]} + */ + dependentServiceNames: DS.attr('array', {defaultValue: []}), + // Is the service a distributed filesystem isDFS: function () { var dfsServices = ['HDFS', 'GLUSTERFS']; http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/app/templates/common/configs/service_config.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/configs/service_config.hbs b/ambari-web/app/templates/common/configs/service_config.hbs index 8840a1e..c3dce57 100644 --- a/ambari-web/app/templates/common/configs/service_config.hbs +++ b/ambari-web/app/templates/common/configs/service_config.hbs @@ -90,6 +90,11 @@ <span>{{dependenciesMessage}}</span> <a href="#" {{action "showChangedDependentConfigs" target="controller"}}>{{t common.showDetails}}</a> </div> + {{#if showSelectGroupsPopup}} + <div class="alert alert-warning"> + <span>{{dependenciesGroupMessage}}</span> <a href="#" {{action "changedDependentGroup" target="controller"}}>{{t common.showDetails}}</a> + </div> + {{/if}} </div> </div> {{/unless}} http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/app/templates/common/configs/services_config.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/configs/services_config.hbs b/ambari-web/app/templates/common/configs/services_config.hbs index bce5082..cc1c3b0 100644 --- a/ambari-web/app/templates/common/configs/services_config.hbs +++ b/ambari-web/app/templates/common/configs/services_config.hbs @@ -36,6 +36,11 @@ <span>{{dependenciesMessage}}</span> <a href="#" {{action "showChangedDependentConfigs" target="controller"}}>{{t common.showDetails}}</a> </div> {{/if}} +{{#if showSelectGroupsPopup}} + <div class="alert alert-warning"> + <span>{{dependenciesGroupMessage}}</span> <a href="#" {{action "changedDependentGroup" target="controller"}}>{{t common.showDetails}}</a> + </div> +{{/if}} {{view App.ServiceConfigContainerView}} {{#if controller.isRecommendedLoaded}} <p class="loading align-center"></p> http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/app/templates/common/modal_popups/select_groups_popup.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/modal_popups/select_groups_popup.hbs b/ambari-web/app/templates/common/modal_popups/select_groups_popup.hbs index 00a24ef..2c45af5 100644 --- a/ambari-web/app/templates/common/modal_popups/select_groups_popup.hbs +++ b/ambari-web/app/templates/common/modal_popups/select_groups_popup.hbs @@ -18,9 +18,9 @@ <form class="form-horizontal"> <div class="form-group"> - <label class="col-sm-2 control-label"><strong>{{view.parentView.serviceName}} </strong> </label> + <label class="col-sm-2 control-label"><strong>{{view.serviceName}} </strong> </label> <div class="col-sm-8"> - {{view Ember.Select contentBinding="view.parentView.groups" valueBinding="view.parentView.selectedGroup"}} + {{view Ember.Select contentBinding="view.groups" valueBinding="view.selectedGroup"}} </div> </div> </form> http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/app/views/common/modal_popups/select_groups_popup.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/modal_popups/select_groups_popup.js b/ambari-web/app/views/common/modal_popups/select_groups_popup.js index 3774708..7b5a280 100644 --- a/ambari-web/app/views/common/modal_popups/select_groups_popup.js +++ b/ambari-web/app/views/common/modal_popups/select_groups_popup.js @@ -20,33 +20,88 @@ var App = require('app'); /** * Show confirmation popup - * * @param {String} serviceName - * @param {String[]} groups - * @param {Object} groupsToSave + * @param {string} selectedServiceName + * @param {App.ConfigGroup} selectedConfigGroup + * @param {App.ServiceConfig[]} dependentStepConfigs * @param {Object[]} configs * @return {App.ModalPopup} */ -App.showSelectGroupsPopup = function (serviceName, groups, groupsToSave, configs) { +App.showSelectGroupsPopup = function (selectedServiceName, selectedConfigGroup, dependentStepConfigs, configs) { return App.ModalPopup.show({ encodeBody: false, primary: Em.I18n.t('common.save'), - secondary: Em.I18n.t('common.cancel'), header: Em.I18n.t('popup.dependent.configs.select.config.group.header'), - groups: groups, - serviceName: serviceName, - groupsToSave: groupsToSave, - selectedGroup: '', + selectedServiceName: selectedServiceName, + selectedConfigGroup: selectedConfigGroup, + dependentStepConfigs: dependentStepConfigs, + selectedGroups: {}, didInsertElement: function() { - this._super(); - this.set('selectedGroup', this.get('groupsToSave')[this.get('serviceName')]); + this.set('selectedGroups', $.extend({},selectedConfigGroup.get('dependentConfigGroups'))); }, - bodyClass: Em.View.extend({ - templateName: require('templates/common/modal_popups/select_groups_popup') + bodyClass: Em.CollectionView.extend({ + content: dependentStepConfigs, + itemViewClass: Em.View.extend({ + templateName: require('templates/common/modal_popups/select_groups_popup'), + didInsertElement: function() { + this.set('selectedGroup', this.get('parentView.parentView.selectedConfigGroup.dependentConfigGroups')[this.get('serviceName')]); + }, + serviceName: function() { + return this.get('content').get('serviceName'); + }.property('content'), + selectedGroup: null, + updateGroup: function() { + var dependentGroups = $.extend({},this.get('parentView.parentView.selectedConfigGroup.dependentConfigGroups')); + dependentGroups[this.get('serviceName')] = this.get('selectedGroup'); + this.set('parentView.parentView.selectedConfigGroup.dependentConfigGroups', dependentGroups); + }.observes('selectedGroup'), + groups: function() { + return this.get('content').get('configGroups').filterProperty('isDefault', false).mapProperty('name'); + }.property('content') + }) }), onPrimary: function () { this._super(); - this.get('groupsToSave')[this.get('serviceName')] = this.get('selectedGroup'); - configs.setEach('configGroup', this.get('groupsToSave')[this.get('serviceName')]); + Object.keys(this.get('selectedConfigGroup.dependentConfigGroups')).forEach(function(serviceName) { + var selectedGroupName = this.get('selectedConfigGroup.dependentConfigGroups')[serviceName]; + var currentGroupName = this.get('selectedGroups')[serviceName] || ""; + var configGroup = this.get('dependentStepConfigs').findProperty('serviceName', serviceName).get('configGroups').findProperty('name', selectedGroupName); + if (selectedGroupName != currentGroupName) { + /** changing config group for _dependentConfigValues **/ + configs.filterProperty('serviceName', serviceName).filterProperty('configGroup', selectedGroupName).forEach(function (c) { + if (configs.filterProperty('serviceName', serviceName).filterProperty('configGroup', currentGroupName)) { + configs.removeObject(c); + } + }); + configs.filterProperty('serviceName', serviceName).filterProperty('configGroup', currentGroupName).setEach('configGroup', selectedGroupName); + /** danger part!!!! changing config group ***/ + this.get('dependentStepConfigs').findProperty('serviceName', serviceName).get('configs').forEach(function(cp) { + var dependentConfig = configs.filterProperty('propertyName', cp.get('name')).filterProperty('fileName', App.config.getConfigTagFromFileName(cp.get('filename'))).findProperty('configGroup', selectedGroupName); + var recommendedValue = dependentConfig && Em.get(dependentConfig, 'recommendedValue'); + if (cp.get('overrides')) { + var currentGroupOverride = cp.get('overrides').findProperty('group.name', currentGroupName); + if (currentGroupOverride && currentGroupOverride.get('initialValue') != currentGroupOverride.get('recommendedValue')) { + currentGroupOverride.set('group', configGroup); + currentGroupOverride.set('recommendedValue', recommendedValue); + currentGroupOverride.set('value', recommendedValue); + } else { + var selectedGroupOverride = cp.get('overrides').findProperty('group.name', configGroup.get('name')); + if (selectedGroupOverride) { + selectedGroupOverride.set('recommendedValue', recommendedValue); + selectedGroupOverride.set('value', recommendedValue); + } else { + App.get('router.mainServiceInfoConfigsController').addOverrideProperty(cp, configGroup, recommendedValue); + } + } + } else { + App.get('router.mainServiceInfoConfigsController').addOverrideProperty(cp, configGroup, recommendedValue); + } + }, this) + } + }, this); + }, + onSecondary: function() { + this._super(); + this.get('selectedConfigGroup').set('dependentConfigGroups', this.get('selectedGroups')); } }); }; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/5e0ee82b/ambari-web/test/controllers/main/service/info/config_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/service/info/config_test.js b/ambari-web/test/controllers/main/service/info/config_test.js index df62723..4520b89 100644 --- a/ambari-web/test/controllers/main/service/info/config_test.js +++ b/ambari-web/test/controllers/main/service/info/config_test.js @@ -363,7 +363,6 @@ describe("App.MainServiceInfoConfigsController", function () { mainServiceInfoConfigsController.set('groupsToSave', { HDFS: 'my cool group'}); mainServiceInfoConfigsController.set('_dependentConfigValues', Em.A([{name: 'prop_1'}])); mainServiceInfoConfigsController.doCancel(); - expect(App.isEmptyObject(mainServiceInfoConfigsController.get('groupsToSave'))).to.be.true; expect(App.isEmptyObject(mainServiceInfoConfigsController.get('_dependentConfigValues'))).to.be.true; }); });
