You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2016/02/18 17:55:00 UTC

ambari git commit: AMBARI-15089 Refactor create configs JSON methods for saving. (ababiichuk)

Repository: ambari
Updated Branches:
  refs/heads/trunk 0bd63c80b -> 0a9101e97


AMBARI-15089 Refactor create configs JSON methods for saving. (ababiichuk)


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

Branch: refs/heads/trunk
Commit: 0a9101e97c21b5bb5f25a84d264176a86f159f2e
Parents: 0bd63c8
Author: ababiichuk <ab...@hortonworks.com>
Authored: Thu Feb 18 15:21:07 2016 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Thu Feb 18 18:54:01 2016 +0200

----------------------------------------------------------------------
 .../app/controllers/wizard/step8_controller.js  | 240 ++++++-------------
 .../mixins/common/configs/configs_comparator.js |   4 +-
 .../app/mixins/common/configs/configs_saver.js  | 217 +++++++----------
 .../test/controllers/wizard/step8_test.js       | 176 +-------------
 .../mixins/common/configs/configs_saver_test.js |  98 ++++----
 5 files changed, 225 insertions(+), 510 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/0a9101e9/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 0ac998b..911d0a8 100644
--- a/ambari-web/app/controllers/wizard/step8_controller.js
+++ b/ambari-web/app/controllers/wizard/step8_controller.js
@@ -18,13 +18,27 @@
 
 var App = require('app');
 var stringUtils = require('utils/string_utils');
-var dataManipulationUtils = require('utils/data_manipulation');
 
-App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wizardDeployProgressControllerMixin, App.ConfigOverridable, {
+App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wizardDeployProgressControllerMixin, App.ConfigOverridable, App.ConfigsSaverMixin, {
 
   name: 'wizardStep8Controller',
 
   /**
+   * @type {boolean}
+   */
+  isAddService: Em.computed.equal('content.controllerName', 'addServiceController'),
+
+  /**
+   * @type {boolean}
+   */
+  isAddHost: Em.computed.equal('content.controllerName', 'addHostController'),
+
+  /**
+   * @type {boolean}
+   */
+  isInstaller: Em.computed.equal('content.controllerName', 'installerController'),
+
+  /**
    * List of raw data about cluster that should be displayed
    * @type {Array}
    */
@@ -622,31 +636,6 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
   },
 
   /**
-   * Update configurations for installed services.
-   * Do separated PUT-request for each siteName for each service
-   *
-   * @param {Array} fileNamesToUpdate - file names that should be updated
-   * @method updateConfigurations
-   */
-  updateConfigurations: function (fileNamesToUpdate) {
-    var configurationController = App.router.get('mainServiceInfoConfigsController');
-    var configs = this.get('configs').slice(0);
-    var configsMap = [];
-    fileNamesToUpdate.forEach(function (fileName) {
-      // TODO - Temporarily commented out before refactoring should clean it more properly
-      // if (!fileName || /^(core)/.test(fileName)) return;
-      var tagName = 'version' + (new Date).getTime();
-      var configsToSave = configs.filterProperty('filename', fileName);
-      configsToSave.forEach(function (item) {
-        item.value = App.config.trimProperty(item, false);
-      });
-      configsMap.push(configurationController.createSiteObj(fileName.replace(".xml", ""), tagName, configsToSave));
-    }, this);
-
-    if (!configsMap.length) return;
-    this.applyConfigurationsToCluster(configsMap);
-  },
-  /**
    * Prepare <code>ajaxQueue</code> and start to execute it
    * @method submitProceed
    */
@@ -859,7 +848,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
         }
         var fileNamesToUpdate = this.get('wizardController').getDBProperty('fileNamesToUpdate').uniq();
         if (fileNamesToUpdate && fileNamesToUpdate.length) {
-          this.updateConfigurations(fileNamesToUpdate);
+          this.applyConfigurationsToCluster(this.generateDesiredConfigsJSON(this.get('configs'), fileNamesToUpdate));
         }
       }
       this.createConfigurations();
