ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ababiic...@apache.org
Subject [2/2] ambari git commit: AMBARI-12468 Remove requests for advanced configs and refactor mergePredefinedWithStored. (ababiichuk)
Date Tue, 21 Jul 2015 10:57:54 GMT
AMBARI-12468 Remove requests for advanced configs and refactor mergePredefinedWithStored. (ababiichuk)


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

Branch: refs/heads/trunk
Commit: 4f78030c424556a1040879697dbc87c44c73459e
Parents: 4bdf025
Author: aBabiichuk <ababiichuk@cybervisiontech.com>
Authored: Tue Jul 21 13:53:51 2015 +0300
Committer: aBabiichuk <ababiichuk@cybervisiontech.com>
Committed: Tue Jul 21 13:57:43 2015 +0300

----------------------------------------------------------------------
 .../controllers/global/cluster_controller.js    |   1 +
 .../main/admin/kerberos/step2_controller.js     |   9 +-
 .../main/admin/kerberos/wizard_controller.js    |  24 +-
 .../main/admin/serviceAccounts_controller.js    |  21 +-
 ambari-web/app/controllers/wizard.js            |  52 +-
 .../app/controllers/wizard/step7_controller.js  |  14 +-
 ambari-web/app/data/HDP2.3/site_properties.js   |   7 +-
 ambari-web/app/data/HDP2/site_properties.js     |   1 +
 .../configs/stack_config_properties_mapper.js   |  48 +-
 ambari-web/app/mappers/configs/themes_mapper.js |   2 +-
 .../mixins/common/configs/enhanced_configs.js   |   2 +-
 .../app/models/configs/stack_config_property.js |   9 +-
 ambari-web/app/routes/add_service_routes.js     |   1 -
 ambari-web/app/routes/installer.js              |   5 +-
 ambari-web/app/utils/ajax/ajax.js               |   5 +
 ambari-web/app/utils/config.js                  | 562 +++++--------------
 .../app/views/common/configs/services_config.js |   4 +-
 ambari-web/app/views/common/controls_view.js    |   2 +-
 .../main/service/info/config_test.js            |  26 +
 .../test/controllers/wizard/step7_test.js       |   8 +-
 ambari-web/test/controllers/wizard_test.js      |  43 --
 .../stack_config_properties_mapper_test.js      |  32 +-
 .../test/mappers/configs/themes_mapper_test.js  |   8 +-
 ambari-web/test/utils/config_test.js            | 390 +------------
 24 files changed, 319 insertions(+), 957 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/controllers/global/cluster_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js
