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/23 17:02:18 UTC

ambari git commit: AMBARI-15142 Small refactor for configs. (ababiichuk)

Repository: ambari
Updated Branches:
  refs/heads/trunk 9310ab70c -> ea6a7a614


AMBARI-15142 Small refactor for configs. (ababiichuk)


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

Branch: refs/heads/trunk
Commit: ea6a7a614190917abaa22dbec5895cb9b66b13b4
Parents: 9310ab7
Author: ababiichuk <ab...@hortonworks.com>
Authored: Tue Feb 23 17:02:00 2016 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Tue Feb 23 17:02:00 2016 +0200

----------------------------------------------------------------------
 .../resourceManager/step3_controller.js         |   2 +-
 .../main/admin/kerberos/step4_controller.js     |   3 +-
 .../main/admin/serviceAccounts_controller.js    |   5 +-
 .../controllers/main/service/info/configs.js    |  32 +++-
 ambari-web/app/controllers/wizard.js            |   1 -
 .../app/controllers/wizard/step7_controller.js  |  66 +------
 .../configs/stack_config_properties_mapper.js   |   4 +-
 .../common/kdc_credentials_controller_mixin.js  |   2 +-
 ambari-web/app/models/stack_service.js          |  15 +-
 ambari-web/app/utils.js                         |   1 +
 ambari-web/app/utils/config.js                  | 187 ++++++-------------
 ambari-web/app/utils/configs/theme/theme.js     | 103 ++++++++++
 .../configs/widgets/config_widget_view.js       |   2 +-
 .../admin/kerberos/step4_controller_test.js     |   9 +-
 .../test/controllers/wizard/step7_test.js       |   7 +-
 ambari-web/test/utils/config_test.js            | 126 +------------
 16 files changed, 227 insertions(+), 338 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js
