Repository: ambari
Updated Branches:
  refs/heads/trunk dc366dbe7 -> 598835003


AMBARI-15715 ASW send invalid requests for config groups. (ababiichuk)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/59883500
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/59883500
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/59883500

Branch: refs/heads/trunk
Commit: 598835003e036f7c72d61905cdeab3a0a63eb31d
Parents: dc366db
Author: ababiichuk <ababiic...@hortonworks.com>
Authored: Tue Apr 5 17:43:05 2016 +0300
Committer: ababiichuk <ababiic...@hortonworks.com>
Committed: Wed Apr 6 12:58:36 2016 +0300

----------------------------------------------------------------------
 .../controllers/main/service/info/configs.js    |   8 +-
 ambari-web/app/controllers/wizard.js            |   4 +-
 .../app/controllers/wizard/step7_controller.js  |  30 ++++-
 .../app/controllers/wizard/step8_controller.js  | 130 ++++---------------
 ...onfig_with_override_recommendation_parser.js |   1 -
 .../app/mixins/common/configs/configs_saver.js  |  95 ++++++++------
 .../main/service/configs/config_overridable.js  |   5 +-
 ambari-web/app/utils/config.js                  |  70 +++++-----
 .../configs/service_configs_by_category_view.js |  38 +++---
 .../main/service/info/config_test.js            |  24 ----
 .../test/controllers/wizard/step7_test.js       |  22 ++--
 .../test/controllers/wizard/step8_test.js       | 123 ------------------
 ambari-web/test/utils/config_test.js            |   6 +-
 .../service_configs_by_category_view_test.js    |  97 --------------
 14 files changed, 181 insertions(+), 472 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/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 5208694..2bcaf2e 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -440,7 +440,13 @@ App.MainServiceInfoConfigsController = 
