Browse Source

AMBARI-12244. Empty review content on step 8 of installer after page refresh and visiting Customize Services loses config customizations (alexantonenko)

Alex Antonenko 10 years ago
parent
commit
dcbd7f5b75

+ 18 - 1
ambari-web/app/controllers/wizard/step7_controller.js

@@ -686,7 +686,24 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
       if (rangerService && !rangerService.get('isInstalled') && !rangerService.get('isSelected')) {
         App.config.removeRangerConfigs(self.get('stepConfigs'));
       }
-      self.updateDependentConfigs();
+      if (!self.get('content.serviceConfigProperties.length')) {
+        // for Add Service just remove or add dependent properties and ignore config values changes
+        // for installed services only
+        if (self.get('wizardController.name') == 'addServiceController') {
+          self.addRemoveDependentConfigs(self.get('installedServiceNames'));
+          self.clearDependenciesForInstalledServices(self.get('installedServiceNames'), self.get('stepConfigs'));
+        }
+        // * add dependencies based on recommendations
+        // * update config values with recommended
+        // * remove properties recieved from recommendations
+        self.updateDependentConfigs();
+      } else {
+        // control flow for managing dependencies for stored configs,
+        // * Don't update values with recommended to save user's input
+        // * add dependencies based on user's input for parent configs
+        // * remove dependencies based on user's input for parent configs
+        self.addRemoveDependentConfigs();
+      }
       self.restoreRecommendedConfigs();
       self.clearDependentConfigsByService(App.StackService.find().filterProperty('isSelected').mapProperty('serviceName'));
       self.set('isRecommendedLoaded', true);

+ 57 - 4
ambari-web/app/mixins/common/configs/enhanced_configs.js

@@ -170,6 +170,40 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
     this.set('_dependentConfigValues', cleanDependencies);
   },
 