index d2b7a86..0ec632b 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js
@@ -142,7 +142,7 @@ App.RMHighAvailabilityWizardStep3Controller = Em.Controller.extend({
     var dependencies = this._prepareDependencies(data);
     /** add dynamic property 'hadoop.proxyuser.' + yarnUser + '.hosts' **/
     var proxyUserConfig = App.ServiceConfigProperty.create(App.config.createDefaultConfig('hadoop.proxyuser.' + yarnUser + '.hosts',
-      'MISC', 'core-site', false,  {category : "HDFS", isUserProperty: false, isEditable: false, isOverridable: false}));
+      'core-site', false,  {category : "HDFS", isUserProperty: false, isEditable: false, isOverridable: false, serviceName: 'MISC'}));
     configs.configs.pushObject(proxyUserConfig);
 
     configs.configs.forEach(function (config) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
index e83fe80..1eb52f1 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
@@ -290,6 +290,7 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
     var credentialProperties = this.get('adminPropertyNames').map(function(prop, index) {
       var existingProperty = krbProperties.findProperty('name', prop.name);
       var coreObject = {
+        serviceName: 'Cluster',
         displayName: prop.displayName,
         isRequired: false,
         isRequiredByAgent: false,
@@ -301,7 +302,7 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
         isVisible: true,
         isUserProperty: false
       };
-      var propTpl = App.config.createDefaultConfig(prop.name, 'Cluster', fileName, false, coreObject);
+      var propTpl = App.config.createDefaultConfig(prop.name, fileName, false, coreObject);
       var siteProperty = siteProperties.filterProperty('filename', fileName).findProperty('name', prop.name);
       if (!Em.isNone(siteProperty)) {
         propTpl = $.extend(true, {}, siteProperty, propTpl);

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/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 45cfbcf..5b98bf3 100644
--- a/ambari-web/app/controllers/main/admin/serviceAccounts_controller.js
+++ b/ambari-web/app/controllers/main/admin/serviceAccounts_controller.js
@@ -103,7 +103,10 @@ App.MainAdminServiceAccountsController = App.MainServiceInfoConfigsController.ex
    * @param {Object[]} serverConfigs
    */
   createConfigObject: function(serverConfigs) {
-    var configs = App.config.mergePredefinedWithSaved(serverConfigs, this.get('selectedService'));
+    var configs = [];
+    serverConfigs.forEach(function(configObject) {
+      configs = configs.concat(App.config.getConfigsFromJSON(configObject, true));
+    });
     var miscConfigs = configs.filterProperty('displayType', 'user').filterProperty('category', 'Users and Groups');
     miscConfigs.setEach('isVisible', true);
     this.set('users', miscConfigs);

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/ambari-web/app/controllers/main/service/info/configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/configs.js b/ambari-web/app/controllers/main/service/info/configs.js
index 3cd652a..a22bb48 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -343,15 +343,15 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
   prepareConfigObjects: function(data, serviceName) {
     this.get('stepConfigs').clear();
 
-    var configGroups = [];
-    data.items.forEach(function (v) {
-      if (v.group_name == 'default') {
-        v.configurations.forEach(function (c) {
-          configGroups.pushObject(c);
+    var configs = [];
+    data.items.forEach(function (version) {
+      if (version.group_name == 'default') {
+        version.configurations.forEach(function (configObject) {
+          configs = configs.concat(App.config.getConfigsFromJSON(configObject, true));
         });
       }
     });
-    var configs = App.config.mergePredefinedWithSaved(configGroups, serviceName, this.get('selectedConfigGroup'), this.get('canEdit'));
+
     configs = App.config.sortConfigs(configs);
     /**
      * if property defined in stack but somehow it missed from cluster properties (can be after stack upgrade)
@@ -367,19 +367,33 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
     if (this.get('content.serviceName') === 'KERBEROS') {
       var kdc_type = configs.findProperty('name', 'kdc_type');
       if (kdc_type.get('value') === 'none') {
-        configs.findProperty('name', 'kdc_host').set('isRequired', false).set('isVisible', false);
-        configs.findProperty('name', 'admin_server_host').set('isRequired', false).set('isVisible', false);
-        configs.findProperty('name', 'domains').set('isRequired', false).set('isVisible', false);
+        configs.findProperty('name', 'kdc_host').set('isVisible', false);
+        configs.findProperty('name', 'admin_server_host').set('isVisible', false);
+        configs.findProperty('name', 'domains').set('isVisible', false);
       } else if (kdc_type.get('value') === 'active-directory') {
         configs.findProperty('name', 'container_dn').set('isVisible', true);
         configs.findProperty('name', 'ldap_url').set('isVisible', true);
       }
     }
 
+    this.setPropertyIsEditable(configs);
     this.set('allConfigs', configs);
   },
 
   /**
+   * Set <code>isEditable<code> proeperty based on selected group, security
+   * and controller restriction
+   * @param configs
+   */
+  setPropertyIsEditable: function(configs) {
+    if (!this.get('selectedConfigGroup.isDefault') || !this.get('canEdit')) {
+      configs.setEach('isEditable', false);
+    } else if (App.get('isKerberosEnabled')) {
+      configs.filterProperty('isSecureConfig').setEach('isEditable', false);
+    }
+  },
+
+  /**
    * adds properties form stack that doesn't belong to cluster
    * to step configs
    * also set recommended value if isn't exists

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index 329d246..654bea5 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -895,7 +895,6 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
         }
         var configProperty = App.config.createDefaultConfig(
           _configProperties.get('name'),
-          _configProperties.get('serviceName'),
           _configProperties.get('filename'),
           _configProperties.get('isUserProperty'),
           {value: _configProperties.get('value')}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/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 0b29fe5..fc6b5ab 100644
--- a/ambari-web/app/controllers/wizard/step7_controller.js
+++ b/ambari-web/app/controllers/wizard/step7_controller.js
@@ -652,49 +652,6 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
   },
 
   /**
-   * Resolve config theme conditions
-   * in order to correctly calculate config errors number of service
-   * @param {Array} configs
-   */
-  resolveConfigThemeConditions: function (configs) {
-    App.ThemeCondition.find().forEach(function (configCondition) {
-      var _configs = Em.A(configCondition.get('configs'));
-      if (configCondition.get("resource") === 'config' && _configs.length > 0) {
-        var isConditionTrue = App.config.calculateConfigCondition(configCondition.get("if"), configs);
-        var action = isConditionTrue ? configCondition.get("then") : configCondition.get("else");
-        if (configCondition.get('id')) {
-          var valueAttributes = action.property_value_attributes;
-          if (valueAttributes && !Em.none(valueAttributes['visible'])) {
-            var themeResource;
-            if (configCondition.get('type') === 'subsection') {
-              themeResource = App.SubSection.find().findProperty('name', configCondition.get('name'));
-            } else if (configCondition.get('type') === 'subsectionTab') {
-              themeResource = App.SubSectionTab.find().findProperty('name', configCondition.get('name'));
-            } else if (configCondition.get('type') === 'config') {
-              //simulate section wrapper for condition type "config"
-              themeResource = Em.Object.create({
-                configProperties: [App.config.configId(configCondition.get('configName'), configCondition.get('fileName'))]
-              });
-            }
-            if (themeResource) {
-              themeResource.get('configProperties').forEach(function (_configId) {
-                configs.forEach(function (item) {
-                  if (App.config.configId(item.name, item.filename) === _configId) {
-                    // if config has already been hidden by condition with "subsection" or "subsectionTab" type
-                    // then ignore condition of "config" type
-                    if (configCondition.get('type') === 'config' && item.hiddenBySection) return false;
-                    item.hiddenBySection = !valueAttributes['visible'];
-                  }
-                });
-              }, this);
-            }
-          }
-        }
-      }
-    });
-  },
-
-  /**
    * Update hawq configuration depending on the state of the cluster
    * @param {Array} configs
    */
@@ -724,7 +681,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
     if (App.get('isKerberosEnabled') && this.get('wizardController.name') == 'addServiceController') {
       this.addKerberosDescriptorConfigs(configs, this.get('wizardController.kerberosDescriptorConfigs') || []);
     }
-    this.resolveConfigThemeConditions(configs);
+    App.configTheme.resolveConfigThemeConditions(configs);
     var stepConfigs = this.createStepConfigs();
     var serviceConfigs = this.renderConfigs(stepConfigs, configs);
     // if HA is enabled -> Make some reconfigurations
@@ -845,16 +802,16 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
     ];
 
     propertyNames.forEach(function(propertyName, propertyIndex) {
-      var propertyFromHdfs = configs.findProperty('id', propertyName + '__hdfs-site');
-      var newProperty = App.config.createDefaultConfig(propertyName, 'HAWQ', 'hdfs-client.xml', true);
+      var propertyFromHdfs = configs.findProperty('id', App.config.configId(propertyName, 'hdfs-site'));
+      var newProperty = App.config.createDefaultConfig(propertyName, 'hdfs-client.xml', true);
       Em.setProperties(newProperty, {
+        serviceName: 'HAWQ',
         description: propertyFromHdfs.description,
         displayName: propertyFromHdfs.displayName,
         displayType: 'string',
         index: propertyIndex,
         isOverridable: false,
         isReconfigurable: false,
-        name: propertyFromHdfs.name,
         value: propertyFromHdfs.value,
         recommendedValue: propertyFromHdfs.recommendedValue
       });
@@ -871,8 +828,8 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
    * @returns {Object[]} existing configs + additional config parameters in yarn-client.xml
    */
   addHawqConfigsOnRMHa: function(configs) {
-    var rmHost1 = configs.findProperty('id', 'yarn.resourcemanager.hostname.rm1__yarn-site').value ;
-    var rmHost2 = configs.findProperty('id', 'yarn.resourcemanager.hostname.rm2__yarn-site').value ;
+    var rmHost1 = configs.findProperty('id', App.config.configId('yarn.resourcemanager.hostname.rm1', 'yarn-site')).value ;
+    var rmHost2 = configs.findProperty('id', App.config.configId('yarn.resourcemanager.hostname.rm2', 'yarn-site')).value ;
     var yarnConfigToBeAdded = [
       {
         name: 'yarn.resourcemanager.ha',
@@ -889,10 +846,10 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
     ];
 
     yarnConfigToBeAdded.forEach(function(propertyDetails) {
-      var newProperty = App.config.createDefaultConfig(propertyDetails.name, 'HAWQ', 'yarn-client.xml', true);
+      var newProperty = App.config.createDefaultConfig(propertyDetails.name, 'yarn-client.xml', true);
       var value = rmHost1 + ':' + propertyDetails.port + ',' + rmHost2 + ':' + propertyDetails.port;
       Em.setProperties(newProperty, {
-        name: propertyDetails.name,
+        serviceName: 'HAWQ',
         description: propertyDetails.description,
         displayName: propertyDetails.displayName,
         isOverridable: false,
@@ -1143,10 +1100,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
     //add user properties
     Em.keys(configsMap).forEach(function (filename) {
       Em.keys(configsMap[filename]).forEach(function (propertyName) {
-        allConfigs.push(App.config.createDefaultConfig(propertyName,
-          App.config.getServiceByConfigType(filename) ? App.config.getServiceByConfigType(filename).get('serviceName') : 'MISC',
-          App.config.getOriginalFileName(filename),
-          false, {
+        allConfigs.push(App.config.createDefaultConfig(propertyName, App.config.getOriginalFileName(filename), false, {
             value: configsMap[filename][propertyName],
             savedValue: configsMap[filename][propertyName],
             hasInitialValue: true
@@ -1376,7 +1330,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
         return true;
       } else if (stackProperty.propertyDependsOn.length) {
         return !!stackProperty.propertyDependsOn.filter(function (p) {
-          var service = App.config.getServiceByConfigType(p.type);
+          var service = App.config.get('serviceByConfigTypeMap')[p.type];
           return service && !this.get('installedServices')[service.get('serviceName')];
         }, this).length;
       } else {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/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 2c7328e..32a45a5 100644
--- a/ambari-web/app/mappers/configs/stack_config_properties_mapper.js
+++ b/ambari-web/app/mappers/configs/stack_config_properties_mapper.js
@@ -114,7 +114,7 @@ App.stackConfigPropertiesMapper = App.QuickDataMapper.create({
                 name : dep.StackConfigurationDependency.dependency_name
               });
               var service = App.StackService.find(config.StackConfigurations.service_name);
-              var dependentService = App.config.getServiceByConfigType(dep.StackConfigurationDependency.dependency_type);
+              var dependentService = App.config.get('serviceByConfigTypeMap')[dep.StackConfigurationDependency.dependency_type];
               if (dependentService && service && dependentService.get('serviceName') != service.get('serviceName') && !service.get('dependentServiceNames').contains(dependentService.get('serviceName'))) {
                 service.set('dependentServiceNames', service.get('dependentServiceNames').concat(dependentService.get('serviceName')));
               }
@@ -123,7 +123,7 @@ App.stackConfigPropertiesMapper = App.QuickDataMapper.create({
           if (Em.get(config, 'StackConfigurations.property_depends_on.length') > 0) {
             config.StackConfigurations.property_depends_on.forEach(function(dep) {
               var service = App.StackService.find(config.StackConfigurations.service_name);
-              var dependentService = App.config.getServiceByConfigType(dep.type);
+              var dependentService = App.config.get('serviceByConfigTypeMap')[dep.type];
               if (dependentService && service && dependentService.get('serviceName') != service.get('serviceName') && !service.get('dependentServiceNames').contains(dependentService.get('serviceName'))) {
                 service.set('dependentServiceNames', service.get('dependentServiceNames').concat(dependentService.get('serviceName')));
               }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/ambari-web/app/mixins/common/kdc_credentials_controller_mixin.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/kdc_credentials_controller_mixin.js b/ambari-web/app/mixins/common/kdc_credentials_controller_mixin.js
index 45bc551..86ae83c 100644
--- a/ambari-web/app/mixins/common/kdc_credentials_controller_mixin.js
+++ b/ambari-web/app/mixins/common/kdc_credentials_controller_mixin.js
@@ -111,7 +111,7 @@ App.KDCCredentialsControllerMixin = Em.Mixin.create({
   initilizeKDCStoreProperties: function(configs) {
     var self = this;
     this.get('credentialsStoreConfigs').forEach(function(item) {
-      var configObject = App.config.createDefaultConfig(item.name, 'KERBEROS', 'krb5-conf.xml', false, false);
+      var configObject = App.config.createDefaultConfig(item.name, 'krb5-conf.xml', false);
       $.extend(configObject, item);
       if (item.name === 'persist_credentials') {
         if (self.get('isStorePersisted')) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/ambari-web/app/models/stack_service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/stack_service.js b/ambari-web/app/models/stack_service.js
index 281e0d8..14af448 100644
--- a/ambari-web/app/models/stack_service.js
+++ b/ambari-web/app/models/stack_service.js
@@ -48,8 +48,14 @@ App.StackService = DS.Model.extend({
    * @type {String[]}
    */
   configTypeList: function() {
-    return Object.keys(this.get('configTypes') || {});
+    var configTypes = Object.keys(this.get('configTypes') || {});
+    //Falcon has dependency on oozie-site but oozie-site advanced/custom section should not be shown on Falcon page
+    if (this.get('serviceName') === 'FALCON') {
+      configTypes = configTypes.without('oozie-site');
+    }
+    return configTypes;
   }.property('configTypes'),
+
   /**
    * contains array of serviceNames that have configs that
    * depends on configs from current service
@@ -367,12 +373,7 @@ App.StackService.configCategories = function () {
   }
   serviceConfigCategories.pushObject(App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}));
 
-  var configTypes = Object.keys(this.get('configTypes'));
-
-  //Falcon has dependency on oozie-site but oozie-site advanced/custom section should not be shown on Falcon page
-  if (this.get('serviceName') !== 'OOZIE') {
-    configTypes = configTypes.without('oozie-site');
-  }
+  var configTypes = this.get('configTypeList');
 
   // Add Advanced section for every configType to all the services
   configTypes.forEach(function (type) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/ambari-web/app/utils.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils.js b/ambari-web/app/utils.js
index 920aa55..1041a9c 100644
--- a/ambari-web/app/utils.js
+++ b/ambari-web/app/utils.js
@@ -24,6 +24,7 @@ require('utils/base64');
 require('utils/db');
 require('utils/helper');
 require('utils/config');
+require('utils/configs/theme/theme');
 require('utils/configs/config_initializer');
 require('utils/configs/nn_ha_config_initializer');
 require('utils/configs/rm_ha_config_initializer');

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index 40d4699..ca1855a 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -206,21 +206,10 @@ App.config = Em.Object.create({
     }
   },
 
-  /**
-   * get service for current config type
-   * @param {String} configType - config fileName without xml
-   * @return App.StackService
-   */
-  getServiceByConfigType: function(configType) {
-    return App.StackService.find().find(function(s) {
-      return s.get('configTypeList').contains(configType);
-    });
-  },
-
   serviceByConfigTypeMap: function () {
     var ret = {};
     App.StackService.find().forEach(function(s) {
-      Object.keys(s.get('configTypes')).forEach(function (ct) {
+      s.get('configTypeList').forEach(function (ct) {
         ret[ct] = s;
       });
     });
@@ -228,52 +217,37 @@ App.config = Em.Object.create({
   }.property(),
 
   /**
-   * generates config objects
-   * @param configGroups
-   * @param serviceName
-   * @param selectedConfigGroup
-   * @param canEdit
+   * Generate configs collection with Ember or plain config objects
+   * from config JSON
+   *
+   * @param configJSON
+   * @param useEmberObject
    * @returns {Array}
    */
-  mergePredefinedWithSaved: function (configGroups, serviceName, selectedConfigGroup, canEdit) {
-    var configs = [];
-
-    configGroups.forEach(function (siteConfig) {
-      var filename = App.config.getOriginalFileName(siteConfig.type);
-      var attributes = siteConfig['properties_attributes'] || {};
-      var finalAttributes = attributes.final || {};
-      var properties = siteConfig.properties || {};
-
-      for (var index in properties) {
-        var serviceConfigObj = this.getDefaultConfig(index, serviceName, filename);
-        this.restrictSecureProperties(serviceConfigObj);
-
-        if (serviceConfigObj.isRequiredByAgent !== false) {
-          var formattedValue = this.formatPropertyValue(serviceConfigObj, properties[index]);
-          serviceConfigObj.value = serviceConfigObj.savedValue = formattedValue;
-          serviceConfigObj.isFinal = serviceConfigObj.savedIsFinal = finalAttributes[index] === "true";
-          serviceConfigObj.isEditable = this.getIsEditable(serviceConfigObj, selectedConfigGroup, canEdit);
-          serviceConfigObj.isVisible = serviceConfigObj.isVisible !== false || serviceName === 'MISC';
-        }
+  getConfigsFromJSON: function(configJSON, useEmberObject) {
+    var configs = [],
+      filename = App.config.getOriginalFileName(configJSON.type),
+      properties = configJSON.properties,
+      finalAttributes = Em.get(configJSON, 'properties_attributes.final') || {};
 
+    for (var index in properties) {
+      var serviceConfigObj = this.getDefaultConfig(index, filename);
+
+      if (serviceConfigObj.isRequiredByAgent !== false) {
+        serviceConfigObj.value = serviceConfigObj.savedValue = this.formatPropertyValue(serviceConfigObj, properties[index]);
+        serviceConfigObj.isFinal = serviceConfigObj.savedIsFinal = finalAttributes[index] === "true";
+        serviceConfigObj.isEditable = serviceConfigObj.isReconfigurable;
+      }
+
+      if (useEmberObject) {
         var serviceConfigProperty = App.ServiceConfigProperty.create(serviceConfigObj);
         serviceConfigProperty.validate();
         configs.push(serviceConfigProperty);
+      } else {
+        configs.push(serviceConfigObj);
       }
-    }, this);
-    return configs;
-  },
-
-  /**
-   * put secure properties in read-only mode
-   * @param {object} config
-   */
-  restrictSecureProperties: function (config) {
-    if (config.isSecureConfig) {
-      var isReadOnly = App.get('isKerberosEnabled');
-      config.isReconfigurable = config.isReconfigurable && !isReadOnly;
-      config.isOverridable = config.isOverridable && !isReadOnly;
     }
+    return configs;
   },
 
   /**
@@ -282,14 +256,13 @@ App.config = Em.Object.create({
    * such config
    *
    * @param name
-   * @param serviceName
    * @param fileName
    * @param coreObject
    * @returns {*|Object}
    */
-  getDefaultConfig: function(name, serviceName, fileName, coreObject) {
+  getDefaultConfig: function(name, fileName, coreObject) {
     var cfg = App.configsCollection.getConfigByName(name, fileName) ||
-      App.config.createDefaultConfig(name, serviceName, fileName, false, coreObject);
+      App.config.createDefaultConfig(name, fileName, false);
     if (Em.typeOf(coreObject) === 'object') {
       Em.setProperties(cfg, coreObject);
     }
@@ -301,13 +274,13 @@ App.config = Em.Object.create({
    * These property values has the lowest priority and can be overridden be stack/UI
    * config property but is used when such properties are absent in stack/UI configs
    * @param {string} name
-   * @param {string} serviceName
    * @param {string} fileName
    * @param {boolean} definedInStack
    * @param {Object} [coreObject]
    * @returns {Object}
    */
-  createDefaultConfig: function(name, serviceName, fileName, definedInStack, coreObject) {
+  createDefaultConfig: function(name, fileName, definedInStack, coreObject) {
+    var serviceName = this.get('serviceByConfigTypeMap')[fileName] || 'MISC';
     var tpl = {
       /** core properties **/
       id: this.configId(name, fileName),
@@ -457,17 +430,6 @@ App.config = Em.Object.create({
   },
 
   /**
-   * Calculate isEditable rely on controller state selected group and config restriction
-   * @param {Object} serviceConfigProperty
-   * @param {Object} selectedConfigGroup
-   * @param {boolean} canEdit
-   * @returns {boolean}
-   */
-  getIsEditable: function(serviceConfigProperty, selectedConfigGroup, canEdit) {
-    return canEdit && Em.get(selectedConfigGroup, 'isDefault') && Em.get(serviceConfigProperty, 'isReconfigurable')
-  },
-
-  /**
    * format property value depending on displayType
    * and one exception for 'kdc_type'
    * @param serviceConfigProperty
@@ -476,29 +438,14 @@ App.config = Em.Object.create({
    */
   formatPropertyValue: function(serviceConfigProperty, originalValue) {
     var value = Em.isNone(originalValue) ? Em.get(serviceConfigProperty, 'value') : originalValue,
-        displayType = Em.get(serviceConfigProperty, 'displayType') || Em.get(serviceConfigProperty, 'valueAttributes.type'),
-        category = Em.get(serviceConfigProperty, 'category');
+        displayType = Em.get(serviceConfigProperty, 'displayType') || Em.get(serviceConfigProperty, 'valueAttributes.type');
+    if (Em.get(serviceConfigProperty, 'name') === 'kdc_type') {
+      return App.router.get('mainAdminKerberosController.kdcTypesValues')[value];
+    }
+    if ( /^\s+$/.test("" + value)) {
+      return " ";
+    }
     switch (displayType) {
-      case 'content':
-      case 'string':
-      case 'multiLine':
-        return this.trimProperty({ displayType: displayType, value: value });
-        break;
-      case 'directories':
-        if (['DataNode', 'NameNode'].contains(category)) {
-          return value.split(',').sort().join(',');//TODO check if this code is used
-        }
-        break;
-      case 'directory':
-        if (['SNameNode'].contains(category)) {
-          return value.split(',').sort()[0];//TODO check if this code is used
-        }
-        break;
-      case 'componentHosts':
-        if (typeof(value) == 'string') {
-          return value.replace(/\[|]|'|&apos;/g, "").split(',');
-        }
-        break;
       case 'int':
         if (/\d+m$/.test(value) ) {
           return value.slice(0, value.length - 1);
@@ -506,18 +453,24 @@ App.config = Em.Object.create({
           var int = parseInt(value);
           return isNaN(int) ? "" : int.toString();
         }
-        break;
       case 'float':
         var float = parseFloat(value);
         return isNaN(float) ? "" : float.toString();
+      case 'componentHosts':
+        if (typeof(value) == 'string') {
+          return value.replace(/\[|]|'|&apos;/g, "").split(',');
+        }
+        return value;
+      case 'content':
+      case 'string':
+      case 'multiLine':
+      case 'directories':
+      case 'directory':
+        return this.trimProperty({ displayType: displayType, value: value });
+      default:
+        return value;
     }
-    if (Em.get(serviceConfigProperty, 'name') === 'kdc_type') {
-      return App.router.get('mainAdminKerberosController.kdcTypesValues')[value];
-    }
-    if ( /^\s+$/.test("" + value)) {
-      value = " ";
-    }
-    return value;
+
   },
 
   /**
@@ -559,43 +512,6 @@ App.config = Em.Object.create({
   },
 
   /**
-   *
-   * @param {string} ifStatement
-   * @param {Array} serviceConfigs
-   * @returns {boolean}
-   */
-  calculateConfigCondition: function(ifStatement, serviceConfigs) {
-    // Split `if` statement if it has logical operators
-    var ifStatementRegex = /(&&|\|\|)/;
-    var IfConditions = ifStatement.split(ifStatementRegex);
-    var allConditionResult = [];
-    IfConditions.forEach(function(_condition){
-      var condition = _condition.trim();
-      if (condition === '&&' || condition === '||') {
-        allConditionResult.push(_condition);
-      }  else {
-        var splitIfCondition = condition.split('===');
-        var ifCondition = splitIfCondition[0];
-        var result = splitIfCondition[1] || "true";
-        var parseIfConditionVal = ifCondition;
-        var regex = /\$\{.*?\}/g;
-        var configStrings = ifCondition.match(regex);
-        configStrings.forEach(function (_configString) {
-          var configObject = _configString.substring(2, _configString.length - 1).split("/");
-          var config = serviceConfigs.filterProperty('filename', configObject[0] + '.xml').findProperty('name', configObject[1]);
-          if (config) {
-            var configValue = Em.get(config, 'value');
-            parseIfConditionVal = parseIfConditionVal.replace(_configString, configValue);
-          }
-        }, this);
-        var conditionResult = window.eval(JSON.stringify(parseIfConditionVal.trim())) === result.trim();
-        allConditionResult.push(conditionResult);
-      }
-    }, this);
-    return Boolean(window.eval(allConditionResult.join('')));
-  },
-
-  /**
    * create new ServiceConfig object by service name
    * @param {string} serviceName
    * @param {App.ServiceConfigGroup[]} [configGroups]
@@ -687,7 +603,7 @@ App.config = Em.Object.create({
    * @return {Object}
    **/
   createCustomGroupConfig: function (propertyName, fileName, value, group, isEditable, isInstaller) {
-    var propertyObject = this.createDefaultConfig(propertyName, group.get('service.serviceName'), this.getOriginalFileName(fileName), false, {
+    var propertyObject = this.createDefaultConfig(propertyName, this.getOriginalFileName(fileName), false, {
       savedValue: isInstaller ? null : value,
       value: value,
       group: group,
@@ -726,8 +642,9 @@ App.config = Em.Object.create({
     var savedIsFinal = connectedConfigs.someProperty('savedIsFinal', true);
     var recommendedIsFinal = connectedConfigs.someProperty('recommendedIsFinal', true);
 
-    var cs = App.config.createDefaultConfig('capacity-scheduler', 'YARN', 'capacity-scheduler.xml', true, {
+    var cs = App.config.createDefaultConfig('capacity-scheduler', 'capacity-scheduler.xml', true, {
       'value': value,
+      'serviceName': 'YARN',
       'savedValue': savedValue || null,
       'recommendedValue': recommendedValue || null,
       'isFinal': isFinal,

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/ambari-web/app/utils/configs/theme/theme.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/configs/theme/theme.js b/ambari-web/app/utils/configs/theme/theme.js
new file mode 100644
index 0000000..236faa8
--- /dev/null
+++ b/ambari-web/app/utils/configs/theme/theme.js
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.configTheme = Em.Object.create({
+
+  /**
+   * Resolve config theme conditions
+   * in order to correctly calculate config errors number of service
+   * @param {Array} configs
+   */
+  resolveConfigThemeConditions: function (configs) {
+    App.ThemeCondition.find().forEach(function (configCondition) {
+      var _configs = Em.A(configCondition.get('configs'));
+      if (configCondition.get("resource") === 'config' && _configs.length > 0) {
+        var isConditionTrue = this.calculateConfigCondition(configCondition.get("if"), configs);
+        var action = isConditionTrue ? configCondition.get("then") : configCondition.get("else");
+        if (configCondition.get('id')) {
+          var valueAttributes = action.property_value_attributes;
+          if (valueAttributes && !Em.none(valueAttributes['visible'])) {
+            var themeResource;
+            if (configCondition.get('type') === 'subsection') {
+              themeResource = App.SubSection.find().findProperty('name', configCondition.get('name'));
+            } else if (configCondition.get('type') === 'subsectionTab') {
+              themeResource = App.SubSectionTab.find().findProperty('name', configCondition.get('name'));
+            } else if (configCondition.get('type') === 'config') {
+              //simulate section wrapper for condition type "config"
+              themeResource = Em.Object.create({
+                configProperties: [App.config.configId(configCondition.get('configName'), configCondition.get('fileName'))]
+              });
+            }
+            if (themeResource) {
+              themeResource.get('configProperties').forEach(function (_configId) {
+                configs.forEach(function (item) {
+                  if (App.config.configId(item.name, item.filename) === _configId) {
+                    // if config has already been hidden by condition with "subsection" or "subsectionTab" type
+                    // then ignore condition of "config" type
+                    if (configCondition.get('type') === 'config' && item.hiddenBySection) return false;
+                    item.hiddenBySection = !valueAttributes['visible'];
+                  }
+                });
+              }, this);
+            }
+          }
+        }
+      }
+    });
+  },
+
+  /**
+   *
+   * @param {string} ifStatement
+   * @param {Array} serviceConfigs
+   * @returns {boolean}
+   */
+  calculateConfigCondition: function(ifStatement, serviceConfigs) {
+    // Split `if` statement if it has logical operators
+    var ifStatementRegex = /(&&|\|\|)/;
+    var IfConditions = ifStatement.split(ifStatementRegex);
+    var allConditionResult = [];
+    IfConditions.forEach(function(_condition){
+      var condition = _condition.trim();
+      if (condition === '&&' || condition === '||') {
+        allConditionResult.push(_condition);
+      }  else {
+        var splitIfCondition = condition.split('===');
+        var ifCondition = splitIfCondition[0];
+        var result = splitIfCondition[1] || "true";
+        var parseIfConditionVal = ifCondition;
+        var regex = /\$\{.*?\}/g;
+        var configStrings = ifCondition.match(regex);
+        configStrings.forEach(function (_configString) {
+          var configObject = _configString.substring(2, _configString.length - 1).split("/");
+          var config = serviceConfigs.filterProperty('filename', configObject[0] + '.xml').findProperty('name', configObject[1]);
+          if (config) {
+            var configValue = Em.get(config, 'value');
+            parseIfConditionVal = parseIfConditionVal.replace(_configString, configValue);
+          }
+        }, this);
+        var conditionResult = window.eval(JSON.stringify(parseIfConditionVal.trim())) === result.trim();
+        allConditionResult.push(conditionResult);
+      }
+    }, this);
+    return Boolean(window.eval(allConditionResult.join('')));
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/ambari-web/app/views/common/configs/widgets/config_widget_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/widgets/config_widget_view.js b/ambari-web/app/views/common/configs/widgets/config_widget_view.js
index 9858b75..3ad9e3b 100644
--- a/ambari-web/app/views/common/configs/widgets/config_widget_view.js
+++ b/ambari-web/app/views/common/configs/widgets/config_widget_view.js
@@ -394,7 +394,7 @@ App.ConfigWidgetView = Em.View.extend(App.SupportsDependentConfigs, App.WidgetPo
     configConditions.forEach(function(configCondition){
       var ifStatement =  configCondition.get("if");
       if (configCondition.get("resource") === 'config') {
-        isConditionTrue = App.config.calculateConfigCondition(ifStatement, serviceConfigs);
+        isConditionTrue = App.configTheme.calculateConfigCondition(ifStatement, serviceConfigs);
         if (configCondition.get("type") === 'subsection' || configCondition.get("type") === 'subsectionTab') {
           this.changeSubsectionAttribute(configCondition, isConditionTrue);
         } else {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js b/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
index fa78916..1b706ea 100644
--- a/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
@@ -185,14 +185,17 @@ describe('App.KerberosWizardStep4Controller', function() {
         sinon.stub(App.StackService, 'find').returns([
           Em.Object.create({
             serviceName: 'KERBEROS',
-            configCategories: []
+            configCategories: [],
+            configTypeList: []
           }),
           Em.Object.create({
             serviceName: 'HDFS',
-            configCategories: []
+            configCategories: [],
+            configTypeList: []
           }),
           Em.Object.create({
-            serviceName: 'MAPREDUCE2'
+            serviceName: 'MAPREDUCE2',
+            configTypeList: []
           })
         ]);
         sinon.stub(App.Service, 'find').returns([

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/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 0ceec97..1291ed9 100644
--- a/ambari-web/test/controllers/wizard/step7_test.js
+++ b/ambari-web/test/controllers/wizard/step7_test.js
@@ -2323,14 +2323,15 @@ describe('App.InstallerStep7Controller', function () {
       beforeEach(function () {
         installerStep7Controller.set('wizardController', {name: 'addServiceController'});
         this.stub = sinon.stub(App.configsCollection, 'getConfigByName');
-        sinon.stub(App.config, 'getServiceByConfigType', function (type) {
-          return Em.Object.create({serviceName: type === 't1' ? 's1' : 's2'});
+        sinon.stub(App.config, 'get').withArgs('serviceByConfigTypeMap').returns({
+          't1': Em.Object.create({serviceName: 's1'}),
+          't2': Em.Object.create({serviceName: 's2'})
         })
       });
 
       afterEach(function () {
         App.configsCollection.getConfigByName.restore();
-        App.config.getServiceByConfigType.restore();
+        App.config.get.restore();
       });
 
       it('stackProperty does not exist', function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ea6a7a61/ambari-web/test/utils/config_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/config_test.js b/ambari-web/test/utils/config_test.js
index 8dda9f6..e556230 100644
--- a/ambari-web/test/utils/config_test.js
+++ b/ambari-web/test/utils/config_test.js
@@ -510,44 +510,6 @@ describe('App.config', function () {
     });
   });
 
-  describe('#getIsEditable', function() {
-    [{
-        isDefaultGroup: true,
-        isReconfigurable: true,
-        canEdit: true,
-        res: true,
-        m: "isEditable is true"
-      },
-      {
-        isDefaultGroup: false,
-        isReconfigurable: true,
-        canEdit: true,
-        res: false,
-        m: "isEditable is false; config group is not default"
-      },
-      {
-        isDefaultGroup: true,
-        isReconfigurable: false,
-        canEdit: true,
-        res: false,
-        m: "isEditable is true; config is not reconfigurable"
-      },
-      {
-        isDefaultGroup: true,
-        isReconfigurable: true,
-        canEdit: false,
-        res: false,
-        m: "isEditable is true; edition restricted by controller state"
-    }].forEach(function(t) {
-        it(t.m, function() {
-          var configProperty = Ember.Object.create({isReconfigurable: t.isReconfigurable});
-          var configGroup = Ember.Object.create({isDefault: t.isDefaultGroup});
-          var isEditable = App.config.getIsEditable(configProperty, configGroup, t.canEdit);
-          expect(isEditable).to.equal(t.res);
-        })
-      });
-  });
-
   describe('#getIsSecure', function() {
     var secureConfigs = App.config.get('secureConfigs');
     before(function() {
@@ -692,6 +654,12 @@ describe('App.config', function () {
       sinon.stub(App.config, 'shouldSupportFinal', function() {
         return true;
       });
+      sinon.stub(App.config, 'get', function(param) {
+        if (param === 'serviceByConfigTypeMap') {
+          return { 'pFileName': 'pServiceName' };
+        }
+        return Em.get(App.config, param);
+      });
     });
 
     after(function() {
@@ -699,11 +667,12 @@ describe('App.config', function () {
       App.config.getDefaultCategory.restore();
       App.config.getIsSecure.restore();
       App.config.shouldSupportFinal.restore();
+      App.config.get.restore();
     });
 
     var res = {
       /** core properties **/
-      id: "pName__pFileName",
+      id: 'pName__pFileName',
       name: 'pName',
       filename: 'pFileName.xml',
       value: '',
@@ -738,7 +707,7 @@ describe('App.config', function () {
       widgetType: null
     };
     it('create default config object', function () {
-      expect(App.config.createDefaultConfig('pName', 'pServiceName', 'pFileName', true)).to.eql(res);
+      expect(App.config.createDefaultConfig('pName', 'pFileName', true)).to.eql(res);
     });
     it('getDefaultDisplayType is called', function() {
       expect(App.config.getDefaultDisplayType.called).to.be.true;
@@ -890,83 +859,6 @@ describe('App.config', function () {
     });
   });
 
-  describe("#restrictSecureProperties()", function() {
-    var testCases = [
-      {
-        input: {
-          isSecureConfig: true,
-          isKerberosEnabled: true,
-          isReconfigurable: false,
-          isOverridable: false
-        },
-        expected: {
-          isReconfigurable: false,
-          isOverridable: false
-        }
-      },
-      {
-        input: {
-          isSecureConfig: true,
-          isKerberosEnabled: true,
-          isReconfigurable: true,
-          isOverridable: true
-        },
-        expected: {
-          isReconfigurable: false,
-          isOverridable: false
-        }
-      },
-      {
-        input: {
-          isSecureConfig: true,
-          isKerberosEnabled: false,
-          isReconfigurable: true,
-          isOverridable: true
-        },
-        expected: {
-          isReconfigurable: true,
-          isOverridable: true
-        }
-      },
-      {
-        input: {
-          isSecureConfig: false,
-          isReconfigurable: false,
-          isOverridable: false
-        },
-        expected: {
-          isReconfigurable: false,
-          isOverridable: false
-        }
-      },
-      {
-        input: {
-          isSecureConfig: false,
-          isReconfigurable: true,
-          isOverridable: true
-        },
-        expected: {
-          isReconfigurable: true,
-          isOverridable: true
-        }
-      }
-    ];
-
-    testCases.forEach(function(test) {
-      it("isSecureConfig = " + test.input.isSecureConfig + "; isKerberosEnabled = " + test.input.isKerberosEnabled, function() {
-        var config = {
-          isSecureConfig: test.input.isSecureConfig,
-          isReconfigurable: test.input.isReconfigurable,
-          isOverridable: test.input.isOverridable
-        };
-        App.set('isKerberosEnabled', !!test.input.isKerberosEnabled);
-        App.config.restrictSecureProperties(config);
-        expect(config.isReconfigurable).to.equal(test.expected.isReconfigurable);
-        expect(config.isOverridable).to.equal(test.expected.isOverridable);
-      });
-    });
-  });
-
   describe("#truncateGroupName()", function() {
 
     it("name is empty", function() {