Em.Controller.extend(App.ConfigsLoader, A
               }
             } else {
               var isEditable = self.get('canEdit') && configGroup.get('name') 
== self.get('selectedConfigGroup.name');
-              allConfigs.push(App.config.createCustomGroupConfig(prop, 
fileName, config.properties[prop], configGroup, isEditable));
+              allConfigs.push(App.config.createCustomGroupConfig({
+                propertyName: prop,
+                filename: fileName,
+                value: config.properties[prop],
+                savedValue: config.properties[prop],
+                isEditable: isEditable
+              }, configGroup));
             }
           }
         });

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js 
b/ambari-web/app/controllers/wizard.js
index 26893b5..c349e55 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -943,16 +943,14 @@ App.WizardController = 
Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
    */
   saveServiceConfigGroups: function (stepController, isAddService) {
     var serviceConfigGroups = [],
-      isForInstalledService = false,
       hosts = isAddService ? 
App.router.get('addServiceController').getDBProperty('hosts') : 
this.getDBProperty('hosts');
     stepController.get('stepConfigs').forEach(function (service) {
       // mark group of installed service
-      if (service.get('selected') === false) isForInstalledService = true;
+      var isForInstalledService = service.get('selected') === false;
       service.get('configGroups').forEach(function (configGroup) {
         var properties = [];
         configGroup.get('properties').forEach(function (property) {
           properties.push({
-            isRequiredByAgent: property.get('isRequiredByAgent'),
             name: property.get('name'),
             value: property.get('value'),
             isFinal: property.get('isFinal'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/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 1df119e..77af047 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -207,6 +207,12 @@ App.WizardStep7Controller = 
Em.Controller.extend(App.ServerValidatorMixin, App.E
   filter: '',
 
   /**
+   * Defines if configs can be editable
+   * @type {boolean}
+   */
+  canEdit: true,
+
+  /**
    * list of dependencies that are user to set init value of config
    *
    * @type {Object}
@@ -399,7 +405,7 @@ App.WizardStep7Controller = 
Em.Controller.extend(App.ServerValidatorMixin, App.E
         if (item.tag === serviceName) {
           var groupHosts = item.hosts.mapProperty('host_name');
           configGroups.push({
-            id: serviceName + item.id,
+            id: App.ServiceConfigGroup.groupId(serviceName, item.group_name),
             config_group_id: item.id,
             name: item.group_name,
             description: item.description,
@@ -494,9 +500,14 @@ App.WizardStep7Controller = 
Em.Controller.extend(App.ServerValidatorMixin, App.E
             "isFinal": hostOverrideIsFinal,
             "savedIsFinal": hostOverrideIsFinal,
             "isEditable": false
-          }, group, true);
+          }, group);
         } else {
-          params.serviceConfigs.push(App.config.createCustomGroupConfig(prop, 
fileName, config.properties[prop], group));
+          params.serviceConfigs.push(App.config.createCustomGroupConfig({
+            propertyName: prop,
+            filename: fileName,
+            value: config.properties[prop],
+            savedValue: config.properties[prop]
+          }, group));
         }
       }
     });
@@ -1121,9 +1132,9 @@ App.WizardStep7Controller = 
Em.Controller.extend(App.ServerValidatorMixin, App.E
   setGroupsToDelete: function (groups) {
     var groupsToDelete = this.get('groupsToDelete');
     groups.forEach(function (group) {
-      if (group.get('id'))
+      if (group.get('configGroupId'))
         groupsToDelete.push({
-          id: group.get('id')
+          configGroupId: group.get('configGroupId')
         });
     });
     this.get('wizardController').setDBProperty('groupsToDelete', 
groupsToDelete);
@@ -1181,7 +1192,13 @@ App.WizardStep7Controller = 
Em.Controller.extend(App.ServerValidatorMixin, App.E
               overriddenSCP = App.ServiceConfigProperty.create(parentSCP);
               overriddenSCP.set('parentSCP', parentSCP);
             } else {
-              overriddenSCP = 
App.config.createCustomGroupConfig(propertyData.name, propertyData.filename, 
propertyData.value, modelGroup, true, false);
+              overriddenSCP = App.config.createCustomGroupConfig({
+                propertyName: propertyData.name,
+                filename: propertyData.filename,
+                value: propertyData.value,
+                savedValue: propertyData.value,
+                isEditable: false
+              }, modelGroup);
               this.get('stepConfigs').findProperty('serviceName', 
service.serviceName).get('configs').pushObject(overriddenSCP);
             }
               overriddenSCP.set('isOriginalSCP', false);
@@ -1284,7 +1301,6 @@ App.WizardStep7Controller = 
Em.Controller.extend(App.ServerValidatorMixin, App.E
       var group = 
this.get('selectedService.configGroups').findProperty('name', 
selectedGroup.get('name'));
       var newSCP = App.config.createOverride(config, {value: valueForOverride, 
recommendedValue: valueForOverride}, group);
       configOverrides.push(newSCP);
-      group.get('properties').pushObject(newSCP);
       this.set('overrideToAdd', null);
     }
     configOverrides.setEach('isEditable', !selectedGroup.get('isDefault'));

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/ambari-web/app/controllers/wizard/step8_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step8_controller.js 
b/ambari-web/app/controllers/wizard/step8_controller.js
index 4658b8e..f708a5f 100644
--- a/ambari-web/app/controllers/wizard/step8_controller.js
+++ b/ambari-web/app/controllers/wizard/step8_controller.js
@@ -219,7 +219,8 @@ App.WizardStep8Controller = 
Em.Controller.extend(App.AddSecurityConfigs, App.wiz
    */
   formatProperties: function () {
     this.get('content.serviceConfigProperties').forEach(function 
(_configProperty) {
-      _configProperty.value = App.config.trimProperty(_configProperty, false);
+      _configProperty.value = (typeof _configProperty.value === "boolean")
+        ? _configProperty.value.toString() : 
App.config.trimProperty(_configProperty, false);
     });
   },
 
@@ -228,22 +229,9 @@ App.WizardStep8Controller = 
Em.Controller.extend(App.AddSecurityConfigs, App.wiz
    * @method loadConfigs
    */
   loadConfigs: function () {
-    //storedConfigs contains custom configs as well
-    var configs = this.get('content.serviceConfigProperties');
-    configs.forEach(function (_config) {
-      _config.value = (typeof _config.value === "boolean") ? 
_config.value.toString() : _config.value;
-    });
-    var customGroupConfigs = [];
-    var allConfigs = configs.filter(function (config) {
-      if (config.group) {
-        customGroupConfigs.push(config);
-        return false;
-      } else {
-        return true;
-      }
-    });
-    this.set('customNonDefaultGroupConfigs', customGroupConfigs);
-    this.set('configs', allConfigs);
+    this.set('configs', 
this.get('content.serviceConfigProperties').filter(function (config) {
+      return !config.group;
+    }));
   },
 
   /**
@@ -1454,113 +1442,47 @@ App.WizardStep8Controller = 
Em.Controller.extend(App.AddSecurityConfigs, App.wiz
    */
   createConfigurationGroups: function () {
     var configGroups = 
this.get('content.configGroups').filterProperty('is_default', false);
-    var clusterName = this.get('clusterName');
-    var sendData = [];
-    var updateData = [];
-    var timeTag = (new Date).getTime();
     var groupsToDelete = 
App.router.get(this.get('content.controllerName')).getDBProperty('groupsToDelete');
     if (groupsToDelete && groupsToDelete.length > 0) {
       this.removeInstalledServicesConfigurationGroups(groupsToDelete);
     }
     configGroups.forEach(function (configGroup) {
-      var groupConfigs = [];
-      var groupData = {
-        "cluster_name": clusterName,
-        "group_name": configGroup.name,
-        "tag": configGroup.service_id,
-        "description": configGroup.description,
-        "hosts": [],
-        "desired_configs": []
-      };
-      configGroup.hosts.forEach(function (hostName) {
-        groupData.hosts.push({"host_name": hostName});
-      });
-      // get properties that was created for non-default config group
-      configGroup.properties = 
configGroup.properties.concat(this.get('customNonDefaultGroupConfigs').filterProperty('group',
 configGroup.name));
-      //wrap properties into Em.Object to make them compatible with 
buildGroupDesiredConfigs method
-      configGroup.properties.forEach(function (property) {
-        groupConfigs.push(Em.Object.create(property));
-      });
-      groupData.desired_configs = this.buildGroupDesiredConfigs(groupConfigs, 
timeTag);
-      // check for group from installed service
-      if (configGroup.is_for_installed_service === true) {
-        // if group is a new one, create it
-        if (!configGroup.id) {
-          sendData.push({"ConfigGroup": groupData});
-        } else if (configGroup.is_for_update){
-          // update an existing group
-          groupData.id = configGroup.id;
-          updateData.push({"ConfigGroup": groupData});
-        }
-      } else {
-        sendData.push({"ConfigGroup": groupData});
+      if (configGroup.is_for_update || !configGroup.config_group_id) {
+        this.saveGroup(configGroup.properties, configGroup, 
this.getServiceConfigNote('', configGroup.service_id));
       }
-      //each group should have unique tag to prevent overriding configs from 
common sites
-      timeTag++;
-    }, this);
-    if (sendData.length > 0) {
-      this.applyConfigurationGroups(sendData);
-    }
-    if (updateData.length > 0) {
-      this.applyInstalledServicesConfigurationGroup(updateData);
-    }
-  },
-
-  /**
-   * construct desired_configs for config groups from overriden properties
-   * @param configs
-   * @param timeTag
-   * @return {Array}
-   * @private
-   * @method buildGroupDesiredConfigs
-   */
-  buildGroupDesiredConfigs: function (configs, timeTag) {
-    var sites = [];
-    var time = timeTag || (new Date).getTime();
-    var siteFileNames = configs.mapProperty('filename').uniq();
-    sites = siteFileNames.map(function (filename) {
-      return {
-        type: filename.replace('.xml', ''),
-        tag: 'version' + time,
-        properties: []
-      };
-    });
-
-    configs.forEach(function (config) {
-      var type = config.get('filename').replace('.xml', '');
-      var site = sites.findProperty('type', type);
-      site.properties.push(config);
-    });
-
-    return sites.map(function (site) {
-      return this.createDesiredConfig(site.type, site.tag, site.properties, 
null, true);
     }, this);
   },
 
   /**
-   * Create new config groups request
-   * Queued request
-   * @param {Object[]} sendData
-   * @method applyConfigurationGroups
+   * add request to create config group to queue
+   *
+   * @param data
+   * @method createConfigGroup
    */
-  applyConfigurationGroups: function (sendData) {
+  createConfigGroup: function(data) {
     this.addRequestToAjaxQueue({
       name: 'wizard.step8.apply_configuration_groups',
+      sender: this,
       data: {
-        data: JSON.stringify(sendData)
+        data: JSON.stringify(data)
       }
     });
   },
 
   /**
-   * Update existed config groups
-   * Separated request for each group
-   * @param {Object[]} updateData
-   * @method applyInstalledServicesConfigurationGroup
+   * add request to update config group to queue
+   *
+   * @param data {Object}
+   * @method updateConfigGroup
    */
-  applyInstalledServicesConfigurationGroup: function (updateData) {
-    updateData.forEach(function (item) {
-      
App.router.get('mainServiceInfoConfigsController').putConfigGroupChanges(item);
+  updateConfigGroup: function (data) {
+    this.addRequestToAjaxQueue({
+      name: 'config_groups.update_config_group',
+      sender: this,
+      data: {
+        id: data.ConfigGroup.id,
+        configGroup: data
+      }
     });
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/ambari-web/app/mixins/common/configs/config_with_override_recommendation_parser.js
----------------------------------------------------------------------
diff --git 
a/ambari-web/app/mixins/common/configs/config_with_override_recommendation_parser.js
 
b/ambari-web/app/mixins/common/configs/config_with_override_recommendation_parser.js
index 7272905..0898ed9 100644
--- 
a/ambari-web/app/mixins/common/configs/config_with_override_recommendation_parser.js
+++ 
b/ambari-web/app/mixins/common/configs/config_with_override_recommendation_parser.js
@@ -88,7 +88,6 @@ App.ConfigWithOverrideRecommendationParser = 
Em.Mixin.create(App.ConfigRecommend
                        "isEditable": true
                };
                var override = App.config.createOverride(config, coreObject, 
configGroup);
-               configGroup.get('properties').pushObject(override);
 
                this.applyRecommendation(Em.get(config, 'name'), Em.get(config, 
'filename'), configGroup.get('name'),
                        recommendedValue, this._getInitialValue(override), 
parentProperties);

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/ambari-web/app/mixins/common/configs/configs_saver.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/configs_saver.js 
b/ambari-web/app/mixins/common/configs/configs_saver.js
index 9a945db..c78c3de 100644
--- a/ambari-web/app/mixins/common/configs/configs_saver.js
+++ b/ambari-web/app/mixins/common/configs/configs_saver.js
@@ -145,22 +145,13 @@ App.ConfigsSaverMixin = Em.Mixin.create({
         var serviceName = stepConfig.get('serviceName');
         var configs = stepConfig.get('configs');
         var configGroup = this.getGroupFromModel(serviceName);
-        if (configGroup) {
-          if (configGroup.get('isDefault')) {
+        if (configGroup && !configGroup.get('isDefault')) {
 
-            var configsToSave = this.getServiceConfigToSave(serviceName, 
configs);
+          var overriddenConfigs = this.getConfigsForGroup(configs, 
configGroup.get('name'));
 
-            if (configsToSave) {
-              this.putChangedConfigurations([configsToSave]);
-            }
-
-          } else {
-
-            var overridenConfigs = this.getConfigsForGroup(configs, 
configGroup.get('name'));
-
-            if (Em.isArray(overridenConfigs)) {
-              this.saveGroup(overridenConfigs, configGroup, 
this.get('content.serviceName') === serviceName);
-            }
+          if (Em.isArray(overriddenConfigs)) {
+            var successCallback = this.get('content.serviceName') === 
serviceName ? 'putConfigGroupChangesSuccess' : null;
+            this.saveGroup(overriddenConfigs, configGroup, 
this.get('serviceConfigVersionNote'), successCallback);
           }
         }
       }, this);
@@ -319,7 +310,7 @@ App.ConfigsSaverMixin = Em.Mixin.create({
 
     //generates list of properties that was changed
     var modifiedConfigs = this.getModifiedConfigs(configs);
-    var serviceFilenames = 
Object.keys(App.StackService.find(serviceName).get('configTypes')).map(function 
(type) {
+    var serviceFileNames = 
Object.keys(App.StackService.find(serviceName).get('configTypes')).map(function 
(type) {
       return App.config.getOriginalFileName(type);
     });
 
@@ -331,7 +322,7 @@ App.ConfigsSaverMixin = Em.Mixin.create({
     if (!Em.isArray(modifiedConfigs) || modifiedConfigs.length == 0) return 
null;
 
     var fileNamesToSave = 
modifiedConfigs.mapProperty('filename').concat(this.get('modifiedFileNames')).filter(function(filename)
 {
-      return serviceFilenames.contains(filename);
+      return serviceFileNames.contains(filename);
     }).uniq();
 
     var configsToSave = this.generateDesiredConfigsJSON(modifiedConfigs, 
fileNamesToSave, this.get('serviceConfigVersionNote'));
@@ -451,7 +442,7 @@ App.ConfigsSaverMixin = Em.Mixin.create({
     if (Em.isArray(properties)) {
       properties.forEach(function(property) {
 
-        if (Em.get(property, 'isRequiredByAgent')) {
+        if (Em.get(property, 'isRequiredByAgent') !== false) {
           desired_config.properties[Em.get(property, 'name')] = 
this.formatValueBeforeSave(property);
           /**
            * add is final value
@@ -521,40 +512,64 @@ App.ConfigsSaverMixin = Em.Mixin.create({
 
   /**
    * save config group
-   * @param overridenConfigs
+   * @param overriddenConfigs
    * @param selectedConfigGroup
-   * @param showPopup
+   * @param configVersionNote
+   * @param successCallback
    */
-  saveGroup: function(overridenConfigs, selectedConfigGroup, showPopup) {
-    var groupHosts = [];
-    var fileNamesToSave = overridenConfigs.mapProperty('filename').uniq();
-    selectedConfigGroup.get('hosts').forEach(function (hostName) {
-      groupHosts.push({"host_name": hostName});
-    });
-    var id = selectedConfigGroup.get('configGroupId');
-    id = Em.isNone(id) ? selectedConfigGroup.get('id') : id;
-    this.putConfigGroupChanges({
+  saveGroup: function(overriddenConfigs, selectedConfigGroup, 
configVersionNote, successCallback) {
+    var fileNamesToSave = overriddenConfigs.mapProperty('filename').uniq();
+    var group = Ember.typeOf(selectedConfigGroup) === "instance" ? 
selectedConfigGroup.toJSON() : selectedConfigGroup;
+    var groupHosts = group.hosts.map(function (hostName) { return { 
"host_name": hostName }; });
+
+    var groupData = {
       ConfigGroup: {
-        "id": id,
-        "cluster_name": App.get('clusterName'),
-        "group_name": selectedConfigGroup.get('name'),
-        "tag": selectedConfigGroup.get('service.id'),
-        "description": selectedConfigGroup.get('description'),
+        "cluster_name": App.get('clusterName') || this.get('clusterName'),
+        "group_name": group.name,
+        "tag": group.service_id,
+        "description": group.description,
         "hosts": groupHosts,
-        "service_config_version_note": this.get('serviceConfigVersionNote'),
-        "desired_configs": this.generateDesiredConfigsJSON(overridenConfigs, 
fileNamesToSave, null, true)
+        "service_config_version_note": configVersionNote || "",
+        "desired_configs": this.generateDesiredConfigsJSON(overriddenConfigs, 
fileNamesToSave, null, true)
       }
-    }, showPopup);
+    };
+
+    if (group.config_group_id) {
+      groupData.ConfigGroup.id = group.config_group_id;
+      this.updateConfigGroup(groupData, successCallback);
+    } else {
+      this.createConfigGroup(groupData, successCallback);
+    }
+  },
+
+  /**
+   *
+   * @param data
+   * @param successCallback
+   * @returns {*|$.ajax}
+   */
+  createConfigGroup: function(data, successCallback) {
+    var ajaxOptions = {
+      name: 'wizard.step8.apply_configuration_groups',
+      sender: this,
+      data: {
+        data: JSON.stringify(data)
+      }
+    };
+    if (successCallback) {
+      ajaxOptions.success = successCallback;
+    }
+    return App.ajax.send(ajaxOptions);
   },
 
   /**
    * persist properties of config groups to server
    * show result popup if <code>showPopup</code> is true
    * @param data {Object}
-   * @param showPopup {Boolean}
+   * @param [successCallback] {String}
    * @method putConfigGroupChanges
    */
-  putConfigGroupChanges: function (data, showPopup) {
+  updateConfigGroup: function (data, successCallback) {
     var ajaxOptions = {
       name: 'config_groups.update_config_group',
       sender: this,
@@ -563,8 +578,8 @@ App.ConfigsSaverMixin = Em.Mixin.create({
         configGroup: data
       }
     };
-    if (showPopup) {
-      ajaxOptions.success = "putConfigGroupChangesSuccess";
+    if (successCallback) {
+      ajaxOptions.success = successCallback;
     }
     return App.ajax.send(ajaxOptions);
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/ambari-web/app/mixins/main/service/configs/config_overridable.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/main/service/configs/config_overridable.js 
b/ambari-web/app/mixins/main/service/configs/config_overridable.js
index 582ce4f..c894a4f 100644
--- a/ambari-web/app/mixins/main/service/configs/config_overridable.js
+++ b/ambari-web/app/mixins/main/service/configs/config_overridable.js
@@ -63,10 +63,7 @@ App.ConfigOverridable = Em.Mixin.create({
     }
     else {
       var valueForOverride = (serviceConfigProperty.get('widget') || 
serviceConfigProperty.get('displayType') == 'checkbox') ? 
serviceConfigProperty.get('value') : '';
-      var override = App.config.createOverride(serviceConfigProperty, { 
"value": valueForOverride, "isEditable": true }, selectedConfigGroup);
-      if (isInstaller) {
-        selectedConfigGroup.get('properties').pushObject(override);
-      }
+      App.config.createOverride(serviceConfigProperty, { "value": 
valueForOverride, "isEditable": true }, selectedConfigGroup);
     }
     Em.$('body>.tooltip').remove();
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index 467c96f..50c6c4a 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -590,31 +590,6 @@ App.config = Em.Object.create({
   },
 
   /**
-   * Create config with non default config group. Some custom config properties
-   * can be created and assigned to non-default config group.
-   *
-   * @param {String} propertyName - name of the property
-   * @param {String} fileName - file name of the property
-   * @param {String} value - config value
-   * @param {Em.Object} group - config group to set
-   * @param {Boolean} [isEditable]
-   * @param {Boolean} [isInstaller]
-   * @return {Object}
-   **/
-  createCustomGroupConfig: function (propertyName, fileName, value, group, 
isEditable, isInstaller) {
-    var propertyObject = this.createDefaultConfig(propertyName, 
this.getOriginalFileName(fileName), false, {
-      savedValue: isInstaller ? null : value,
-      value: value,
-      group: group,
-      isEditable: !!isEditable,
-      isOverridable: false
-    });
-    group.set('switchGroupTextShort', 
Em.I18n.t('services.service.config_groups.switchGroupTextShort').format(group.get('name')));
-    group.set('switchGroupTextFull', 
Em.I18n.t('services.service.config_groups.switchGroupTextFull').format(group.get('name')));
-    return App.ServiceConfigProperty.create(propertyObject);
-  },
-
-  /**
    *
    * @param configs
    */
@@ -888,15 +863,44 @@ App.config = Em.Object.create({
   },
 
   /**
+   * Create config with non default config group. Some custom config properties
+   * can be created and assigned to non-default config group.
+   *
+   * @param {Em.Object} override - config value
+   * @param {Em.Object} configGroup - config group to set
+   * @return {Object}
+   **/
+  createCustomGroupConfig: function (override, configGroup) {
+    App.assertObject(override);
+    App.assertEmberObject(configGroup);
+
+    var newOverride = 
App.ServiceConfigProperty.create(this.createDefaultConfig(override.propertyName,
 override.filename, false, override));
+
+    newOverride.setProperties({
+      'isOriginalSCP': false,
+      'overrides': null,
+      'group': configGroup,
+      'parentSCP': null
+    });
+
+    if (!configGroup.get('properties.length')) {
+      configGroup.set('properties', Em.A([]));
+    }
+    configGroup.set('properties', 
configGroup.get('properties').concat(newOverride));
+
+    return newOverride;
+  },
+
+
+  /**
    * @param {App.ServiceConfigProperty} serviceConfigProperty
    * @param {Object} override - plain object with properties that is different 
from parent SCP
    * @param {App.ServiceConfigGroup} configGroup
-   * @param {boolean} [updateGroup]
    * @returns {App.ServiceConfigProperty}
    */
-  createOverride: function(serviceConfigProperty, override, configGroup, 
updateGroup) {
-    Em.assert('serviceConfigProperty can\' be null', serviceConfigProperty);
-    Em.assert('configGroup can\' be null', configGroup);
+  createOverride: function(serviceConfigProperty, override, configGroup) {
+    App.assertObject(serviceConfigProperty);
+    App.assertEmberObject(configGroup);
 
     if (Em.isNone(serviceConfigProperty.get('overrides'))) 
serviceConfigProperty.set('overrides', []);
 
@@ -915,12 +919,10 @@ App.config = Em.Object.create({
       'parentSCP': serviceConfigProperty
     });
 
-    if (updateGroup) {
-      if (!configGroup.get('properties.length')) {
-        configGroup.set('properties', Em.A([]));
-      }
-      configGroup.get('properties').push(newOverride);
+    if (!configGroup.get('properties.length')) {
+      configGroup.set('properties', Em.A([]));
     }
+    configGroup.set('properties', 
configGroup.get('properties').concat(newOverride));
 
     serviceConfigProperty.get('overrides').pushObject(newOverride);
     serviceConfigProperty.set('overrideValues', 
serviceConfigProperty.get('overrides').mapProperty('value'));

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/ambari-web/app/views/common/configs/service_configs_by_category_view.js
----------------------------------------------------------------------
diff --git 
a/ambari-web/app/views/common/configs/service_configs_by_category_view.js 
b/ambari-web/app/views/common/configs/service_configs_by_category_view.js
index fdd0bfc..b5d5b45 100644
--- a/ambari-web/app/views/common/configs/service_configs_by_category_view.js
+++ b/ambari-web/app/views/common/configs/service_configs_by_category_view.js
@@ -338,27 +338,23 @@ App.ServiceConfigsByCategoryView = 
Em.View.extend(App.UserPref, App.ConfigOverri
   },
 
   createProperty: function (propertyObj) {
-    var selectedConfigGroup = this.get('controller.selectedConfigGroup'),
-      isSecureConfig = this.isSecureConfig(propertyObj.name, 
propertyObj.filename);
-    this.get('serviceConfigs').pushObject(App.ServiceConfigProperty.create({
-      name: propertyObj.name,
-      displayName: propertyObj.displayName || propertyObj.name,
-      value: propertyObj.value,
-      displayType: stringUtils.isSingleLine(propertyObj.value) ? 'string' : 
'multiLine',
-      isSecureConfig: isSecureConfig,
-      category: propertyObj.categoryName,
-      serviceName: propertyObj.serviceName,
-      savedValue: null,
-      recommendedValue: null,
-      supportsFinal: App.config.shouldSupportFinal(propertyObj.serviceName, 
propertyObj.filename),
-      supportsAddingForbidden: false, //Can add a new property implies the 
given categrary allows adding new properties...
-      filename: propertyObj.filename || '',
-      isUserProperty: true,
-      isNotSaved: true,
-      isRequired: false,
-      group: selectedConfigGroup.get('isDefault') ? null : selectedConfigGroup,
-      isOverridable: selectedConfigGroup.get('isDefault')
-    }));
+    var selectedConfigGroup = this.get('controller.selectedConfigGroup');
+    if (selectedConfigGroup.get('isDefault')) {
+      var config = App.config.createDefaultConfig(propertyObj.name, 
propertyObj.filename, false, {
+        value: propertyObj.value,
+        category: propertyObj.categoryName,
+        isNotSaved: true
+      });
+    } else {
+      var config = App.config.createCustomGroupConfig({
+        name: propertyObj.name,
+        filename: propertyObj.filename,
+        value: propertyObj.value,
+        category: propertyObj.categoryName,
+        isNotSaved: true
+      }, selectedConfigGroup);
+    }
+    
this.get('serviceConfigs').pushObject(App.ServiceConfigProperty.create(config));
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/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 9adfd28..b533054 100644
--- a/ambari-web/test/controllers/main/service/info/config_test.js
+++ b/ambari-web/test/controllers/main/service/info/config_test.js
@@ -609,30 +609,6 @@ describe("App.MainServiceInfoConfigsController", function 
() {
 
   });
 
-  describe("#putConfigGroupChanges", function() {
-
-    var t = {
-      data: {
-        ConfigGroup: {
-          id: "id"
-        }
-      },
-      request: [{
-        ConfigGroup: {
-          id: "id"
-        }
-      }]
-    };
-
-    it("updates configs groups", function() {
-      mainServiceInfoConfigsController.putConfigGroupChanges(t.data);
-      var args = testHelpers.findAjaxRequest('name', 
'config_groups.update_config_group');
-      expect(args[0]).exists;
-      var data = 
JSON.parse(App.ajax.fakeGetUrl('config_groups.update_config_group').format(args[0].data).data);
-      expect(data).to.deep.equal(t.request);
-    });
-  });
-
   describe("#checkOverrideProperty", function () {
     var tests = [{
       overrideToAdd: {

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/ambari-web/test/controllers/wizard/step7_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step7_test.js 
b/ambari-web/test/controllers/wizard/step7_test.js
index f1033bb..2cbe42c 100644
--- a/ambari-web/test/controllers/wizard/step7_test.js
+++ b/ambari-web/test/controllers/wizard/step7_test.js
@@ -458,19 +458,19 @@ describe('App.InstallerStep7Controller', function () {
     });
     it('should add new groups to groupsToDelete', function () {
       var groupsToDelete = [
-          {id: '1'},
-          {id: '2'}
+          {configGroupId: '1'},
+          {configGroupId: '2'}
         ],
         groups = [
-          Em.Object.create({id: '3'}),
+          Em.Object.create({configGroupId: '3'}),
           Em.Object.create(),
-          Em.Object.create({id: '5'})
+          Em.Object.create({configGroupId: '5'})
         ],
         expected = [
-          {id: "1"},
-          {id: "2"},
-          {id: "3"},
-          {id: "5"}
+          {configGroupId: "1"},
+          {configGroupId: "2"},
+          {configGroupId: "3"},
+          {configGroupId: "5"}
         ];
       installerStep7Controller.set('groupsToDelete', groupsToDelete);
       installerStep7Controller.setGroupsToDelete(groups);
@@ -2333,10 +2333,12 @@ describe('App.InstallerStep7Controller', function () {
         serviceConfigs: [],
         typeTagToGroupMap: {
           'type1///tag1': Em.Object.create({
-            name: 't1t1'
+            name: 't1t1',
+            properties: []
           }),
           'type2///tag1': Em.Object.create({
-            name: 't2t1'
+            name: 't2t1',
+            properties: []
           })
         },
         configKeyToConfigMap: {

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/ambari-web/test/controllers/wizard/step8_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step8_test.js 
b/ambari-web/test/controllers/wizard/step8_test.js
index 5f6e4f7..867d5f8 100644
--- a/ambari-web/test/controllers/wizard/step8_test.js
+++ b/ambari-web/test/controllers/wizard/step8_test.js
@@ -209,104 +209,6 @@ describe('App.WizardStep8Controller', function () {
 
   });
 
-  describe('#createConfigurationGroups', function () {
-    var content;
-    beforeEach(function() {
-      sinon.stub(App.router,'get').returns(Em.Object.create({
-        getDBProperty: function() {
-          return Em.A([
-            Em.Object.create({
-              value: 1
-            })
-          ]);
-        },
-        getConfigAttributes: function() {
-          return Em.A(['atr']);
-        }
-      }));
-      content = Em.Object.create({
-        configGroups: Em.A([
-          Em.Object.create({
-            is_default: true,
-            service: Em.Object.create({
-              id: 1
-            }),
-            name: 'n1',
-            description: 'describe',
-            hosts: ['h1', 'h2'],
-            properties: Em.A([
-              Em.Object.create({
-                value: 'p1',
-                filename: 'file.xml'
-              }),
-              Em.Object.create({
-                value: 'p2',
-                filename: 'file1.xml'
-              })
-            ])
-          }),
-          Em.Object.create({
-            is_default: false,
-            service: Em.Object.create({
-              id: 2
-            }),
-            name: 'n2',
-            hosts: ['h3', 'h4'],
-            description: 'describe1',
-            properties: Em.A([
-              Em.Object.create({
-                value: 'p3',
-                filename: 'file2.xml'
-              }),
-              Em.Object.create({
-                value: 'p4',
-                filename: 'file3.xml'
-              })
-            ])
-          })
-        ])
-      });
-      var defaultGroups = Em.A([
-        Em.Object.create({
-          group: 'n2',
-          filename: 'file5.xml'
-        }),
-        Em.Object.create({
-          group: 'n1',
-          filename: 'file4.xml'
-        })
-      ]);
-      installerStep8Controller.set('content', content);
-      installerStep8Controller.set('clusterName', 'name');
-      installerStep8Controller.set('customNonDefaultGroupConfigs', 
defaultGroups);
-      installerStep8Controller.set('ajaxRequestsQueue', 
App.ajaxQueue.create());
-      installerStep8Controller.get('ajaxRequestsQueue').clear();
-      installerStep8Controller.createConfigurationGroups();
-    });
-    afterEach(function() {
-      App.router.get.restore();
-    });
-
-    it('should push group in properties', function () {
-      var expected = [
-        {
-          "value": "p3",
-          "filename": "file2.xml"
-        },
-        {
-          "value": "p4",
-          "filename": "file3.xml"
-        },
-        {
-          "group": "n2",
-          "filename": "file5.xml"
-        }
-      ];
-      var result = 
JSON.parse(JSON.stringify(content.configGroups[1].properties));
-      expect(result).to.eql(expected);
-    });
-  });
-
   describe('#loadServices', function () {
 
     beforeEach(function () {
@@ -1154,23 +1056,6 @@ describe('App.WizardStep8Controller', function () {
     });
   });
 
-  describe('#applyInstalledServicesConfigurationGroup', function() {
-    beforeEach(function() {
-      sinon.stub(App.router, 'get', function() {
-        return configurationController;
-      });
-    });
-    afterEach(function() {
-      App.router.get.restore();
-    });
-    it('should do ajax request for each config group', function() {
-      var configGroups = [{ConfigGroup: {id:''}}, {ConfigGroup: {id:''}}];
-      
installerStep8Controller.applyInstalledServicesConfigurationGroup(configGroups);
-      var args = testHelpers.filterAjaxRequests('name', 
'config_groups.update_config_group');
-      expect(args).to.have.property('length').equal(configGroups.length);
-    });
-  });
-
   describe('#getExistingClusterNames', function() {
 
     it('should do ajax request', function() {
@@ -1328,14 +1213,6 @@ describe('App.WizardStep8Controller', function () {
       });
     });
 
-    describe('#applyConfigurationGroups', function() {
-      it('should call addRequestToAjaxQueue', function() {
-        var data = [{}, {}];
-        installerStep8Controller.applyConfigurationGroups(data);
-        
expect(installerStep8Controller.addRequestToAjaxQueue.args[0][0].data.data).to.equal(JSON.stringify(data));
-      });
-    });
-
     describe('#newServiceComponentErrorCallback', function() {
 
       it('should add request for new component', function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/ambari-web/test/utils/config_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/config_test.js 
b/ambari-web/test/utils/config_test.js
index 5f233f2..8ac5bff 100644
--- a/ambari-web/test/utils/config_test.js
+++ b/ambari-web/test/utils/config_test.js
@@ -425,7 +425,7 @@ describe('App.config', function () {
 
     var configProperty = App.ServiceConfigProperty.create(template);
 
-    var group = Em.Object.create({name: "group1"});
+    var group = Em.Object.create({name: "group1", properties: []});
 
     Object.keys(template).forEach(function (key) {
       it(key, function () {
@@ -470,11 +470,11 @@ describe('App.config', function () {
     });
 
     it('throws error due to undefined configGroup', function() {
-      expect(App.config.createOverride.bind(App.config, configProperty, {}, 
null)).to.throw(Error, 'configGroup can\' be null');
+      expect(App.config.createOverride.bind(App.config, configProperty, {}, 
null)).to.throw(App.EmberObjectTypeError);
     });
 
     it('throws error due to undefined originalSCP', function() {
-      expect(App.config.createOverride.bind(App.config, null, {}, 
group)).to.throw(Error, 'serviceConfigProperty can\' be null');
+      expect(App.config.createOverride.bind(App.config, null, {}, 
group)).to.throw(App.ObjectTypeError);
     });
 
     describe('updates originalSCP object ', function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/59883500/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
----------------------------------------------------------------------
diff --git 
a/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js 
b/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
index 5b443b6..7b6c451 100644
--- 
a/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
+++ 
b/ambari-web/test/views/common/configs/service_configs_by_category_view_test.js
@@ -253,103 +253,6 @@ describe('App.ServiceConfigsByCategoryView', function () {
 
   });
 
-  describe('#createProperty', function () {
-
-    var cases = [
-      {
-        propertyObj: {
-          name: 'n0',
-          displayName: 'd0',
-          value: 'v0',
-          filename: 'f0',
-          categoryName: 'c0',
-          serviceName: 's0'
-        },
-        isDefaultConfigGroup: true,
-        result: {
-          name: 'n0',
-          displayName: 'd0',
-          value: 'v0',
-          displayType: 'string',
-          isSecureConfig: true,
-          category: 'c0',
-          serviceName: 's0',
-          savedValue: null,
-          supportsFinal: true,
-          filename: 'f0',
-          isUserProperty: true,
-          isNotSaved: true,
-          isRequired: false,
-          group: null,
-          isOverridable: true
-        },
-        title: 'single line value, secure config, final attribute supported, 
default config group'
-      },
-      {
-        propertyObj: {
-          name: 'n1',
-          value: 'v\n1',
-          filename: '',
-          categoryName: 'c1',
-          serviceName: 's1'
-        },
-        isDefaultConfigGroup: false,
-        result: {
-          name: 'n1',
-          displayName: 'n1',
-          value: 'v\n1',
-          displayType: 'multiLine',
-          isSecureConfig: false,
-          category: 'c1',
-          serviceName: 's1',
-          savedValue: null,
-          supportsFinal: false,
-          filename: '',
-          isUserProperty: true,
-          isNotSaved: true,
-          isRequired: false,
-          group: Em.Object.create({
-            isDefault: false
-          }),
-          isOverridable: false
-        },
-        title: 'multiline value, non-secure config, no display name and 
filename, final attribute not supported, custom config group'
-      }
-    ];
-
-    before(function () {
-      view.get('serviceConfigs').clear();
-      sinon.stub(view, 'isSecureConfig').withArgs('n0', 
'f0').returns(true).withArgs('n1', '').returns(false);
-      sinon.stub(App.config, 'shouldSupportFinal').withArgs('s0', 
'f0').returns(true).withArgs('s1', '').returns(false);
-    });
-
-    after(function () {
-      view.get('serviceConfigs').clear();
-      view.isSecureConfig.restore();
-      App.config.shouldSupportFinal.restore();
-    });
-
-    cases.forEach(function (item) {
-      it(item.title, function () {
-        view.reopen({
-          filteredCategoryConfigs: [],
-          controller: {
-            selectedConfigGroup: Em.Object.create({
-              isDefault: item.isDefaultConfigGroup
-            })
-          }
-        });
-        view.createProperty(item.propertyObj);
-        expect(view.get('serviceConfigs').filterProperty('name', 
item.propertyObj.name)).to.have.length(1);
-        expect(view.get('serviceConfigs').findProperty('name', 
item.propertyObj.name).getProperties([
-          'name', 'displayName', 'value', 'displayType', 'isSecureConfig', 
'category', 'serviceName', 'savedValue',
-          'supportsFinal', 'filename', 'isUserProperty', 'isNotSaved', 
'isRequired', 'group', 'isOverridable'
-        ])).to.eql(item.result);
-      });
-    });
-
-  });
-
   describe('#categoryConfigs', function () {
     var result = [1, 2, 3, 4, 5];
     var cases = [

Reply via email to