+  /**
+   * Remove configs from <code>_dependentConfigValues</code> which depends between installed services only.
+   *
+   * @param {String[]} installedServices
+   * @param {App.ServiceConfig[]} stepConfigs
+   */
+  clearDependenciesForInstalledServices: function(installedServices, stepConfigs) {
+    var allConfigs = stepConfigs.mapProperty('configs').filter(function(item) {
+      return item.length;
+    }).reduce(function(p, c) {
+      if (p) {
+        return p.concat(c);
+      }
+    });
+    var cleanDependencies = this.get('_dependentConfigValues').reject(function(item) {
+      if (installedServices.contains(Em.get(item, 'serviceName'))) {
+        var parentConfigs = Em.getWithDefault(item, 'parentConfigs', []);
+        if (!parentConfigs.length) {
+          return true;
+        }
+        // check that all parent properties from installed service
+        return !parentConfigs.reject(function(parentConfigName) {
+          var property = allConfigs.findProperty('name', parentConfigName);
+          if (!property) {
+            return false;
+          }
+          return installedServices.contains(Em.get(property, 'serviceName'));
+        }).length;
+      }
+      return false;
+    });
+    this.set('_dependentConfigValues', cleanDependencies);
+  },
+
   /**
    * get config group object for current service
    * @param serviceName
@@ -431,15 +465,15 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
             if (dependentProperty) {
               Em.set(dependentProperty, 'value', initialValue);
               Em.set(dependentProperty, 'recommendedValue', recommendedValue);
-              Em.set(dependentProperty, 'toDelete', false);
-              Em.set(dependentProperty, 'toAdd', false);
+              Em.set(dependentProperty, 'toDelete', false); // handled in <code>saveRecommendedAttributes</code>
+              Em.set(dependentProperty, 'toAdd', isNewProperty);
               Em.set(dependentProperty, 'parentConfigs', dependentProperty.parentConfigs.concat(parentPropertiesNames).uniq());
             } else {
               this.get('_dependentConfigValues').pushObject({
                 saveRecommended: true,
                 saveRecommendedDefault: true,
                 toDelete: false,
-                isDeleted: false,
+                isDeleted: false, // handled in <code>saveRecommendedAttributes</code>
                 toAdd: isNewProperty,
                 fileName: key,
                 propertyName: propertyName,
@@ -586,6 +620,25 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
     this.set('recommendationTimeStamp', (new Date).getTime());
   },
 
+  /**
+   * Add and remove dependencies based on recommendations
+   *
+   * @param {String[]} [serviceNames=undefined] - list of services to apply changes
+   */
+  addRemoveDependentConfigs: function(serviceNames) {
+    var self = this;
+    this.get('stepConfigs').forEach(function(serviceConfigs) {
+      if (serviceNames && !serviceNames.contains(serviceConfigs.get('serviceName'))) {
+        return;
+      }
+      var selectedGroup = self.getGroupForService(serviceConfigs.get('serviceName'));
+      if (selectedGroup) {
+        self._addRecommendedProperties(serviceConfigs, selectedGroup);
+        self._removeUnRecommendedProperties(serviceConfigs, selectedGroup);
+      }
+    });
+  },
+
 
   /**
    * add configs that was recommended and wasn't present in stepConfigs
@@ -755,7 +808,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
    * Helper method to get property from the <code>stepConfigs</code>
    *
    * @param {String} name - config property name
-   * @param {} fileName - config property filename
+   * @param {String} fileName - config property filename
    * @return {App.ServiceConfigProperty|Boolean} - App.ServiceConfigProperty instance or <code>false</code> when property not found
    */
   findConfigProperty: function(name, fileName) {

+ 13 - 1
ambari-web/app/mixins/common/serverValidator.js

@@ -114,10 +114,22 @@ App.ServerValidatorMixin = Em.Mixin.create({
    * @returns {*}
    */
   loadServerSideConfigsRecommendations: function() {
+    var self = this;
     // if extended controller doesn't support recommendations ignore this call but keep promise chain
     if (!this.get('isControllerSupportsEnhancedConfigs')) {
       return $.Deferred().resolve().promise();
     }
+    var recommendations = this.get('hostGroups');
+    // send user's input based on stored configurations
+    if (this.get('content.serviceConfigProperties.length')) {
+      recommendations.blueprint.configurations = blueprintUtils.buildConfigsJSON(this.get('services'), this.get('stepConfigs'));
+    }
+    // for add service send configurations for installed services on first transition to Customize Services step
+    if (!this.get('content.serviceConfigProperties.length') && this.get('wizardController.name') === 'addServiceController') {
+      recommendations.blueprint.configurations = blueprintUtils.buildConfigsJSON(this.get('services'), this.get('stepConfigs').filter(function(serviceConfigs) {
+        return self.get('installedServiceNames').contains(serviceConfigs.get('serviceName'));
+      }));
+    }
     return App.ajax.send({
       'name': 'config.recommendations',
       'sender': this,
@@ -127,7 +139,7 @@ App.ServerValidatorMixin = Em.Mixin.create({
           recommend: 'configurations',
           hosts: this.get('hostNames'),
           services: this.get('serviceNames'),
-          recommendations: this.get('hostGroups')
+          recommendations: recommendations
         }
       },
       'success': 'loadRecommendationsSuccess',

+ 1 - 0
ambari-web/app/models/configs/objects/service_config_property.js

@@ -113,6 +113,7 @@ App.ServiceConfigProperty = Em.Object.extend({
   showLabel: true,
   error: false,
   warn: false,
+  previousValue: null, // cached value before changing config <code>value</code>
 
   /**
    * List of <code>isFinal</code>-values for overrides

+ 7 - 1
ambari-web/app/routes/installer.js

@@ -333,7 +333,13 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
         controller.saveServiceConfigProperties(wizardStep7Controller);
         controller.saveServiceConfigGroups(wizardStep7Controller);
         controller.setDBProperty('recommendationsConfigs', wizardStep7Controller.get('recommendationsConfigs'));
-        router.transitionTo('step8');
+        App.clusterStatus.setClusterStatus({
+          localdb: App.db.data
+        }, {
+          alwaysCallback: function() {
+            router.transitionTo('step8');
+          }
+        });
       }
     }
   }),

+ 5 - 5
ambari-web/app/views/common/configs/widgets/combo_config_widget_view.js

@@ -104,12 +104,12 @@ App.ComboConfigWidgetView = App.ConfigWidgetView.extend({
    * @param {Object} e
    */
   setConfigValue: function(e) {
-    var configValueChanged = this.get('config.value') != e.context;
     this.set('config.value', e.context);
     this.set('content.value', this.generateWidgetValue(e.context));
-    if (configValueChanged) {
+    if (this.get('config.previousValue') != this.get('config.value')) {
       this.sendRequestRorDependentConfigs(this.get('config'));
     }
+    this.set('config.previousValue', this.get('config.value'));
   },
 
   /**
@@ -143,9 +143,9 @@ App.ComboConfigWidgetView = App.ConfigWidgetView.extend({
     }
   },
 
-  setValue: function() {
-    this.setConfigValue({ context: this.get('config.value') });
-  },
+  // setValue: function() {
+  //   this.setConfigValue({ context: this.get('config.value') });
+  // },
 
   isValueCompatibleWithWidget: function() {
     var res = this._super() && this.get('content.valuesList').someProperty('configValue', this.get('config.value'));