@@ -1357,70 +1346,23 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
   },
 
   /**
-   * Compare generated config object with current configs that were filled
-   * on "Customize Services" page.
-   *
-   * @param {Object} properties - generated by createSiteObj|createCoreSiteObj
-   * @param {Array} configs - current configs to compare
-   * @return {Boolean}
-   * @method isConfigsChanged
-   **/
-  isConfigsChanged: function (properties, configs) {
-    var isChanged = false;
-    for (var property in properties) {
-      var config = configs.findProperty('name', property);
-      // if config not found then it's looks like a new config
-      if (!config) {
-        isChanged = true;
-      } else {
-        if (!config.hasInitialValue || config.isNotDefaultValue) {
-          isChanged = true;
-        }
-      }
-    }
-    return isChanged;
-  },
-
-  /**
    * Create config objects for cluster and services
    * @method createConfigurations
    */
   createConfigurations: function () {
-    var selectedServices = this.get('selectedServices');
-    var coreSiteObject = this.createCoreSiteObj();
-    var tag = 'version1';
-    var clusterSiteObj = this.createSiteObj('cluster-env', tag);
+    var tag = this.getServiceConfigVersion();
 
-    if (this.get('content.controllerName') == 'installerController') {
-      this.get('serviceConfigTags').pushObject(clusterSiteObj);
+    if (this.get('isInstaller')) {
+      /** add cluster-env **/
+      this.get('serviceConfigTags').pushObject(this.createDesiredConfig('cluster-env', tag, this.get('configs').filterProperty('filename', 'cluster-env.xml')));
     }
 
-    if (this.get('content.controllerName') == 'addServiceController') {
-      tag = 'version' + (new Date).getTime();
-      coreSiteObject.tag = tag;
-      var coreSiteConfigs = this.get('configs').filterProperty('filename', 'core-site.xml');
-      if (this.isConfigsChanged(coreSiteObject.properties, coreSiteConfigs)) {
-        coreSiteObject.service_config_version_note = Em.I18n.t('dashboard.configHistory.table.notes.addService');
-        this.get('serviceConfigTags').pushObject(coreSiteObject);
-      }
-    }
-
-    selectedServices.forEach(function (service) {
+    this.get('selectedServices').forEach(function (service) {
       Object.keys(service.get('configTypes')).forEach(function (type) {
         if (!this.get('serviceConfigTags').someProperty('type', type)) {
-          var serviceVersionNotes = Em.I18n.t('dashboard.configHistory.table.notes.default').format(service.get('displayName'));
-          if (type === 'core-site') {
-            coreSiteObject.service_config_version_note = serviceVersionNotes;
-            this.get('serviceConfigTags').pushObject(coreSiteObject);
-          } else if (type === 'storm-site') {
-            var obj = this.createStormSiteObj(tag);
-            obj.service_config_version_note = serviceVersionNotes;
-            this.get('serviceConfigTags').pushObject(obj);
-          }  else {
-            var obj = this.createSiteObj(type, tag);
-            obj.service_config_version_note = serviceVersionNotes;
-            this.get('serviceConfigTags').pushObject(obj);
-          }
+          var configs = this.get('configs').filterProperty('filename', App.config.getOriginalFileName(type));
+          var serviceConfigNote = this.getServiceConfigNote(type, service.get('displayName'));
+          this.get('serviceConfigTags').pushObject(this.createDesiredConfig(type, tag, configs, serviceConfigNote));
         }
       }, this);
     }, this);
@@ -1428,6 +1370,27 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
   },
 
   /**
+   * Get config version tag
+   *
+   * @returns {string}
+   */
+  getServiceConfigVersion: function() {
+    return 'version' + (this.get('isAddService') ? (new Date).getTime() : '1');
+  },
+
+  /**
+   * Get config version message
+   *
+   * @param type
+   * @param serviceDisplayName
+   * @returns {*}
+   */
+  getServiceConfigNote: function(type, serviceDisplayName) {
+    return (this.get('isAddService') && (type === 'core-site')) ?
+      Em.I18n.t('dashboard.configHistory.table.notes.addService') : Em.I18n.t('dashboard.configHistory.table.notes.default').format(serviceDisplayName);
+  },
+
+  /**
    * Send <code>serviceConfigTags</code> to server
    * Queued request
    * One request for each service config tag
@@ -1564,7 +1527,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
     });
 
     return sites.map(function (site) {
-      return App.router.get('mainServiceInfoConfigsController').createSiteObj(site.type, site.tag, site.properties);
+      return this.createDesiredConfig(site.type, site.tag, site.properties, null, true);
     }, this);
   },
 
@@ -1608,94 +1571,45 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
   },
 
   /**
-   * Create Core Site object
-   * @returns {{type: string, tag: string, properties: {}}}
-   * @method createCoreSiteObj
-   */
-  createCoreSiteObj: function () {
-    var installedAndSelectedServices = Em.A([]);
-    installedAndSelectedServices.pushObjects(this.get('installedServices'));
-    installedAndSelectedServices.pushObjects(this.get('selectedServices'));
-    var coreSiteObj = this.get('configs').filterProperty('filename', 'core-site.xml'),
-      coreSiteProperties = this.createSiteObj('core-site', 'version1').properties,
-      isGLUSTERFSSelected = installedAndSelectedServices.someProperty('serviceName', 'GLUSTERFS');
-
-    coreSiteObj.forEach(function (_coreSiteObj) {
-      if (coreSiteObj.isRequiredByAgent !== false) {
-        if (isGLUSTERFSSelected && _coreSiteObj.name == "fs.default.name") {
-          coreSiteProperties[_coreSiteObj.name] =
-            this.get('configs').someProperty('name', 'fs_glusterfs_default_name') ?
-              this.get('configs').findProperty('name', 'fs_glusterfs_default_name').value : null;
-        }
-        if (isGLUSTERFSSelected && _coreSiteObj.name == "fs.defaultFS") {
-          coreSiteProperties[_coreSiteObj.name] =
-            this.get('configs').someProperty('name', 'glusterfs_defaultFS_name') ?
-              this.get('configs').findProperty('name', 'glusterfs_defaultFS_name').value : null;
-        }
-      }
-    }, this);
-    var attributes = App.router.get('mainServiceInfoConfigsController').getConfigAttributes(coreSiteObj);
-    var configObj = {"type": "core-site", "tag": "version1", "properties": coreSiteProperties};
-    if (attributes) {
-      configObj['properties_attributes'] = attributes;
-    }
-    return  configObj;
-  },
+   * Selected and installed services
+   * @override
+   */
+  currentServices: function() {
+    return this.get('installedServices').concat(this.get('selectedServices'));
+  }.property('installedServices.length', 'selectedServices.length'),
 
   /**
-   * Create siteObj for custom service with it own configs
-   * @param {string} site
-   * @param tag
-   * @returns {{type: string, tag: string, properties: {}}}
-   * @method createSiteObj
-   */
-  createSiteObj: function (site,  tag) {
-    var properties = {};
-    var configs = this.get('configs').filterProperty('filename', site + '.xml');
-    var attributes = App.router.get('mainServiceInfoConfigsController').getConfigAttributes(configs);
-    configs.forEach(function (_configProperty) {
-      var heapsizeExceptions = ['hadoop_heapsize', 'yarn_heapsize', 'nodemanager_heapsize', 'resourcemanager_heapsize', 'apptimelineserver_heapsize',
-        'jobhistory_heapsize', 'nfsgateway_heapsize', 'accumulo_master_heapsize', 'accumulo_tserver_heapsize', 'accumulo_monitor_heapsize', 'accumulo_gc_heapsize',
-        'accumulo_other_heapsize', 'hbase_master_heapsize', 'hbase_regionserver_heapsize', 'metrics_collector_heapsize'];
-        // do not pass any globals whose name ends with _host or _hosts
-        if (_configProperty.isRequiredByAgent !== false) {
-          // append "m" to JVM memory options except for heapsizeExtensions
-          if (/_heapsize|_newsize|_maxnewsize|_permsize|_maxpermsize$/.test(_configProperty.name) && !heapsizeExceptions.contains(_configProperty.name) && !(_configProperty.value).endsWith("m")) {
-            properties[_configProperty.name] = _configProperty.value + "m";
-          } else {
-            properties[_configProperty.name] = _configProperty.value;
-          }
-        }
-    }, this);
-    var configObj = {"type": site, "tag": tag, "properties": properties };
-    if (attributes) {
-      configObj['properties_attributes'] = attributes;
+   * Add handling GLUSTREFS properties
+   * @param property
+   * @returns {*}
+   * @override
+   */
+  formatValueBeforeSave: function(property) {
+    if (this.formatGLUSTERFSProperties(Em.get(property, 'filename'))) {
+      switch (property.name) {
+        case "fs.default.name":
+          return this.get('configs').someProperty('name', 'fs_glusterfs_default_name') ?
+            this.get('configs').findProperty('name', 'fs_glusterfs_default_name').value : null;
+        case "fs.defaultFS":
+          return this.get('configs').someProperty('name', 'glusterfs_defaultFS_name') ?
+            this.get('configs').findProperty('name', 'glusterfs_defaultFS_name').value : null;
+      }
     }
-    return configObj;
+    return this._super(property);
   },
 
   /**
-   * Create site obj for Storm
-   * Some config-properties should be modified in custom way
-   * @param tag
-   * @returns {{type: string, tag: string, properties: {}}}
-   * @method createStormSiteObj
+   * Defines if some GLUSTERFS properties should be changed
+   *
+   * @param {String} type
+   * @returns {boolean}
    */
-  createStormSiteObj: function (tag) {
-    var configs = this.get('configs').filterProperty('filename', 'storm-site.xml');
-    var stormProperties = {};
-    configs.forEach(function (_configProperty) {
-      if (_configProperty.isRequiredByAgent !== false) {
-        if (["nimbus.seeds", "storm.zookeeper.servers"].contains(_configProperty.name)) {
-          stormProperties[_configProperty.name] = JSON.stringify(_configProperty.value).replace(/"/g, "'");
-        } else {
-          stormProperties[_configProperty.name] = _configProperty.value;
-        }
-      }
-    }, this);
-    return {type: 'storm-site', tag: tag, properties: stormProperties};
+  formatGLUSTERFSProperties: function(type) {
+    return App.config.getConfigTagFromFileName(type) === 'core-site'
+      && this.get('installedServices').concat(this.get('selectedServices')).someProperty('serviceName', 'GLUSTERFS');
   },
 
+
   /**
    * Create one Alert Notification (if user select this on step7)
    * Only for Install Wizard and stack

http://git-wip-us.apache.org/repos/asf/ambari/blob/0a9101e9/ambari-web/app/mixins/common/configs/configs_comparator.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/configs_comparator.js b/ambari-web/app/mixins/common/configs/configs_comparator.js
index 75bb44a..c7d8322 100644
--- a/ambari-web/app/mixins/common/configs/configs_comparator.js
+++ b/ambari-web/app/mixins/common/configs/configs_comparator.js
@@ -89,11 +89,11 @@ App.ConfigsComparator = Em.Mixin.create({
     json.items.forEach(function (item) {
       item.configurations.forEach(function (configuration) {
         if (serviceName == 'YARN' && configuration.type == 'capacity-scheduler') {
-          var configsToSkip = this.get('settingsTabProperties').filterProperty('filename', 'capacity-scheduler.xml').filterProperty('subSection').mapProperty('name');
+          var configsToSkip = App.config.getPropertiesFromTheme('YARN');
           // put all properties in a single textarea for capacity-scheduler
           var value = '';
           for (var prop in configuration.properties) {
-            if (configsToSkip.contains(prop)) {
+            if (configsToSkip.contains(App.config.configId(prop, configuration.type))) {
               serviceVersionMap[item.service_config_version][prop + '-' + configuration.type] = {
                 name: prop,
                 value: configuration.properties[prop],

http://git-wip-us.apache.org/repos/asf/ambari/blob/0a9101e9/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 c2da486..78ce85d 100644
--- a/ambari-web/app/mixins/common/configs/configs_saver.js
+++ b/ambari-web/app/mixins/common/configs/configs_saver.js
@@ -17,21 +17,14 @@
  */
 
 var App = require('app');
-var dataManipulationUtils = require('utils/data_manipulation');
 var lazyLoading = require('utils/lazy_loading');
 
 /**
- * this mixin has method to save configs (used in MainServiceInfoConfigsController)
- * all methods are divided into couple groups :
- *  0. HELPERS - some helper methods
- *  1. PRE SAVE CHECKS - warning popups and validations checks
- *  2. PREPARE CONFIGS TO SAVE - filtering and formatting changed configs
- *    2.1 PREPARE DATABASE CONFIGS - modify database properties
- *    2.2 ADD DYNAMIC CONFIGS - !!!NEED INVESTIGATION
- *  3. GENERATING JSON TO SAVE - generating json data
- *  4. AJAX REQUESTS - ajax request
- *  5. AFTER SAVE INFO - after save methods like to show popup with result
- *  6. ADDITIONAL
+ * Mixin for saving configs
+ * Contains methods for
+ * - generation JSON for saving configs and groups
+ * - format properties if needed
+ * - requests to save configs and groups
  */
 App.ConfigsSaverMixin = Em.Mixin.create({
 
@@ -50,7 +43,10 @@ App.ConfigsSaverMixin = Em.Mixin.create({
    * List of heapsize properties not to be parsed
    * @type {string[]}
    */
-  heapsizeException: ['hadoop_heapsize', 'yarn_heapsize', 'nodemanager_heapsize', 'resourcemanager_heapsize', 'apptimelineserver_heapsize', 'jobhistory_heapsize', 'nfsgateway_heapsize', 'accumulo_master_heapsize', 'accumulo_tserver_heapsize', 'accumulo_monitor_heapsize', 'accumulo_gc_heapsize', 'accumulo_other_heapsize', 'hbase_master_heapsize', 'hbase_regionserver_heapsize', 'metrics_collector_heapsize'],
+  heapsizeException: ['hadoop_heapsize', 'yarn_heapsize', 'nodemanager_heapsize', 'resourcemanager_heapsize',
+    'apptimelineserver_heapsize', 'jobhistory_heapsize', 'nfsgateway_heapsize', 'accumulo_master_heapsize',
+    'accumulo_tserver_heapsize', 'accumulo_monitor_heapsize', 'accumulo_gc_heapsize', 'accumulo_other_heapsize',
+    'hbase_master_heapsize', 'hbase_regionserver_heapsize', 'metrics_collector_heapsize'],
 
   /**
    * Regular expression for heapsize properties detection
@@ -59,6 +55,30 @@ App.ConfigsSaverMixin = Em.Mixin.create({
   heapsizeRegExp: /_heapsize|_newsize|_maxnewsize|_permsize|_maxpermsize$/,
 
   /**
+   * If some of services has such type core-site can be saved
+   *
+   * @type {string}
+   */
+  coreSiteServiceType: 'HCFS',
+
+  /**
+   * Core site can be used by multiple services
+   * If some of services listed below is selected/installed than core site can be saved
+   *
+   * @type {string[]}
+   */
+  coreSiteServiceNames: ['HDFS', 'GLUSTERFS', 'RANGER_KMS'],
+
+  /**
+   * List of services which configs should be saved
+   *
+   * @type {App.StackService[]}
+   */
+  currentServices: function() {
+    return [App.StackService.find(this.get('content.serviceName'))];
+  }.property('content.serviceName'),
+
+  /**
    * clear info to default
    * @method clearSaveInfo
    */
@@ -353,11 +373,11 @@ App.ConfigsSaverMixin = Em.Mixin.create({
    * generating common JSON object for desired configs
    * @param configsToSave
    * @param fileNamesToSave
-   * @param serviceConfigNote
-   * @param {boolean} [isNotDefaultGroup=false]
+   * @param {string} [serviceConfigNote='']
+   * @param {boolean} [ignoreVersionNote=false]
    * @returns {Array}
    */
-  generateDesiredConfigsJSON: function(configsToSave, fileNamesToSave, serviceConfigNote, isNotDefaultGroup) {
+  generateDesiredConfigsJSON: function(configsToSave, fileNamesToSave, serviceConfigNote, ignoreVersionNote) {
     var desired_config = [];
     if (Em.isArray(configsToSave) && Em.isArray(fileNamesToSave) && fileNamesToSave.length && configsToSave.length) {
       serviceConfigNote = serviceConfigNote || "";
@@ -367,7 +387,7 @@ App.ConfigsSaverMixin = Em.Mixin.create({
         if (this.allowSaveSite(fName)) {
           var properties = configsToSave.filterProperty('filename', fName);
           var type = App.config.getConfigTagFromFileName(fName);
-          desired_config.push(this.createDesiredConfig(type, tagVersion, properties, serviceConfigNote, isNotDefaultGroup));
+          desired_config.push(this.createDesiredConfig(type, tagVersion, properties, serviceConfigNote, ignoreVersionNote));
         }
       }, this);
     }
@@ -375,54 +395,65 @@ App.ConfigsSaverMixin = Em.Mixin.create({
   },
 
   /**
-   * for some file names we have a restriction
-   * and can't save them, in this this method will return false
+   * For some file names we have a restriction
+   * and can't save them, in this case method will return false
+   *
    * @param fName
    * @returns {boolean}
    */
   allowSaveSite: function(fName) {
-    switch (fName) {
-      case 'mapred-queue-acls.xml':
+    switch(App.config.getConfigTagFromFileName(fName)) {
+      case 'mapred-queue-acls':
         return false;
-      case 'core-site.xml':
-        var serviceName = this.get('content.serviceName');
-        var serviceType = App.StackService.find().findProperty('serviceName',serviceName).get('serviceType');
-        return ['HDFS', 'GLUSTERFS', 'RANGER_KMS'].contains(this.get('content.serviceName')) || serviceType === 'HCFS';
-      default :
+      case 'core-site':
+        return this.allowSaveCoreSite();
+      default:
         return true;
     }
   },
 
   /**
+   * Defines conditions in which core-site can be saved
+   *
+   * @returns {boolean}
+   */
+  allowSaveCoreSite: function() {
+    return this.get('currentServices').some(function(service) {
+      return (this.get('coreSiteServiceNames').contains(service.get('serviceName'))
+        || this.get('coreSiteServiceType') === service.get('serviceType'));
+    }, this);
+  },
+
+  /**
    * generating common JSON object for desired config
    * @param {string} type - file name without '.xml'
    * @param {string} tagVersion - version + timestamp
    * @param {App.ConfigProperty[]} properties - array of properties from model
-   * @param {string} serviceConfigNote
-   * @param {boolean} [isNotDefaultGroup=false]
+   * @param {string} [serviceConfigNote='']
+   * @param {boolean} [ignoreVersionNote=false]
    * @returns {{type: string, tag: string, properties: {}, properties_attributes: {}|undefined, service_config_version_note: string|undefined}}
    */
-  createDesiredConfig: function(type, tagVersion, properties, serviceConfigNote, isNotDefaultGroup) {
+  createDesiredConfig: function(type, tagVersion, properties, serviceConfigNote, ignoreVersionNote) {
     Em.assert('type and tagVersion should be defined', type && tagVersion);
     var desired_config = {
       "type": type,
       "tag": tagVersion,
       "properties": {}
     };
-    if (!isNotDefaultGroup) {
+    if (!ignoreVersionNote) {
       desired_config.service_config_version_note = serviceConfigNote || "";
     }
     var attributes = { final: {} };
     if (Em.isArray(properties)) {
       properties.forEach(function(property) {
 
-        if (property.get('isRequiredByAgent')) {
-          desired_config.properties[property.get('name')] = this.formatValueBeforeSave(property);
+        if (Em.get(property, 'isRequiredByAgent')) {
+          desired_config.properties[Em.get(property, 'name')] = this.formatValueBeforeSave(property);
           /**
            * add is final value
            */
-          if (property.get('isFinal')) {
-            attributes.final[property.get('name')] = "true";
+          if (Em.get(property, 'isFinal')) {
+            attributes.final[Em.get(property, 'name')] = "true";
           }
         }
       }, this);
@@ -441,20 +472,20 @@ App.ConfigsSaverMixin = Em.Mixin.create({
    * @returns {string}
    */
   formatValueBeforeSave: function(property) {
-    var name = property.get('name');
-    var value = property.get('value');
+    var name = Em.get(property, 'name');
+    var value = Em.get(property, 'value');
     var kdcTypesMap = App.router.get('mainAdminKerberosController.kdcTypesValues');
-    //TODO check for core-site
-    if (this.get('heapsizeRegExp').test(name) && !this.get('heapsizeException').contains(name) && !(value).endsWith("m")) {
+
+    if (this.addM(name, value)) {
       return value += "m";
     }
-    if (typeof property.get('value') === "boolean") {
-      return property.get('value').toString();
+    if (typeof value === "boolean") {
+      return value.toString();
     }
     switch (name) {
       case 'kdc_type':
         return Em.keys(kdcTypesMap).filter(function(key) {
-            return kdcTypesMap[key] === property.get('value');
+            return kdcTypesMap[key] === value;
         })[0];
       case 'storm.zookeeper.servers':
       case 'nimbus.seeds':
@@ -465,10 +496,23 @@ App.ConfigsSaverMixin = Em.Mixin.create({
         }
         break;
       default:
-        return App.config.trimProperty(property, true);
+        return App.config.trimProperty(property);
     }
   },
 
+  /**
+   * Site object name follow the format *permsize/*heapsize and the value NOT ends with "m"
+   *
+   * @param name
+   * @param value
+   * @returns {*|boolean}
+   */
+  addM: function (name, value) {
+    return this.get('heapsizeRegExp').test(name)
+      && !this.get('heapsizeException').contains(name)
+      && !(value).endsWith("m");
+  },
+
   /*********************************** 4. AJAX REQUESTS **************************************/
 
   /**
@@ -863,94 +907,5 @@ App.ConfigsSaverMixin = Em.Mixin.create({
         this.hide();
       }
     });
-  },
-
-  /**
-   * Save "final" attribute for properties
-   * @param {Array} properties - array of properties
-   * @returns {Object|null}
-   * @method getConfigAttributes
-   */
-  getConfigAttributes: function(properties) {
-    var attributes = {
-      final: {}
-    };
-    var finalAttributes = attributes.final;
-    var hasAttributes = false;
-    properties.forEach(function (property) {
-      if (property.isRequiredByAgent !== false && property.isFinal) {
-        hasAttributes = true;
-        finalAttributes[property.name] = "true";
-      }
-    });
-    if (hasAttributes) {
-      return attributes;
-    }
-    return null;
-  },
-
-  /**
-   * create site object
-   * @param {string} siteName
-   * @param {string} tagName
-   * @param {object[]} siteObj
-   * @return {Object}
-   * @method createSiteObj
-   */
-  createSiteObj: function (siteName, tagName, siteObj) {
-    var heapsizeException = this.get('heapsizeException');
-    var heapsizeRegExp = this.get('heapsizeRegExp');
-    var siteProperties = {};
-    siteObj.forEach(function (_siteObj) {
-      var value = _siteObj.value;
-      if (_siteObj.isRequiredByAgent == false) return;
-      // site object name follow the format *permsize/*heapsize and the value NOT ends with "m"
-      if (heapsizeRegExp.test(_siteObj.name) && !heapsizeException.contains(_siteObj.name) && !(_siteObj.value).endsWith("m")) {
-        value += "m";
-      }
-      siteProperties[_siteObj.name] = value;
-      switch (siteName) {
-        case 'falcon-startup.properties':
-        case 'falcon-runtime.properties':
-        case 'pig-properties':
-          siteProperties[_siteObj.name] = value;
-          break;
-        default:
-          siteProperties[_siteObj.name] = this.setServerConfigValue(_siteObj.name, value);
-      }
-    }, this);
-    var result = {"type": siteName, "tag": tagName, "properties": siteProperties};
-    var attributes = this.getConfigAttributes(siteObj);
-    if (attributes) {
-      result['properties_attributes'] = attributes;
-    }
-    return result;
-  },
-
-  /**
-   * This method will be moved to config's decorators class.
-   *
-   * For now, provide handling for special properties that need
-   * be specified in special format required for server.
-   *
-   * @param configName {String} - name of config property
-   * @param value {*} - value of config property
-   *
-   * @return {String} - formatted value
-   * @method setServerConfigValue
-   */
-  setServerConfigValue: function (configName, value) {
-    switch (configName) {
-      case 'storm.zookeeper.servers':
-      case 'nimbus.seeds':
-        if(Em.isArray(value)) {
-          return JSON.stringify(value).replace(/"/g, "'");
-        } else {
-          return value;
-        }
-        break;
-      default:
-        return value;
-    }
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/0a9101e9/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 298c9a8..e647eda 100644
--- a/ambari-web/test/controllers/wizard/step8_test.js
+++ b/ambari-web/test/controllers/wizard/step8_test.js
@@ -67,36 +67,6 @@ describe('App.WizardStep8Controller', function () {
     configurationController = App.MainServiceInfoConfigsController.create({});
   });
 
-  var siteObjTests = Em.A([
-    {name: 'createHdfsSiteObj', e: {type: 'hdfs-site', tag: 'version1', l: 2}},
-    {name: 'createHueSiteObj', e: {type: 'hue-site', tag: 'version1', l: 2}},
-    {name: 'createMrSiteObj', e: {type: 'mapred-site', tag: 'version1', l: 2}},
-    {name: 'createYarnSiteObj', e: {type: 'yarn-site', tag: 'version1', l: 2}},
-    {name: 'createCapacityScheduler', e: {type: 'capacity-scheduler', tag: 'version1', l: 2}},
-    {name: 'createMapredQueueAcls', e: {type: 'mapred-queue-acls', tag: 'version1', l: 2}},
-    {name: 'createHbaseSiteObj', e: {type: 'hbase-site', tag: 'version1', l: 2}},
-    {name: 'createOozieSiteObj', e: {type: 'oozie-site', tag: 'version1', l: 2}},
-    {name: 'createHiveSiteObj', e: {type: 'hive-site', tag: 'version1', l: 2}},
-    {name: 'createWebHCatSiteObj', e: {type: 'webhcat-site', tag: 'version1', l: 2}},
-    {name: 'createTezSiteObj', e: {type: 'tez-site', tag: 'version1', l: 2}},
-    {name: 'createPigPropertiesSiteObj', e: {type: 'pig-properties', tag: 'version1', l: 1}},
-    {name: 'createFalconStartupSiteObj', e: {type: 'falcon-startup.properties', tag: 'version1', l: 2}},
-    {name: 'createFalconRuntimeSiteObj', e: {type: 'falcon-runtime.properties', tag: 'version1', l: 2}}
-  ]);
-
-  siteObjTests.forEach(function (test) {
-    describe('#' + test.name, function () {
-
-      it(test.name, function () {
-
-        var siteObj = installerStep8Controller.createSiteObj(test.e.type, test.e.tag);
-        expect(siteObj.tag).to.equal(test.e.tag);
-        expect(Em.keys(siteObj.properties).length).to.equal(test.e.l);
-      });
-
-    });
-  });
-
   App.TestAliases.testAsComputedFilterBy(getController(), 'installedServices', 'content.services', 'isInstalled', true);
 
   App.TestAliases.testAsComputedEqual(getController(), 'isManualKerberos', 'App.router.mainAdminKerberosController.kdc_type', 'none');
@@ -239,91 +209,6 @@ describe('App.WizardStep8Controller', function () {
 
   });
 
-  describe('#createCoreSiteObj', function () {
-
-    beforeEach(function () {
-      var content = Em.Object.create({
-        services: Em.A([
-          Em.Object.create({
-            serviceName: 's1',
-            isSelected: true,
-            isInstalled: false
-          }),
-          Em.Object.create({
-            serviceName: 's2',
-            isSelected: true,
-            isInstalled: false
-          }),
-          Em.Object.create({
-            serviceName: 's3',
-            isSelected: true,
-            isInstalled: false
-          }),
-          Em.Object.create({
-            serviceName: 'GLUSTERFS',
-            isSelected: false,
-            isInstalled: true,
-            configTypesRendered: {hdfs:'tag1'}
-          })
-        ])
-      });
-      var installedServices = content.services.filterProperty('isInstalled', true);
-      var selectedServices = content.services.filterProperty('isSelected', true);
-      installerStep8Controller.set('content', content);
-      installerStep8Controller.set('installedServices', installedServices);
-      installerStep8Controller.set('selectedServices', selectedServices);
-      installerStep8Controller.set('configs', Em.A([
-        Em.Object.create({
-          name: 'fs_glusterfs_default_name',
-          filename: 'core-site.xml',
-          value: 'value',
-          overrides: Em.A([
-            Em.Object.create({
-              value: '4',
-              hosts: Em.A(['h1','h2'])
-            })
-          ])
-        }),
-        Em.Object.create({
-          name: 'fs.defaultFS',
-          filename: 'core-site.xml',
-          value: 'value',
-          overrides: Em.A([
-            Em.Object.create({
-              value: '4',
-              hosts: Em.A(['h1','h2'])
-            })
-          ])
-        }),
-        Em.Object.create({
-          name: 'glusterfs_defaultFS_name',
-          filename: 'core-site.xml',
-          value: 'value',
-          overrides: Em.A([
-            Em.Object.create({
-              value: '4',
-              hosts: Em.A(['h1','h2'])
-            })
-          ])
-        })
-      ]));
-    });
-
-    it('should return config', function () {
-      var expected = {
-        "type": "core-site",
-        "tag": "version1",
-        "properties": {
-          "fs_glusterfs_default_name": "value",
-          "fs.defaultFS": "value",
-          "glusterfs_defaultFS_name": "value"
-        }
-      };
-
-      expect(installerStep8Controller.createCoreSiteObj()).to.eql(expected);
-    });
-  });
-
   describe('#createConfigurationGroups', function () {
     var content;
     beforeEach(function() {
@@ -337,8 +222,7 @@ describe('App.WizardStep8Controller', function () {
         },
         getConfigAttributes: function() {
           return Em.A(['atr']);
-        },
-        createSiteObj: App.MainServiceInfoConfigsController.create({}).createSiteObj.bind(App.MainServiceInfoConfigsController.create({}))
+        }
       }));
       content = Em.Object.create({
         configGroups: Em.A([
@@ -423,22 +307,6 @@ describe('App.WizardStep8Controller', function () {
     });
   });
 
-  describe('#isConfigsChanged', function () {
-    it('should return true if config changed', function () {
-      var properties = Em.Object.create({
-        property:true,
-        property1: Em.Object.create({
-          hasInitialValue: false,
-          isNotDefaultValue: false
-        })
-      });
-      var _configs = Em.A([Em.Object.create({
-        name: 'property'
-      })]);
-      expect(installerStep8Controller.isConfigsChanged(properties, _configs)).to.be.true;
-    });
-  });
-
   describe('#loadServices', function () {
 
     beforeEach(function () {
@@ -1197,42 +1065,6 @@ describe('App.WizardStep8Controller', function () {
 
   });
 
-  describe('#createStormSiteObj', function() {
-    it('should replace quote \'"\' to "\'" for some properties', function() {
-      var _configs = [
-          {filename: 'storm-site.xml', value: ["a", "b"], name: 'storm.zookeeper.servers'}
-        ],
-        expected = {
-          type: 'storm-site',
-          tag: 'version1',
-          properties: {
-            'storm.zookeeper.servers': '[\'a\',\'b\']'
-          }
-        };
-      installerStep8Controller.reopen({configs: _configs});
-      expect(installerStep8Controller.createStormSiteObj('version1')).to.eql(expected);
-    });
-
-    it('should not escape special characters', function() {
-      var _configs = [
-          {filename: 'storm-site.xml', value: "abc\n\t", name: 'nimbus.childopts'},
-          {filename: 'storm-site.xml', value: "a\nb", name: 'supervisor.childopts'},
-          {filename: 'storm-site.xml', value: "a\t\tb", name: 'worker.childopts'}
-        ],
-        expected = {
-          type: 'storm-site',
-          tag: 'version1',
-          properties: {
-            'nimbus.childopts': 'abc\n\t',
-            'supervisor.childopts': 'a\nb',
-            'worker.childopts': 'a\t\tb'
-          }
-        };
-      installerStep8Controller.reopen({configs: _configs});
-      expect(installerStep8Controller.createStormSiteObj('version1')).to.eql(expected);
-    });
-  });
-
   describe('#ajaxQueueFinished', function() {
 
     beforeEach(function () {
@@ -2068,20 +1900,20 @@ describe('App.WizardStep8Controller', function () {
 
   describe('#startDeploy', function () {
 
-    var stubbedNames = ['createCluster', 'createSelectedServices', 'updateConfigurations', 'createConfigurations',
+    var stubbedNames = ['createCluster', 'createSelectedServices', 'createConfigurations',
         'applyConfigurationsToCluster', 'createComponents', 'registerHostsToCluster', 'createConfigurationGroups',
         'createMasterHostComponents', 'createSlaveAndClientsHostComponents', 'createAdditionalClientComponents',
         'createAdditionalHostComponents'],
       cases = [
         {
           controllerName: 'installerController',
-          notExecuted: ['createAdditionalClientComponents', 'updateConfigurations'],
+          notExecuted: ['createAdditionalClientComponents'],
           fileNamesToUpdate: [],
           title: 'Installer, no configs to update'
         },
         {
           controllerName: 'addHostController',
-          notExecuted: ['updateConfigurations', 'createConfigurations', 'applyConfigurationsToCluster', 'createAdditionalClientComponents'],
+          notExecuted: ['createConfigurations', 'applyConfigurationsToCluster', 'createAdditionalClientComponents'],
           title: 'Add Host Wizard'
         },
         {

http://git-wip-us.apache.org/repos/asf/ambari/blob/0a9101e9/ambari-web/test/mixins/common/configs/configs_saver_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mixins/common/configs/configs_saver_test.js b/ambari-web/test/mixins/common/configs/configs_saver_test.js
index 2156a46..f7be831 100644
--- a/ambari-web/test/mixins/common/configs/configs_saver_test.js
+++ b/ambari-web/test/mixins/common/configs/configs_saver_test.js
@@ -22,62 +22,76 @@ describe('App.ConfigsSaverMixin', function() {
   var mixinObject = Em.Controller.extend(App.ConfigsSaverMixin, {});
   var instanceObject = mixinObject.create({});
 
-  describe('#allowSaveSite()', function() {
+  describe('#allowSaveCoreSite()', function () {
+    var allowedType = 'CORETYPE';
+    var allowedService = ['S1'];
     var stackServices = [
       Em.Object.create({
-        serviceName: 'HDFS',
-        serviceType: 'NONHCFS'
+        serviceName: 'S4',
+        serviceType: 'CORETYPE'
       }),
       Em.Object.create({
         serviceName: 'S1',
-        serviceType: 'HCFS'
+        serviceType: 'SOMEOTHERTYPE'
       }),
       Em.Object.create({
         serviceName: 'S2',
-        serviceType: 'NONHCFS'
-      }),
-      Em.Object.create({
-        serviceName: 'S3'
+        serviceType: 'SOMEOTHERTYPE'
       })
     ];
-    beforeEach(function() {
-      instanceObject.set('content', {});
-      sinon.stub(App.StackService, 'find', function () {
-        return stackServices;
+    beforeEach(function () {
+      instanceObject.setProperties({
+        'content': {},
+        'coreSiteServiceType': allowedType,
+        'coreSiteServiceNames': allowedService
       });
     });
 
-    afterEach(function() {
-      App.StackService.find.restore();
-    });
-
-    it('returns true by default', function() {
-      expect(instanceObject.allowSaveSite('some-site')).to.be.true
-    });
-
-    it('returns true for core-site and proper service', function() {
-      instanceObject.set('content.serviceName', 'HDFS');
-      expect(instanceObject.allowSaveSite('core-site.xml')).to.be.true
-    });
-
-    it('returns true for core-site and serviceType HCFS', function() {
-      instanceObject.set('content.serviceName', 'S1');
-      expect(instanceObject.allowSaveSite('core-site.xml')).to.be.true
-    });
-
-    it('returns false for core-site and serviceType not HCFS', function() {
-      instanceObject.set('content.serviceName', 'S2');
-      expect(instanceObject.allowSaveSite('core-site.xml')).to.be.false
-    });
-
-    it('returns false for core-site but serviceType undefined', function() {
-      instanceObject.set('content.serviceName', 'S3');
-      expect(instanceObject.allowSaveSite('core-site.xml')).to.be.false
-    });
+    [{
+      currentServices: stackServices[0],
+      res: true,
+      m: 'service type is ok'
+    }, {
+      currentServices: stackServices[1],
+      res: true,
+      m: 'service name is ok'
+    }, {
+      currentServices: stackServices[2],
+      res: false,
+      m: 'not ok'
+    }].forEach(function (c) {
+        describe(c.m, function () {
+          beforeEach(function () {
+            instanceObject.reopen({
+              currentServices: c.currentServices
+            });
+            it('', function () {
+              expect(instanceObject.allowSaveCoreSite()).to.equal(c.res);
+            });
+          });
+        });
+      });
+  });
 
-    it('returns false for mapred-queue-acls.xml', function() {
-      expect(instanceObject.allowSaveSite('mapred-queue-acls.xml')).to.be.false
-    });
+  describe('allowSaveSite', function() {
+    [
+      { fName: 'mapred-queue-acls', res: false, m: 'file name is restricted to be saved' },
+      { fName: 'core-site', res: true, allowSaveCoreSite: true, m: 'core site is allowed to be saved' },
+      { fName: 'core-site', res: false, allowSaveCoreSite: false, m: 'core site is not allowed to be saved' },
+      { fName: 'other-file-name', res: true, m: 'file name has not restriction rule, so can be saved' }
+    ].forEach(function (c) {
+        describe(c.m, function () {
+          beforeEach(function() {
+            sinon.stub(instanceObject, 'allowSaveCoreSite').returns(c.allowSaveCoreSite);
+          });
+          afterEach(function() {
+            instanceObject.allowSaveCoreSite.restore();
+          });
+          it('', function () {
+            expect(instanceObject.allowSaveSite(c.fName)).to.equal(c.res);
+          });
+        });
+      });
   });
 
   describe('#createDesiredConfig()', function() {