index f83d03e..ad5abd1 100644
--- a/ambari-web/app/controllers/global/cluster_controller.js
+++ b/ambari-web/app/controllers/global/cluster_controller.js
@@ -285,6 +285,7 @@ App.ClusterController = Em.Controller.extend({
           });
 
           updater.updateServiceMetric(function () {
+            App.config.loadClusterConfigsFromStack();
             App.config.loadConfigsFromStack(App.Service.find().mapProperty('serviceName')).complete(function () {
               updater.updateComponentConfig(function () {
                 self.updateLoadStatus('componentConfigs');

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
index 0691891..007ac05 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
@@ -72,6 +72,10 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend({
   },
 
 
+  isConfigsLoaded: function () {
+    return this.get('wizardController.stackConfigsLoaded');
+  }.property('wizardController.stackConfigsLoaded'),
+
   /**
    * On load function
    * @method loadStep
@@ -83,7 +87,7 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend({
     }
     this.clearStep();
     //STEP 1: Load advanced configs
-    var advancedConfigs = this.get('content.advancedServiceConfig');
+    var advancedConfigs = App.StackConfigProperty.find();
     //STEP 2: Load on-site configs by service from local DB
     var storedConfigs = this.get('content.serviceConfigProperties');
     //STEP 3: Merge pre-defined configs with loaded on-site configs
@@ -92,8 +96,7 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend({
       advancedConfigs,
       this.get('selectedServiceNames')));
     App.config.setPreDefinedServiceConfigs(this.get('addMiscTabToPage'));
-    //STEP 4: Add advanced configs
-    App.config.addAdvancedConfigs(this.get('configs'), advancedConfigs);
+
     this.filterConfigs(this.get('configs'));
     this.applyServicesConfigs(this.get('configs'), storedConfigs);
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/controllers/main/admin/kerberos/wizard_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/wizard_controller.js b/ambari-web/app/controllers/main/admin/kerberos/wizard_controller.js
index 5251b66..38008f7 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/wizard_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/wizard_controller.js
@@ -30,6 +30,7 @@ App.KerberosWizardController = App.WizardController.extend({
 
   isKerberosWizard: true,
 
+  stackConfigsLoaded: false,
   /**
    * Used for hiding back button in wizard
    */
@@ -153,21 +154,6 @@ App.KerberosWizardController = App.WizardController.extend({
     this.set('content.serviceConfigProperties', serviceConfigProperties);
   },
 
-  /**
-   * load advanced configs from server
-   */
-  loadAdvancedConfigs: function (dependentController) {
-    var self = this;
-    var loadAdvancedConfigResult = [];
-    dependentController.set('isAdvancedConfigLoaded', false);
-    var serviceName = this.get('content.serviceName');
-    App.config.loadAdvancedConfig(serviceName, function (properties) {
-      loadAdvancedConfigResult.pushObjects(properties);
-      self.set('content.advancedServiceConfig', loadAdvancedConfigResult);
-      dependentController.set('isAdvancedConfigLoaded', true);
-    });
-  },
-
   loadKerberosDescriptorConfigs: function () {
     var kerberosDescriptorConfigs = this.getDBProperty('kerberosDescriptorConfigs');
     this.set('kerberosDescriptorConfigs', kerberosDescriptorConfigs);
@@ -268,9 +254,13 @@ App.KerberosWizardController = App.WizardController.extend({
       {
         type: 'sync',
         callback: function () {
-          var kerberosStep2controller = App.get('router.kerberosWizardStep2Controller');
-          this.loadAdvancedConfigs(kerberosStep2controller);
+          var self = this;
           this.loadServiceConfigProperties();
+          if (!this.get('stackConfigsLoaded')) {
+            App.config.loadConfigsFromStack(['KERBEROS']).complete(function() {
+              self.set('stackConfigsLoaded', true);
+            }, this);
+          }
         }
       }
     ],

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/controllers/main/admin/serviceAccounts_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/serviceAccounts_controller.js b/ambari-web/app/controllers/main/admin/serviceAccounts_controller.js
index 1d72d0c..ccbac3e 100644
--- a/ambari-web/app/controllers/main/admin/serviceAccounts_controller.js
+++ b/ambari-web/app/controllers/main/admin/serviceAccounts_controller.js
@@ -45,9 +45,7 @@ App.MainAdminServiceAccountsController = App.MainServiceInfoConfigsController.ex
   },
   loadServiceTagSuccess: function (data, opt, params) {
     var self = this;
-    var installedServices = App.Service.find().mapProperty("serviceName");
     var serviceConfigsDef = params.serviceConfigsDef;
-    var serviceName = this.get('selectedService');
     var loadedClusterSiteToTagMap = {};
 
     for (var site in Em.get(data, 'Clusters.desired_configs')) {
@@ -58,15 +56,8 @@ App.MainAdminServiceAccountsController = App.MainServiceInfoConfigsController.ex
     this.setServiceConfigTags(loadedClusterSiteToTagMap);
     // load server stored configurations
     App.router.get('configurationController').getConfigsByTags(this.get('serviceConfigTags')).done(function (serverConfigs) {
-      // load configurations list for installed services
-      App.config.loadAdvancedConfigPartial(installedServices, {
-        queryFilter: 'configurations/StackConfigurations/property_type.matches(.*[USER,GROUP].*)'
-      }, function(advancedConfigs) {
-        // load cluster configs
-        App.config.loadClusterConfig(function(clusterConfigs) {
-          self.createConfigObject(serverConfigs, advancedConfigs.concat(clusterConfigs));
-        });
-      });
+      var stackConfigs = App.StackConfigProperty.find().filterProperty('displayType', 'user');
+      self.createConfigObject(serverConfigs, stackConfigs);
     });
   },
 
@@ -111,11 +102,11 @@ App.MainAdminServiceAccountsController = App.MainServiceInfoConfigsController.ex
    * Generate configuration object that will be rendered
    *
    * @param {Object[]} serverConfigs
-   * @param {Object[]} advancedConfigs
+   * @param {Object[]} stackConfigs
    */
-  createConfigObject: function(serverConfigs, advancedConfigs) {
-    var configs = App.config.mergePredefinedWithSaved(serverConfigs, advancedConfigs, this.get('selectedService'));
-    var miscConfigs = configs.filterProperty('serviceName', this.get('selectedService')).filterProperty('category', 'Users and Groups').filterProperty('isVisible', true).rejectProperty('displayType', 'password').rejectProperty('displayType', 'checkbox');
+  createConfigObject: function(serverConfigs, stackConfigs) {
+    var configs = App.config.mergePredefinedWithSaved(serverConfigs, stackConfigs, this.get('selectedService'));
+    var miscConfigs = configs.filterProperty('displayType', 'user').filterProperty('category', 'Users and Groups').filterProperty('isVisible', true);
 
     miscConfigs = App.config.miscConfigVisibleProperty(miscConfigs, App.Service.find().mapProperty('serviceName').concat('MISC'));
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index 102d64c..1124188 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -833,43 +833,6 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
   },
 
   /**
-   * load advanced configs from server
-   */
-  loadAdvancedConfigs: function (dependentController) {
-    var self = this;
-    var loadServiceConfigsFn = function (clusterProperties) {
-      var stackServices = self.get('content.services').filter(function (service) {
-        return service.get('isInstalled') || service.get('isSelected');
-      });
-      var loadAdvancedConfigResult = [];
-      dependentController.set('isAdvancedConfigLoaded', false);
-
-      App.config.loadAdvancedConfigAll(stackServices.mapProperty('serviceName'), function (configMap) {
-        stackServices.forEach(function (service) {
-          var serviceName = service.get('serviceName');
-          var properties = configMap[serviceName];
-          var supportsFinal = App.config.getConfigTypesInfoFromService(service).supportsFinal;
-
-          properties.forEach(function (property) {
-            property.supportsFinal = Boolean(supportsFinal.find(function (configType) {
-              return property.filename.startsWith(configType);
-            }));
-            if (property.serviceName == 'MISC' && property.name == 'yarn_user') {
-               property.supportsFinal = false;
-            }
-          });
-          loadAdvancedConfigResult.pushObjects(properties);
-        });
-        loadAdvancedConfigResult.pushObjects(clusterProperties);
-        self.set('content.advancedServiceConfig', loadAdvancedConfigResult);
-        dependentController.set('isAdvancedConfigLoaded', true);
-      });
-    };
-    App.config.loadClusterConfig(loadServiceConfigsFn);
-  },
-
-
-  /**
    * Load serviceConfigProperties to model
    */
   loadServiceConfigProperties: function () {
@@ -912,7 +875,8 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
           isRequired: _configProperties.get('isRequired'), // flag that allow saving property with empty value
           group: !!_configProperties.get('group') ? _configProperties.get('group.name') : null,
           showLabel: _configProperties.get('showLabel'),
-          category: _configProperties.get('category')
+          category: _configProperties.get('category'),
+          configId: App.config.configId(_configProperties.get('name'),_configProperties.get('filename'))
         };
         serviceConfigProperties.push(configProperty);
       }, this);
@@ -1265,11 +1229,13 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
         return s.get('isSelected') || s.get('isInstalled');
       }).mapProperty('serviceName');
       // Load stack configs before loading themes
-      App.config.loadConfigsFromStack(serviceNames).done(function () {
-        self.loadConfigThemeForServices(serviceNames).always(function () {
-          self.set('stackConfigsLoaded', true);
-          App.themesMapper.generateAdvancedTabs(serviceNames);
-          dfd.resolve();
+      App.config.loadClusterConfigsFromStack().always(function() {
+        App.config.loadConfigsFromStack(serviceNames).done(function () {
+          self.loadConfigThemeForServices(serviceNames).always(function () {
+            self.set('stackConfigsLoaded', true);
+            App.themesMapper.generateAdvancedTabs(serviceNames);
+            dfd.resolve();
+          });
         });
       });
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/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 8c8e50d..fb65af3 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -105,20 +105,14 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
   serviceConfigTags: [],
 
   /**
-   * Are advanced configs loaded
-   * @type {bool}
-   */
-  isAdvancedConfigLoaded: true,
-
-  /**
    * Are applied to service configs loaded
    * @type {bool}
    */
   isAppliedConfigLoaded: true,
 
   isConfigsLoaded: function () {
-    return (this.get('isAdvancedConfigLoaded') && this.get('isAppliedConfigLoaded'));
-  }.property('isAdvancedConfigLoaded', 'isAppliedConfigLoaded'),
+    return (this.get('wizardController.stackConfigsLoaded') && this.get('isAppliedConfigLoaded'));
+  }.property('wizardController.stackConfigsLoaded', 'isAppliedConfigLoaded'),
 
   /**
    * Number of errors in the configs in the selected service
@@ -626,7 +620,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
 
     var self = this;
     //STEP 1: Load advanced configs
-    var advancedConfigs = this.get('content.advancedServiceConfig');
+    var advancedConfigs = App.StackConfigProperty.find();
     //STEP 2: Load on-site configs by service from local DB
     var storedConfigs = this.get('content.serviceConfigProperties');
     //STEP 3: Merge pre-defined configs with loaded on-site configs
@@ -636,8 +630,6 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
       this.get('selectedServiceNames').concat(this.get('installedServiceNames'))
     );
     App.config.setPreDefinedServiceConfigs(this.get('addMiscTabToPage'));
-    //STEP 4: Add advanced configs
-    App.config.addAdvancedConfigs(configs, advancedConfigs);
 
     this.set('groupsToDelete', this.get('wizardController').getDBProperty('groupsToDelete') || []);
     if (this.get('wizardController.name') === 'addServiceController') {

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/data/HDP2.3/site_properties.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/HDP2.3/site_properties.js b/ambari-web/app/data/HDP2.3/site_properties.js
index 5e2b2c1..0b86817 100644
--- a/ambari-web/app/data/HDP2.3/site_properties.js
+++ b/ambari-web/app/data/HDP2.3/site_properties.js
@@ -41,7 +41,12 @@ var excludedConfigs = [
   'xa_ldap_ad_domain',
   'xa_ldap_ad_url',
   'policymgr_http_enabled',
-  'policymgr_external_url'
+  'policymgr_external_url',
+  'hbase.regionserver.global.memstore.lowerLimit',
+  'hbase.regionserver.global.memstore.upperLimit',
+  "port",
+  "hive.metastore.heapsize",
+  "hive.client.heapsize"
 ];
 
 var hdp23properties = hdp22properties.filter(function (item) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/data/HDP2/site_properties.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/HDP2/site_properties.js b/ambari-web/app/data/HDP2/site_properties.js
index d946900..e359a41 100644
--- a/ambari-web/app/data/HDP2/site_properties.js
+++ b/ambari-web/app/data/HDP2/site_properties.js
@@ -181,6 +181,7 @@ var hdp2properties = [
     "isRequiredByAgent": false,
     "isVisible": false,
     "category": "Advanced hdfs-site",
+    "filename": "hdfs-site.xml",
     "serviceName": "HDFS"
   },
   {

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/mappers/configs/stack_config_properties_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/configs/stack_config_properties_mapper.js b/ambari-web/app/mappers/configs/stack_config_properties_mapper.js
index 8315565..0fc5340 100644
--- a/ambari-web/app/mappers/configs/stack_config_properties_mapper.js
+++ b/ambari-web/app/mappers/configs/stack_config_properties_mapper.js
@@ -34,25 +34,34 @@ App.stackConfigPropertiesMapper = App.QuickDataMapper.create({
     property_depended_by: 'StackConfigurations.property_depended_by',
     property_depends_on: 'StackConfigurations.property_depends_on',
     value_attributes: 'StackConfigurations.property_value_attributes',
-    is_final: 'default_is_final',
-    recommended_is_final: 'default_is_final',
+    is_final: 'recommended_is_final',
+    recommended_is_final: 'recommended_is_final',
     supports_final: 'supports_final',
     widget: 'widget',
     /**** ui properties ***/
     display_type: 'display_type',
-    category: 'category'
+    category: 'category',
+    index: 'index'
   },
 
   map: function (json) {
-    console.time('stackConfigMapper execution time');
+    console.time('stackConfigPropertiesMapper execution time');
+    if (json && json.Versions) {
+      //hack for cluster versions
+      json = {items: [json]};
+      var clusterConfigs = true;
+    }
     if (json && json.items) {
       var configs = [];
       json.items.forEach(function(stackItem) {
-        var configTypeInfo = Em.get(stackItem, 'StackServices.config_types');
+        var configTypeInfo = clusterConfigs ? Em.get(stackItem, 'Versions.config_types') : Em.get(stackItem, 'StackServices.config_types');
 
         stackItem.configurations.forEach(function(config) {
+          if (clusterConfigs) {
+            config.StackConfigurations = config.StackLevelConfigurations;
+          }
           var configType = App.config.getConfigTagFromFileName(config.StackConfigurations.type);
-          config.id = config.StackConfigurations.property_name + '_' + configType;
+          config.id = App.config.configId(config.StackConfigurations.property_name, configType);
           config.recommended_is_final = config.StackConfigurations.final === "true";
           config.supports_final = !!configTypeInfo[configType] && configTypeInfo[configType].supports.final === "true";
           // Map from /dependencies to property_depended_by
@@ -80,7 +89,7 @@ App.stackConfigPropertiesMapper = App.QuickDataMapper.create({
         this.setDependentServices(service);
       }, this);
     }
-    console.timeEnd('stackConfigMapper execution time');
+    console.timeEnd('stackConfigPropertiesMapper execution time');
   },
 
   /******************* METHODS TO MERGE STACK PROPERTIES WITH STORED ON UI *********************************/
@@ -92,17 +101,18 @@ App.stackConfigPropertiesMapper = App.QuickDataMapper.create({
    * @method mergeWithUI
    */
   mergeWithUI: function(config) {
-    var uiConfigProperty = this.getUIConfig(config.StackConfigurations.property_name, config.StackConfigurations.type);
-    var displayType = App.permit(App.config.advancedConfigIdentityData(config.StackConfigurations), 'displayType').displayType || 'string';
-    if (!config.StackConfigurations.property_display_name) {
-      config.StackConfigurations.property_display_name = uiConfigProperty && uiConfigProperty.displayName ? uiConfigProperty.displayName : config.StackConfigurations.property_name;
-    }
-    config.category = uiConfigProperty ? uiConfigProperty.category : 'Advanced ' + App.config.getConfigTagFromFileName(config.StackConfigurations.type);
-    if (App.config.isContentProperty(config.StackConfigurations.property_name, config.StackConfigurations.type)) {
-      config.display_type = 'content';
-    } else {
-      config.display_type = uiConfigProperty ? uiConfigProperty.displayType || displayType : displayType;
+    var c = config.StackConfigurations;
+    var uiConfigProperty = this.getUIConfig(c.property_name, c.type);
+    var advancedData = App.config.advancedConfigIdentityData(c);
+
+    if (!c.property_display_name) {
+      c.property_display_name = App.config.getPropertyIfExists('displayName', App.config.getDefaultDisplayName(c.property_name, c.type), advancedData, uiConfigProperty);
     }
+    c.service_name = App.config.getPropertyIfExists('serviceName', c.service_name, advancedData, uiConfigProperty);
+
+    config.category = App.config.getPropertyIfExists('category', App.config.getDefaultCategory(true, c.type), advancedData, uiConfigProperty);
+    config.display_type = App.config.getPropertyIfExists('displayType', App.config.getDefaultDisplayType(c.property_name, c.type, c.property_value), advancedData, uiConfigProperty);
+    config.index = App.config.getPropertyIfExists('index', null, advancedData, uiConfigProperty);
   },
 
   /**
@@ -114,7 +124,7 @@ App.stackConfigPropertiesMapper = App.QuickDataMapper.create({
    * @method getUIConfig
    */
   getUIConfig: function(propertyName, siteName) {
-    return App.config.get('preDefinedSiteProperties').filterProperty('filename', siteName).findProperty('name', propertyName);
+    return App.config.get('preDefinedSitePropertiesMap')[App.config.configId(propertyName, siteName)];
   },
 
   /**
@@ -145,7 +155,7 @@ App.stackConfigPropertiesMapper = App.QuickDataMapper.create({
       stackProperty.get(key).forEach(function(dependent) {
         var tag = App.config.getConfigTagFromFileName(dependent.type);
         /** setting dependent serviceNames (without current serviceName) **/
-        var dependentProperty = App.StackConfigProperty.find(dependent.name + "_" + tag);
+        var dependentProperty = App.StackConfigProperty.find(App.config.configId(dependent.name, tag));
         if (dependentProperty) {
           if (dependentProperty.get('serviceName') && dependentProperty.get('serviceName') != service.get('serviceName') && !service.get('dependentServiceNames').contains(dependentProperty.get('serviceName'))) {
             service.set('dependentServiceNames', service.get('dependentServiceNames').concat([dependentProperty.get('serviceName')]));

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/mappers/configs/themes_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/configs/themes_mapper.js b/ambari-web/app/mappers/configs/themes_mapper.js
index eda0e52..e632860 100644
--- a/ambari-web/app/mappers/configs/themes_mapper.js
+++ b/ambari-web/app/mappers/configs/themes_mapper.js
@@ -164,7 +164,7 @@ App.themesMapper = App.QuickDataMapper.create({
   getConfigId: function(json) {
     if (json && json.config && typeof json.config === "string") {
       var split = json.config.split("/");
-      return split[1] + "_" + split[0];
+      return App.config.configId(split[1], split[0]);
     } else {
       console.warn('getConfigId: invalid input data');
       return null;

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/mixins/common/configs/enhanced_configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/enhanced_configs.js b/ambari-web/app/mixins/common/configs/enhanced_configs.js
index 5118807..36cf8e6 100644
--- a/ambari-web/app/mixins/common/configs/enhanced_configs.js
+++ b/ambari-web/app/mixins/common/configs/enhanced_configs.js
@@ -556,7 +556,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create({
       var properties = configs[siteName].property_attributes || {};
       Em.keys(properties).forEach(function (propertyName) {
         var cp = configProperties.findProperty('name', propertyName);
-        var stackProperty = App.StackConfigProperty.find().findProperty('id', propertyName + '_' + siteName);
+        var stackProperty = App.StackConfigProperty.find().findProperty('id', App.config.configId(propertyName, siteName));
         var attributes = properties[propertyName] || {};
         Em.keys(attributes).forEach(function (attributeName) {
           if (attributeName == 'delete') {

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/models/configs/stack_config_property.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/stack_config_property.js b/ambari-web/app/models/configs/stack_config_property.js
index 7caeadf..a1925a4 100644
--- a/ambari-web/app/models/configs/stack_config_property.js
+++ b/ambari-web/app/models/configs/stack_config_property.js
@@ -86,7 +86,7 @@ App.StackConfigProperty = DS.Model.extend({
    * service name
    * @property {string}
    */
-  serviceName:  DS.attr('string'),
+  serviceName:  DS.attr('string', {defaultValue: 'MISC'}),
 
   /**
    * stack name
@@ -182,7 +182,12 @@ App.StackConfigProperty = DS.Model.extend({
    * config property isFinal value same as recommendedIsFinal
    * @property {boolean}
    */
-  isFinal: DS.attr('boolean', {defaultValue: false})
+  isFinal: DS.attr('boolean', {defaultValue: false}),
+
+  /**
+   * @type {boolean}
+   */
+  index: DS.attr('number', {defaultValue: null})
 });
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/routes/add_service_routes.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/add_service_routes.js b/ambari-web/app/routes/add_service_routes.js
index c646002..bb8efe1 100644
--- a/ambari-web/app/routes/add_service_routes.js
+++ b/ambari-web/app/routes/add_service_routes.js
@@ -201,7 +201,6 @@ module.exports = App.WizardRoute.extend({
       controller.dataLoading().done(function () {
         var wizardStep7Controller = router.get('wizardStep7Controller');
         controller.loadAllPriorSteps().done(function () {
-          controller.loadAdvancedConfigs(wizardStep7Controller);
           wizardStep7Controller.getConfigTags();
           wizardStep7Controller.set('wizardController', controller);
           controller.usersLoading().done(function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/routes/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/installer.js b/ambari-web/app/routes/installer.js
index 6f36939..37153ac 100644
--- a/ambari-web/app/routes/installer.js
+++ b/ambari-web/app/routes/installer.js
@@ -301,11 +301,8 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
     },
     connectOutlets: function (router, context) {
       var controller = router.get('installerController');
-
+      var wizardStep7Controller = router.get('wizardStep7Controller');
       controller.loadAllPriorSteps().done(function () {
-        var wizardStep7Controller = router.get('wizardStep7Controller');
-        controller.loadAdvancedConfigs(wizardStep7Controller);
-        wizardStep7Controller.set('isAdvancedConfigLoaded', false);
         wizardStep7Controller.set('wizardController', controller);
         controller.connectOutlet('wizardStep7', controller.get('content'));
       });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index cb7c239..b52cb91 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -640,6 +640,11 @@ var urls = {
 
   /*************************STACK CONFIGS**************************************/
 
+  'configs.stack_configs.load.cluster_configs': {
+    'real': '{stackVersionUrl}?fields=configurations/*,Versions/config_types/*',
+    'mock': '/data/stacks/HDP-2.2/configurations.json'
+  },
+
   'configs.stack_configs.load.all': {
     'real': '{stackVersionUrl}/services?fields=configurations/*,StackServices/config_types/*',
     'mock': '/data/stacks/HDP-2.2/configurations.json'

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index c229d1d..2595c8e 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -28,7 +28,7 @@ App.config = Em.Object.create({
    * filename exceptions used to support substandard sitenames which don't have "xml" extension
    * @type {string[]}
    */
-  filenameExceptions: [],
+  filenameExceptions: ['alert_notification'],
 
   preDefinedServiceConfigs: [],
 
@@ -73,6 +73,16 @@ App.config = Em.Object.create({
     return fileName.endsWith('.xml') ? fileName.slice(0, -4) : fileName;
   },
 
+  /**
+   *
+   * @param name
+   * @param fileName
+   * @returns {string}
+   */
+  configId: function(name, fileName) {
+    return name + "__" + App.config.getConfigTagFromFileName(fileName);
+  },
+
   setPreDefinedServiceConfigs: function (isMiscTabToBeAdded) {
     var configs = this.get('preDefinedSiteProperties');
     var services = [];
@@ -124,18 +134,35 @@ App.config = Em.Object.create({
 
   preDefinedSiteProperties: function () {
     var sitePropertiesForCurrentStack = this.preDefinedConfigFile('site_properties');
+    var serviceNames = App.StackService.find().mapProperty('serviceName').concat('MISC');
+    var properties = [];
     if (sitePropertiesForCurrentStack) {
-      return sitePropertiesForCurrentStack.configProperties;
-    }
-    if (App.get('isHadoop23Stack')) {
-      return require('data/HDP2.3/site_properties').configProperties;
-    }
-    if (App.get('isHadoop22Stack')) {
-      return require('data/HDP2.2/site_properties').configProperties;
+      properties =  sitePropertiesForCurrentStack.configProperties;
+    } else if (App.get('isHadoop23Stack')) {
+      properties = require('data/HDP2.3/site_properties').configProperties;
+    } else if (App.get('isHadoop22Stack')) {
+      properties = require('data/HDP2.2/site_properties').configProperties;
+    } else {
+      properties = require('data/HDP2/site_properties').configProperties;
     }
-    return require('data/HDP2/site_properties').configProperties;
+    return properties.filter(function(p) {
+      return serviceNames.contains(p.serviceName);
+    });
   }.property('App.isHadoop22Stack', 'App.isHadoop23Stack'),
 
+  /**
+   * map of <code>preDefinedSiteProperties</code> provide search by index
+   * @type {object}
+   */
+  preDefinedSitePropertiesMap: function () {
+    var map = {};
+
+    this.get('preDefinedSiteProperties').forEach(function (c) {
+      map[this.configId(c.name, c.filename)] = c;
+    }, this);
+    return map;
+  }.property('preDefinedSiteProperties'),
+
   preDefinedConfigFile: function(file) {
     try {
       return require('data/{0}/{1}'.format(App.get('currentStackName'), file));
@@ -284,10 +311,12 @@ App.config = Em.Object.create({
       var properties = siteConfig.properties || {};
 
       for (var index in properties) {
-        var configsPropertyDef = this.get('preDefinedSiteProperties').filterProperty('name', index).findProperty('filename', filename);
+        var configsPropertyDef = this.get('preDefinedSitePropertiesMap')[this.configId(index, filename)];
         var advancedConfig = advancedConfigs.filterProperty('name', index).findProperty('filename', filename);
-        var template = this.createDefaultConfig(index, filename, properties[index], finalAttributes[index] === "true", serviceName, !!advancedConfig, configsPropertyDef && configsPropertyDef.id === 'puppet var');
-        var serviceConfigObj = this.mergeStackConfigsWithUI(template, advancedConfig, configsPropertyDef);
+        var value = properties[index], isFinal = finalAttributes[index] === "true";
+
+        var template = this.createDefaultConfig(index, filename, !!advancedConfig, {value: value, savedValue: value, isFinal: isFinal, savedIsFinal: isFinal});
+        var serviceConfigObj = Em.Object.create(this.mergeStaticProperties(template, advancedConfig, configsPropertyDef));
 
         if (serviceConfigObj.get('isRequiredByAgent') !== false) {
           var formattedValue = this.formatPropertyValue(serviceConfigObj);
@@ -313,65 +342,68 @@ App.config = Em.Object.create({
    * config property but is used when such properties are absent in stack/UI configs
    * @param {string} name
    * @param {string} fileName
-   * @param {string} value
-   * @param {boolean} isFinal
-   * @param {string} serviceName
    * @param {boolean} definedInStack
-   * @param {boolean} [isPuppetVar=false];
+   * @param {Object} [coreObject]
    * @returns {Object}
    */
-  createDefaultConfig: function(name, fileName, value, isFinal, serviceName, definedInStack, isPuppetVar) {
-    return {
+  createDefaultConfig: function(name, fileName, definedInStack, coreObject) {
+    return $.extend({
       /** core properties **/
       name: name,
       filename: fileName,
-      value: value,
-      savedValue: value,
-      isFinal: isFinal,
-      savedIsFinal: isFinal,
+      value: '',
+      savedValue: null,
+      isFinal: false,
+      savedIsFinal: null,
       /** UI and Stack properties **/
       recommendedValue: null,
       recommendedIsFinal: null,
       supportsFinal: false,
-      serviceName: serviceName,
+      serviceName: 'MISC',
+      defaultDirectory: '',
       displayName: this.getDefaultDisplayName(name, fileName),
-      displayType: this.getDefaultDisplayType(value),
+      displayType: this.getDefaultDisplayType(name, fileName, coreObject ? coreObject.value : ''),
       description: null,
       category: this.getDefaultCategory(definedInStack, fileName),
       isSecureConfig: this.getIsSecure(name),
-      showLabel: !this.isContentProperty(name, fileName, ['-log4j']),
+      showLabel: this.getDefaultIsShowLabel(name, fileName),
       isVisible: true,
       isUserProperty: !definedInStack,
       isRequired: definedInStack,
-      id: isPuppetVar ? 'puppet var' : 'site property',
+      id: 'site property',
       isRequiredByAgent:  true,
       isReconfigurable: true,
+      isObserved: false,
       unit: null,
+      overrides: null,
+      hasInitialValue: false,
       isOverridable: true,
       index: null,
       dependentConfigPattern: null,
       options: null,
       radioName: null,
       belongsToService: []
-    }
+    }, coreObject);
   },
 
   /**
    * This method merge properties form <code>stackConfigProperty<code> which are taken from stack
    * with <code>UIConfigProperty<code> which are hardcoded on UI
-   * @param template
-   * @param stackConfigProperty
-   * @param UIConfigProperty
+   * @param coreObject
+   * @param preDefined
+   * @param stackProperty
+   * @param [propertiesToSkip]
+   * @param [preDefinedOnly]
    */
-  mergeStackConfigsWithUI: function(template, stackConfigProperty, UIConfigProperty) {
-    var doNotOverride = ['name', 'filename', 'value', 'savedValue', 'isFinal', 'savedIsFinal', 'id'];
-    var configProperty = Em.Object.create(template);
-    for (var key in template) {
-      if (!doNotOverride.contains(key)) {
-        configProperty.set(key, this.getPropertyIfExists(key, template[key], stackConfigProperty, UIConfigProperty));
+  mergeStaticProperties: function(coreObject, preDefined, stackProperty, propertiesToSkip, preDefinedOnly) {
+    propertiesToSkip = propertiesToSkip || ['name', 'filename', 'value', 'savedValue', 'isFinal', 'savedIsFinal'];
+    preDefinedOnly = preDefinedOnly || ['id'];
+    for (var k in coreObject) {
+      if (!propertiesToSkip.contains(k)) {
+        coreObject[k] = this.getPropertyIfExists(k, coreObject[k], !preDefinedOnly.contains(k) ? stackProperty : null, preDefined);
       }
     }
-    return configProperty;
+    return coreObject;
   },
 
   /**
@@ -397,11 +429,16 @@ App.config = Em.Object.create({
 
   /**
    * Get displayType for properties that has not defined value
+   * @param name
+   * @param type
    * @param value
    * @returns {string}
    */
-  getDefaultDisplayType: function(value) {
-    return stringUtils.isSingleLine(value) ? 'advanced' : 'multiLine';
+  getDefaultDisplayType: function(name, type, value) {
+    if (this.isContentProperty(name, type)) {
+      return 'content';
+    }
+    return value && !stringUtils.isSingleLine(value) ? 'multiLine' : 'advanced';
   },
 
   /**
@@ -445,6 +482,15 @@ App.config = Em.Object.create({
   },
 
   /**
+   *
+   * @param name
+   * @param fileName
+   */
+  getDefaultIsShowLabel: function(name, fileName) {
+    return !this.isContentProperty(name, fileName) || this.isContentProperty(name, fileName, ['-env']);
+  },
+
+  /**
    * format property value depending on displayType
    * and one exception for 'kdc_type'
    * @param serviceConfigProperty
@@ -496,9 +542,13 @@ App.config = Em.Object.create({
    * @returns {boolean}
    */
   isContentProperty: function(name, fileName, tagEnds) {
-    tagEnds = tagEnds || ['-env', '-log4j'];
-    var  type = this.getConfigTagFromFileName(fileName);
-    return name == 'content' && tagEnds.some(function(tagEnd) { return type.endsWith(tagEnd)});
+    if (tagEnds && tagEnds.length) {
+      //tagEnds = tagEnds || ['-env', '-log4j'];
+      var  type = this.getConfigTagFromFileName(fileName);
+      return name == 'content' && tagEnds.some(function(tagEnd) { return type.endsWith(tagEnd)});
+    } else {
+      return name == 'content';
+    }
   },
 
   /**
@@ -538,70 +588,43 @@ App.config = Em.Object.create({
    */
   mergePreDefinedWithStored: function (storedConfigs, advancedConfigs, selectedServiceNames) {
     var mergedConfigs = [];
-    var contentProperties = advancedConfigs ? this.createContentProperties(advancedConfigs) : [];
-    var preDefinedConfigs = this.get('preDefinedSiteProperties').concat(contentProperties);
-    var self = this;
+
     storedConfigs = (storedConfigs) ? storedConfigs : [];
 
-    var preDefinedNames = preDefinedConfigs.mapProperty('name');
-    var storedNames = storedConfigs.mapProperty('name');
-    var names = preDefinedNames.concat(storedNames).uniq();
     var configTypes = App.StackService.find().filter(function(service) {
       return selectedServiceNames.contains(service.get('serviceName'));
     }).map(function(item) {
       return Em.keys(item.get('configTypes'));
-    }).reduce(function(p,c) { return p.concat(c); })
-    .uniq().compact().filter(function(configType) { return !!configType; });
-
-    names.forEach(function (name) {
-      var storedCfgs = storedConfigs.filterProperty('name', name);
-      var preDefinedCfgs = [];
-      var preDefinedConfig = preDefinedConfigs.filterProperty('name', name);
-      preDefinedConfig.forEach(function (_preDefinedConfig) {
-        if (selectedServiceNames.contains(_preDefinedConfig.serviceName) || _preDefinedConfig.serviceName === 'MISC') {
-          if (_preDefinedConfig.serviceName != 'MISC' && _preDefinedConfig.filename && !configTypes.contains(self.getConfigTagFromFileName(_preDefinedConfig.filename))) {
-            return;
-          }
-          preDefinedCfgs.push($.extend(true, {}, _preDefinedConfig));
-        }
-      }, this);
-
-      var configData = {};
-      var isAdvanced = advancedConfigs && advancedConfigs.someProperty('name', name);
-      if (storedCfgs.length <= 1 && preDefinedCfgs.length <= 1) {
-        var stored = storedCfgs[0];
-        var preDefined = preDefinedCfgs[0];
-
-        if (preDefined && stored) {
-          configData = preDefined;
-          configData.value = stored.value;
-          configData.savedValue = stored.savedValue;
-          configData.recommendedValue = stored.recommendedValue;
-          configData.overrides = stored.overrides;
-          configData.displayName = stored.displayName;
-          configData.name = stored.name;
-          configData.filename = stored.filename;
-          configData.description = stored.description;
-          configData.isVisible = stored.isVisible;
-          configData.isFinal = stored.isFinal;
-          configData.supportsFinal = stored.supportsFinal;
-          configData.isRequired = (configData.isRequired !== undefined) ? configData.isRequired : true;
-          configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
-          configData.showLabel = !!stored.showLabel;
-        }
-        else if (!preDefined && stored) {
-          configData = this.addUserProperty(stored, isAdvanced, advancedConfigs);
-        }
-        else if (preDefined && !stored) {
-          configData = preDefined;
-          // skip property if predefined config doesn't exist or ignored in stack property definition for current stack.
-          // if `isRequiredByAgent` is set to `false` then this property used by UI only to display properties like
-          // host names or some misc properties that won't be persisted.
-          var isPresentInConfigApi = advancedConfigs && advancedConfigs.filterProperty('filename', preDefined.filename).someProperty('name', name);
-          if (Em.get(preDefined, 'isRequiredByAgent') !== false && !isPresentInConfigApi &&
-              Em.get(preDefined, 'filename') != 'alert_notification' &&
-              ![
-                'hive_hostname',
+    }).reduce(function(p,c) { return p.concat(c); }).concat(['cluster-env', 'alert_notification'])
+      .uniq().compact().filter(function(configType) { return !!configType; });
+
+    var storedIds = storedConfigs.map(function(s) { return this.configId(s.name, s.filename); }, this);
+    var predefinedIds = Object.keys(this.get('preDefinedSitePropertiesMap'));
+    var stackIds = advancedConfigs.mapProperty('id');
+
+    var configIds = stackIds.concat(predefinedIds).concat(storedIds).uniq();
+
+    configIds.forEach(function(id) {
+      if (id) {
+        var stored = storedConfigs.findProperty('configId', id);
+        var preDefined = this.get('preDefinedSitePropertiesMap')[id];
+        var advanced = App.StackConfigProperty.find(id);
+
+        var name = this.getPropertyIfExists('name', stored && stored.name, advanced, preDefined);
+        var filename = this.getPropertyIfExists('filename', stored && stored.filename, advanced, preDefined);
+        if (configTypes.contains(this.getConfigTagFromFileName(filename))) {
+
+          var isAdvanced = advanced.get('id');
+          var core = stored || { value: this.getPropertyIfExists('value', '', advanced, preDefined), isFinal: this.getPropertyIfExists('isFinal', false, advanced, preDefined)};
+          var configData = this.createDefaultConfig(name, filename, isAdvanced || !!preDefined, core);
+
+          if (preDefined && !stored) {
+            // skip property if predefined config doesn't exist or ignored in stack property definition for current stack.
+            // if `isRequiredByAgent` is set to `false` then this property used by UI only to display properties like
+            // host names or some misc properties that won't be persisted.
+            if (Em.get(preDefined, 'isRequiredByAgent') !== false && !isAdvanced &&
+             filename != 'alert_notification' && advanced.get('serviceName') != 'MISC' &&
+              !['hive_hostname',
                 'oozie_hostname',
                 'hive_existing_oracle_host',
                 'hive_existing_postgresql_host',
@@ -614,121 +637,25 @@ App.config = Em.Object.create({
                 'oozie_existing_mssql_server_host',
                 'oozie_existing_mssql_server_2_host'
               ].contains(Em.get(preDefined, 'name'))) {
-            return;
-          }
-          configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
-          if (isAdvanced) {
-            var advanced = advancedConfigs.filterProperty('filename', configData.filename).findProperty('name', configData.name);
-            this.setPropertyFromStack(configData, advanced);
+              return;
+            }
           }
-        }
 
-        mergedConfigs.push(configData);
-      } else {
-        preDefinedCfgs.forEach(function (cfg) {
-          configData = cfg;
-          configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
-          var storedCfg = storedCfgs.findProperty('filename', cfg.filename);
-          if (storedCfg) {
-            configData.value = storedCfg.value;
-            configData.recommendedValue = storedCfg.recommendedValue;
-            configData.savedValue = storedCfg.savedValue;
-            configData.overrides = storedCfg.overrides;
-            configData.filename = storedCfg.filename;
-            configData.description = storedCfg.description;
-            configData.isFinal = storedCfg.isFinal;
-            configData.supportsFinal = storedCfg.supportsFinal;
-            configData.showLabel = !!storedCfg.showLabel;
-            configData.displayName = storedCfg.displayName;
-          } else if (isAdvanced) {
-            advanced = advancedConfigs.filterProperty('filename', configData.filename).findProperty('name', configData.name);
-            this.setPropertyFromStack(configData, advanced);
+          configData = this.mergeStaticProperties(configData, preDefined, isAdvanced ? advanced : null);
+
+          if (configData.displayType === 'password') {
+            configData.value = stored ? stored.value : configData.recommendedValue || '';
+          } else if (configData.displayType == 'directory' || configData.displayType == 'directories') {
+            configData.value = configData.recommendedValue || configData.defaultDirectory || '';
           }
+
           mergedConfigs.push(configData);
-        }, this);
+        }
       }
     }, this);
     return mergedConfigs;
   },
 
-  /**
-   *
-   * @param configData {Object} Configs that will be bound to the view on step-7 of installer wizard
-   * @param advanced {Object} Config property loaded from Server side stack definition
-   */
-  setPropertyFromStack: function (configData, advanced) {
-
-    // Password fields should be made blank by default in installer wizard
-    // irrespective of whatever value is sent from stack definition.
-    // This forces the user to fill the password field.
-    if (configData.displayType == 'password') {
-      configData.value = '';
-    } else {
-      configData.value = advanced ? advanced.value : configData.value;
-    }
-    configData.recommendedValue = configData.value;
-    configData.filename = advanced ? advanced.filename : configData.filename;
-    configData.displayName = advanced && advanced.displayName ? advanced.displayName : configData.displayName;
-    configData.name = advanced && advanced.name ? advanced.name : configData.name;
-    configData.description = advanced ? advanced.description : configData.description;
-    configData.isFinal = !!(advanced && (advanced.isFinal === "true"));
-    configData.supportsFinal = !!(advanced && advanced.supportsFinal);
-  },
-
-  /**
-   * look over advanced configs and add missing configs to serviceConfigs
-   * filter fetched configs by service if passed
-   * @param serviceConfigs
-   * @param advancedConfigs
-   * @param serviceName
-   */
-  addAdvancedConfigs: function (serviceConfigs, advancedConfigs, serviceName) {
-    var miscConfigs = serviceConfigs.filterProperty('serviceName', 'MISC');
-    var configsToVerifying = (serviceName) ? serviceConfigs.filterProperty('serviceName', serviceName).concat(miscConfigs) : serviceConfigs.slice();
-    var definedService = this.get('preDefinedServiceConfigs').findProperty('serviceName', serviceName);
-    if (definedService) {
-      var definedConfigs = (serviceName) ? definedService.get('configs') : [];
-
-      if (definedConfigs.length) {
-        advancedConfigs = advancedConfigs.filter(function (property) {
-          return !(definedConfigs.someProperty('name', property.name) && !serviceConfigs.someProperty('name', property.name));
-        }, this);
-      }
-    }
-    if (advancedConfigs) {
-      advancedConfigs.forEach(function (_config) {
-        var configType = this.getConfigTagFromFileName(_config.filename);
-        var configCategory = _config.category || 'Advanced ' + configType;
-        var categoryMetaData = null;
-        if (_config) {
-          if (!(this.get('configMapping').computed().someProperty('name', _config.name) ||
-            configsToVerifying.filterProperty('name', _config.name).someProperty('filename', _config.filename))) {
-            if (this.get('customFileNames').contains(_config.filename)) {
-              categoryMetaData = this.identifyCategory(_config);
-              if (categoryMetaData != null) {
-                configCategory = categoryMetaData.get('name');
-              }
-            }
-            _config.id = "site property";
-            _config.category = configCategory;
-            _config.displayName = _config.displayName || _config.name;
-            _config.recommendedValue = _config.value;
-            // make all advanced configs optional and populated by default
-            /*
-             * if (/\${.*}/.test(_config.value) || (service.serviceName !==
-             * 'OOZIE' && service.serviceName !== 'HBASE')) { _config.isRequired =
-             * false; _config.value = ''; } else if
-             * (/^\s+$/.test(_config.value)) { _config.isRequired = false; }
-             */
-            _config.isRequired = true;
-            _config.displayType = _config.displayType ? _config.displayType : stringUtils.isSingleLine(_config.value) ? 'advanced' : 'multiLine';
-            serviceConfigs.push(_config);
-          }
-        }
-      }, this);
-    }
-  },
-
   miscConfigVisibleProperty: function (configs, serviceToShow) {
     configs.forEach(function (item) {
       if (item.get('isVisible') && item.belongsToService && item.belongsToService.length) {
@@ -891,204 +818,6 @@ App.config = Em.Object.create({
   },
 
   /**
-   * Fetch cluster configs from server
-   *
-   * @param callback
-   * @return {$.ajax}
-   */
-  loadClusterConfig: function (callback) {
-    return App.ajax.send({
-      name: 'config.cluster',
-      sender: this,
-      data: {
-        stackVersionUrl: App.get('stackVersionURL'),
-        callback: callback
-      },
-      success: 'loadClusterConfigSuccess',
-      error: 'loadClusterConfigError'
-    });
-  },
-
-  loadClusterConfigSuccess: function (data, opt, params) {
-    console.log("TRACE: In success function for the loadClusterConfigSuccess; url is ", opt.url);
-    var properties = [];
-    if (data.items.length) {
-      data.items.forEach(function (item) {
-        item.StackLevelConfigurations.property_type = item.StackLevelConfigurations.property_type || [];
-        item.StackLevelConfigurations.service_name = 'MISC';
-        var property = this.createAdvancedPropertyObject(item.StackLevelConfigurations);
-        if (property) properties.push(property);
-      }, this);
-    }
-    params.callback(properties);
-  },
-
-  loadClusterConfigError: function (request, ajaxOptions, error, opt, params) {
-    console.log('ERROR: Failed to load cluster-env configs');
-    params.callback([]);
-  },
-
-
-  /**
-   * Generate serviceProperties save it to localDB
-   * called from stepController step6WizardController
-   *
-   * @method loadAdvancedConfig
-   * @param serviceName
-   * @param callback
-   * @return {object|null}
-   */
-  loadAdvancedConfig: function (serviceName, callback) {
-    return App.ajax.send({
-      name: 'config.advanced',
-      sender: this,
-      data: {
-        serviceName: serviceName,
-        stackVersionUrl: App.get('stackVersionURL'),
-        stackVersion: App.get('currentStackVersionNumber'),
-        callback: callback
-      },
-      success: 'loadAdvancedConfigSuccess',
-      error: 'loadAdvancedConfigError'
-    });
-  },
-
-  /**
-   * Generate serviceProperties save it to localDB
-   * called from stepController step6WizardController
-   *
-   * @method loadAdvancedConfig
-   * @param {Array} serviceNames
-   * @param callback
-   * @return {object|null}
-   */
-  loadAdvancedConfigAll: function (serviceNames, callback) {
-    return App.ajax.send({
-      name: 'config.advanced.multiple.services',
-      sender: this,
-      data: {
-        serviceNames: serviceNames.join(','),
-        stackVersionUrl: App.get('stackVersionURL'),
-        stackVersion: App.get('currentStackVersionNumber'),
-        callback: callback
-      },
-      success: 'loadAdvancedConfigAllSuccess',
-      error: 'loadAdvancedConfigAllError'
-    });
-  },
-
-  loadAdvancedConfigAllSuccess: function (data, opt, params, request) {
-    console.log("TRACE: In success function for the loadAdvancedConfig; url is ", opt.url);
-    var serviceConfigMap = {};
-    if (data.items.length) {
-      data.items.forEach(function (service) {
-        var properties = [];
-        service.configurations.forEach(function(item){
-          properties.push(this.createAdvancedPropertyObject(item.StackConfigurations));
-        }, this);
-        serviceConfigMap[service.StackServices.service_name] = properties;
-      }, this);
-    }
-    params.callback(serviceConfigMap, request);
-  },
-
-  loadAdvancedConfigAllError: function (request, ajaxOptions, error, opt, params) {
-    console.log('ERROR: failed to load stack configs for', params.serviceNames);
-    params.callback([], request);
-  },
-
-  /**
-   * Load advanced configs by service names etc.
-   * Use this method when you need to get configs for
-   * particular services by single request
-   *
-   * @method loadAdvancedConfigPartial
-   * @param {String[]} serviceNames
-   * @param {Object} opt
-   * @param {Function} callback
-   * @returns {$.ajax}
-   */
-  loadAdvancedConfigPartial: function (serviceNames, opt, callback) {
-    var data = {
-      serviceList: serviceNames.join(','),
-      stackVersionUrl: App.get('stackVersionURL'),
-      stackVersion: App.get('currentStackVersionNumber'),
-      queryFilter: ('&' + opt.queryFilter) || '',
-      callback: callback
-    };
-    return App.ajax.send({
-      name: 'config.advanced.partial',
-      sender: this,
-      data: data,
-      success: 'loadAdvancedConfigPartialSuccess',
-      error: 'loadAdvancedConfigError'
-    });
-  },
-
-  loadAdvancedConfigSuccess: function (data, opt, params, request) {
-    console.log("TRACE: In success function for the loadAdvancedConfig; url is ", opt.url);
-    var properties = [];
-    if (data.items.length) {
-      data.items.forEach(function (item) {
-        var property = this.createAdvancedPropertyObject(item.StackConfigurations);
-        if (property) properties.push(property);
-      }, this);
-    }
-    params.callback(properties, request);
-  },
-
-  loadAdvancedConfigError: function (request, ajaxOptions, error, opt, params) {
-    console.log('ERROR: failed to load stack configs for', params.serviceName);
-    params.callback([], request);
-  },
-
-  loadAdvancedConfigPartialSuccess: function (data, opt, params, request) {
-    var properties = [];
-    if (data.items.length && data.items.mapProperty('configurations').length) {
-      var configurations = data.items.mapProperty('configurations').reduce(function (p, c) {
-        return p.concat(c);
-      });
-      configurations.forEach(function (item) {
-        var property = this.createAdvancedPropertyObject(item.StackConfigurations);
-        if (property) properties.push(property);
-      }, this);
-    }
-    params.callback(properties, request);
-  },
-
-  /**
-   * Bootstrap configuration property object according to
-   * format that we using in our application.
-   *
-   * @method createAdvancedPropertyObject
-   * @param {Object} item
-   * @returns {Object|Boolean}
-   */
-  createAdvancedPropertyObject: function (item) {
-    var serviceName = item.service_name;
-    var fileName = item.type;
-    /**
-     * Properties from mapred-queue-acls.xml are ignored
-     * Properties from capacity-scheduler.xml are ignored unless HDP stack version is 2.x or
-     * HDP stack version is 1.x
-     */
-    if (fileName == 'mapred-queue-acls.xml') return false;
-    item.isVisible = fileName != 'cluster-env.xml';
-    var property = {
-      serviceName: serviceName,
-      name: item.property_name,
-      value: item.property_value,
-      description: item.property_description,
-      isVisible: item.isVisible,
-      isFinal: item.final === "true",
-      recommendedIsFinal: item.final === "true",
-      filename: item.filename || fileName
-    };
-
-    return $.extend(property, this.advancedConfigIdentityData(item));
-  },
-
-  /**
    * Add additional properties to advanced property config object.
    * Additional logic based on `property_type`.
    *
@@ -1119,7 +848,9 @@ App.config = Em.Object.create({
         propertyData.isReconfigurable = false;
         propertyData.displayName = nameToDisplayNameMap[config.property_name] || App.format.normalizeName(config.property_name);
         propertyData.displayType = checkboxProperties.contains(config.property_name) ? 'checkbox' : 'user';
-        if (config.service_name && !config.property_type.contains('ADDITIONAL_USER_PROPERTY')) {
+        if (config.property_type.contains('ADDITIONAL_USER_PROPERTY')) {
+          propertyData.index = 999;
+        } else if (config.service_name) {
           var propertyIndex = config.service_name == 'MISC' ? 30 : App.StackService.find().mapProperty('serviceName').indexOf(config.service_name);
           propertyData.belongsToService = [config.service_name];
           propertyData.index = propertyIndex;
@@ -1441,11 +1172,6 @@ App.config = Em.Object.create({
     return configData;
   },
 
-  getOriginalConfigAttribute: function (stored, key, advancedConfigs) {
-    return advancedConfigs.findProperty('name', stored.name) ?
-      advancedConfigs.findProperty('name', stored.name)[key] : stored[key];
-  },
-
   complexConfigsTemplate: [
     {
       "id": "site property",
@@ -1656,6 +1382,22 @@ App.config = Em.Object.create({
   },
 
   /**
+   * load cluster stack configs from server and run mapper
+   * @returns {$.ajax}
+   * @method loadConfigsFromStack
+   */
+  loadClusterConfigsFromStack: function () {
+    return App.ajax.send({
+      name: 'configs.stack_configs.load.cluster_configs',
+      sender: this,
+      data: {
+        stackVersionUrl: App.get('stackVersionURL')
+      },
+      success: 'saveConfigsToModel'
+    });
+  },
+
+  /**
    * load stack configs from server and run mapper
    * @param {String[]} [serviceNames=null]
    * @returns {$.ajax}

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/views/common/configs/services_config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/services_config.js b/ambari-web/app/views/common/configs/services_config.js
index 77ccff8..1b5a930 100644
--- a/ambari-web/app/views/common/configs/services_config.js
+++ b/ambari-web/app/views/common/configs/services_config.js
@@ -23,7 +23,9 @@ App.ServicesConfigView = Em.View.extend({
   templateName: require('templates/common/configs/services_config'),
 
   didInsertElement: function () {
-    this.get('controller').loadStep();
+    Em.run.next(this, function() {
+      this.get('controller') && this.get('controller').loadStep();
+    });
   }
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/app/views/common/controls_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/controls_view.js b/ambari-web/app/views/common/controls_view.js
index 178086d..19d846e 100644
--- a/ambari-web/app/views/common/controls_view.js
+++ b/ambari-web/app/views/common/controls_view.js
@@ -94,7 +94,7 @@ App.SupportsDependentConfigs = Ember.Mixin.create({
       var saveRecommended = (this.get('config.value') === this.get('config.recommendedValue'));
       var controller = this.get('controller');
       var type = App.config.getConfigTagFromFileName(config.get('filename'));
-      var p = App.StackConfigProperty.find(name + '_' + type);
+      var p = App.StackConfigProperty.find(App.config.configId(name, type));
       if (p && p.get('propertyDependedBy.length') > 0) {
         return controller.getRecommendationsForDependencies([{
           "type": type,

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/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 2cd2b35..66f6113 100644
--- a/ambari-web/test/controllers/main/service/info/config_test.js
+++ b/ambari-web/test/controllers/main/service/info/config_test.js
@@ -825,7 +825,20 @@ describe("App.MainServiceInfoConfigsController", function () {
   });
 
   describe('#setHiveHostName', function () {
+    beforeEach(function () {
+      sinon.stub(App.StackService, 'find').returns([
+        {
+          serviceName: 'HIVE'
+        },
+        {
+          serviceName: 'OOZIE'
+        }
+      ]);
+    });
 
+    afterEach(function () {
+      App.StackService.find.restore();
+    });
     Em.A([
         {
           globals: [
@@ -922,7 +935,20 @@ describe("App.MainServiceInfoConfigsController", function () {
   });
 
   describe('#setOozieHostName', function () {
+    beforeEach(function () {
+      sinon.stub(App.StackService, 'find').returns([
+        {
+          serviceName: 'HIVE'
+        },
+        {
+          serviceName: 'OOZIE'
+        }
+      ]);
+    });
 
+    afterEach(function () {
+      App.StackService.find.restore();
+    });
     Em.A([
         {
           globals: [

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/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 ed76e82..e3d55a8 100644
--- a/ambari-web/test/controllers/wizard/step7_test.js
+++ b/ambari-web/test/controllers/wizard/step7_test.js
@@ -1386,11 +1386,11 @@ describe('App.InstallerStep7Controller', function () {
         wizardController: Em.Object.create({
           getDBProperty: function (k) {
             return this.get(k);
-          }
+          },
+          stackConfigsLoaded: true
         })
       });
       sinon.stub(App.config, 'mergePreDefinedWithStored', Em.K);
-      sinon.stub(App.config, 'addAdvancedConfigs', Em.K);
       sinon.stub(App.config, 'fileConfigsIntoTextarea', Em.K);
       sinon.stub(installerStep7Controller, 'clearStep', Em.K);
       sinon.stub(installerStep7Controller, 'getConfigTags', Em.K);
@@ -1405,7 +1405,6 @@ describe('App.InstallerStep7Controller', function () {
     });
     afterEach(function () {
       App.config.mergePreDefinedWithStored.restore();
-      App.config.addAdvancedConfigs.restore();
       App.config.fileConfigsIntoTextarea.restore();
       installerStep7Controller.clearStep.restore();
       installerStep7Controller.getConfigTags.restore();
@@ -1423,14 +1422,13 @@ describe('App.InstallerStep7Controller', function () {
       expect(installerStep7Controller.clearStep.calledOnce).to.equal(true);
     });
     it('shouldn\'t do nothing if isAdvancedConfigLoaded is false', function () {
-      installerStep7Controller.set('isAdvancedConfigLoaded', false);
+      installerStep7Controller.set('wizardController.stackConfigsLoaded', false);
       installerStep7Controller.loadStep();
       expect(installerStep7Controller.clearStep.called).to.equal(false);
     });
     it('should use App.config to map configs', function () {
       installerStep7Controller.loadStep();
       expect(App.config.mergePreDefinedWithStored.calledOnce).to.equal(true);
-      expect(App.config.addAdvancedConfigs.calledOnce).to.equal(true);
     });
     it('should call setInstalledServiceConfigs for addServiceController', function () {
       installerStep7Controller.set('wizardController.name', 'addServiceController');

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/test/controllers/wizard_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard_test.js b/ambari-web/test/controllers/wizard_test.js
index b00e5ba..3d938e3 100644
--- a/ambari-web/test/controllers/wizard_test.js
+++ b/ambari-web/test/controllers/wizard_test.js
@@ -92,49 +92,6 @@ describe('App.WizardController', function () {
     });
   });
 
-  describe('#loadAdvancedConfigs', function() {
-    beforeEach(function () {
-      sinon.stub(App.config, 'loadClusterConfig', function(callback){
-        callback();
-      });
-      sinon.stub(App.config, 'loadAdvancedConfigAll', function(val,callback) {
-        var properties = {
-          "s1" : [
-            {
-              supportsFinal: '',
-              filename: 'name'
-            }
-          ]
-        };
-        callback(properties);
-      });
-    });
-    afterEach(function () {
-      App.config.loadClusterConfig.restore();
-      App.config.loadAdvancedConfigAll.restore();
-    });
-    it('Should load configs', function() {
-      var data = Em.Object.create({
-        isAdvancedConfigLoaded: true
-      });
-      var services = Em.A([
-        Em.Object.create({
-          isInstalled: true,
-          serviceName: 's1'
-        })
-      ]);
-      wizardController.set('content.services', services);
-      wizardController.loadAdvancedConfigs(data);
-      var res = JSON.parse(JSON.stringify(wizardController.get('content.advancedServiceConfig')));
-      expect(res).to.be.eql([
-        {
-          "supportsFinal": false,
-          "filename": "name"
-        }
-      ]);
-    });
-  });
-
   describe('#launchBootstrapSuccessCallback', function() {
     it('Save bootstrapRequestId', function() {
       var data = {requestId: 123};

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/test/mappers/configs/stack_config_properties_mapper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mappers/configs/stack_config_properties_mapper_test.js b/ambari-web/test/mappers/configs/stack_config_properties_mapper_test.js
index fbe5a9b..24380c6 100644
--- a/ambari-web/test/mappers/configs/stack_config_properties_mapper_test.js
+++ b/ambari-web/test/mappers/configs/stack_config_properties_mapper_test.js
@@ -69,7 +69,7 @@ describe('App.stackConfigPropertiesMapper', function () {
               {
                 "StackConfigurationDependency" : {
                   "dependency_name" : "p4",
-                  "dependency_type" : "site4",
+                  "dependency_type" : "site4"
                 }
               }
             ]
@@ -175,37 +175,37 @@ describe('App.stackConfigPropertiesMapper', function () {
     it('should load data to model', function() {
       App.stackConfigPropertiesMapper.map(json);
       expect(App.StackConfigProperty.find().get('length')).to.equal(5);
-      expect(App.StackConfigProperty.find().mapProperty('id')).to.eql(['p1_site1','p2_site2','p3_site3', 'p4_site3', 'p5_site3']);
+      expect(App.StackConfigProperty.find().mapProperty('id')).to.eql(['p1__site1','p2__site2','p3__site3', 'p4__site3', 'p5__site3']);
 
-      expect(App.StackConfigProperty.find('p1_site1').get('name')).to.eql('p1');
-      expect(App.StackConfigProperty.find('p1_site1').get('displayName')).to.eql('P1');
-      expect(App.StackConfigProperty.find('p1_site1').get('description')).to.eql('desc1');
-      expect(App.StackConfigProperty.find('p1_site1').get('recommendedValue')).to.eql('v1');
-      expect(App.StackConfigProperty.find('p1_site1').get('recommendedIsFinal')).to.be.false;
-      expect(App.StackConfigProperty.find('p1_site1').get('serviceName')).to.eql('s1');
-      expect(App.StackConfigProperty.find('p1_site1').get('stackName')).to.eql('HDP');
-      expect(App.StackConfigProperty.find('p1_site1').get('stackVersion')).to.eql('2.2');
-      expect(App.StackConfigProperty.find('p1_site1').get('type').toArray()).to.eql([]);
-      expect(App.StackConfigProperty.find('p1_site1').get('fileName')).to.eql('site1.xml');
-      expect(App.StackConfigProperty.find('p1_site1').get('propertyDependedBy')).to.eql([
+      expect(App.StackConfigProperty.find('p1__site1').get('name')).to.eql('p1');
+      expect(App.StackConfigProperty.find('p1__site1').get('displayName')).to.eql('P1');
+      expect(App.StackConfigProperty.find('p1__site1').get('description')).to.eql('desc1');
+      expect(App.StackConfigProperty.find('p1__site1').get('recommendedValue')).to.eql('v1');
+      expect(App.StackConfigProperty.find('p1__site1').get('recommendedIsFinal')).to.be.false;
+      expect(App.StackConfigProperty.find('p1__site1').get('serviceName')).to.eql('s1');
+      expect(App.StackConfigProperty.find('p1__site1').get('stackName')).to.eql('HDP');
+      expect(App.StackConfigProperty.find('p1__site1').get('stackVersion')).to.eql('2.2');
+      expect(App.StackConfigProperty.find('p1__site1').get('type').toArray()).to.eql([]);
+      expect(App.StackConfigProperty.find('p1__site1').get('fileName')).to.eql('site1.xml');
+      expect(App.StackConfigProperty.find('p1__site1').get('propertyDependedBy')).to.eql([
         {
           "type": "site4",
           "name": "p4"
         }
       ]);
-      expect(App.StackConfigProperty.find('p1_site1').get('propertyDependsOn')).to.eql([
+      expect(App.StackConfigProperty.find('p1__site1').get('propertyDependsOn')).to.eql([
         {
           "type": "site5",
           "name": "p5"
         }
       ]);
-      expect(App.StackConfigProperty.find('p1_site1').get('valueAttributes')).to.eql({
+      expect(App.StackConfigProperty.find('p1__site1').get('valueAttributes')).to.eql({
         "type": "int",
         "minimum": "512",
         "maximum": "10240",
         "unit": "MB"
       });
-      expect(App.StackConfigProperty.find('p1_site1').get('supportsFinal')).to.be.true;
+      expect(App.StackConfigProperty.find('p1__site1').get('supportsFinal')).to.be.true;
     });
 
     it('should set "displayType" by "property_type" attribute', function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/4f78030c/ambari-web/test/mappers/configs/themes_mapper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mappers/configs/themes_mapper_test.js b/ambari-web/test/mappers/configs/themes_mapper_test.js
index 63b937c..7e6d35f 100644
--- a/ambari-web/test/mappers/configs/themes_mapper_test.js
+++ b/ambari-web/test/mappers/configs/themes_mapper_test.js
@@ -143,8 +143,8 @@ describe('App.themeMapper', function () {
 
     it('should map theme data', function () {
 
-      App.StackConfigProperty.createRecord({id: 'p1_c1'});
-      App.StackConfigProperty.createRecord({id: 'p2_c1'});
+      App.StackConfigProperty.createRecord({id: 'p1__c1'});
+      App.StackConfigProperty.createRecord({id: 'p2__c1'});
 
       App.themesMapper.map(json);
 
@@ -194,7 +194,7 @@ describe('App.themeMapper', function () {
 
       //checking stack config object
       var config = App.Tab.find('HDFS_settings').get('sections').objectAt(0).get('subSections').objectAt(0).get('configProperties').objectAt(0);
-      expect(config.get('id')).to.eql("p1_c1");
+      expect(config.get('id')).to.eql("p1__c1");
       expect(config.get('subSection.id')).to.eql("subsection1");
       expect(config.get('widget')).to.eql({
         "type": "slider",
@@ -229,7 +229,7 @@ describe('App.themeMapper', function () {
 
   describe('#getConfigId', function () {
     it('gets configs id from json', function () {
-      expect(App.themesMapper.getConfigId({config: "c1/p1"})).to.equal("p1_c1");
+      expect(App.themesMapper.getConfigId({config: "c1/p1"})).to.equal("p1__c1");
     });
     it('returns null as data is invalid', function () {
       expect(App.themesMapper.getConfigId({configs: "c1/p1"})).to.equal(null);


Mime
View raw message