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 2015/08/04 14:37:56 UTC

ambari git commit: AMBARI-12631 Load current version and all versions info in parallel requests to reduce service config page loading time. (ababiichuk)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.1 08a1a6eae -> db1c23ac3


AMBARI-12631 Load current version and all versions info in parallel requests to reduce service config page loading time. (ababiichuk)


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

Branch: refs/heads/branch-2.1
Commit: db1c23ac39fb308dc44546982ccc90f3ccf69478
Parents: 08a1a6e
Author: aBabiichuk <ab...@cybervisiontech.com>
Authored: Tue Aug 4 15:34:55 2015 +0300
Committer: aBabiichuk <ab...@cybervisiontech.com>
Committed: Tue Aug 4 15:35:36 2015 +0300

----------------------------------------------------------------------
 .../controllers/main/service/info/configs.js    |  56 +--
 ambari-web/app/data/HDP2.2/site_properties.js   |   8 +
 .../configs/stack_config_properties_mapper.js   |   2 +-
 ambari-web/app/mixins.js                        |   1 -
 .../app/mixins/common/configs/configs_loader.js |  28 +-
 .../service/configs/preload_requests_chain.js   | 364 -------------------
 .../templates/common/configs/service_config.hbs |   6 +-
 ambari-web/app/views/common/controls_view.js    |   2 +-
 .../main/host/configs_service_test.js           |   9 +-
 .../main/service/info/config_test.js            |   8 +-
 10 files changed, 57 insertions(+), 427 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/db1c23ac/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 ca2500f..6ff285e 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -39,7 +39,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
 
   selectedConfigGroup: null,
 
-  requestInProgress: null,
+  requestsInProgress: [],
 
   groupsStore: App.ServiceConfigGroup.find(),
 
@@ -98,14 +98,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
   }.property('content.serviceName', 'dependentServiceNames.length'),
 
   /**
-   * defines which config groups need to be loaded
-   * @type {object[]}
-   */
-  configGroupsToLoad: function() {
-    return this.get('configGroups').concat(this.get('dependentConfigGroups')).uniq();
-  }.property('content.serviceName', 'dependentServiceNames'),
-
-  /**
    * @type {boolean}
    */
   isCurrentSelected: function () {
@@ -124,10 +116,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
     return App.config.get('preDefinedServiceConfigs');
   }.property('App.config.preDefinedServiceConfigs'),
 
-  configs: function () {
-    return  App.config.get('preDefinedSiteProperties');
-  }.property('App.config.preDefinedSiteProperties'),
-
   showConfigHistoryFeature: true,
 
   /**
@@ -162,8 +150,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
     return this.get('stepConfigs').someProperty('isPropertiesChanged', true);
   }.property('stepConfigs.@each.isPropertiesChanged'),
 
-  slaveComponentGroups: null,
-
   /**
    * Filter text will be located here
    * @type {string}
@@ -199,7 +185,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
   ],
 
   /**
-   * get array of config proerties that are shown in settings tab
+   * get array of config properties that are shown in settings tab
    * @type {App.StackConfigProperty[]}
    */
   settingsTabProperties: function() {
@@ -249,7 +235,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
    * @method trackRequest
    */
   trackRequest: function (request) {
-    this.set('requestInProgress', request);
+    this.get('requestsInProgress').push(request);
   },
 
   /**
@@ -257,10 +243,12 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
    * @method clearStep
    */
   clearStep: function () {
-    if (this.get('requestInProgress') && this.get('requestInProgress').readyState !== 4) {
-      this.get('requestInProgress').abort();
-      this.set('requestInProgress', null);
-    }
+    this.get('requestsInProgress').forEach(function(r) {
+      if (r && r.readyState !== 4) {
+        r.abort();
+      }
+    });
+    this.get('requestsInProgress').clear();
     this.clearLoadInfo();
     this.clearSaveInfo();
     this.clearDependentConfigs();
@@ -272,7 +260,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
       dataIsLoaded: false,
       versionLoaded: false,
       filter: '',
-      serviceConfigVersionNote: ''
+      serviceConfigVersionNote: '',
+      dependentServiceNames: []
     });
     this.get('filterColumns').setEach('selected', false);
     this.clearConfigs();
@@ -288,13 +277,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
   },
 
   /**
-   * @type {object[]}
-   */
-  serviceConfigProperties: function () {
-    return App.db.getServiceConfigProperties();
-  }.property('content'),
-
-  /**
    * "Finger-print" of the <code>stepConfigs</code>. Filled after first configGroup selecting
    * Used to determine if some changes were made (when user navigates away from this page)
    * @type {String|null}
@@ -320,6 +302,9 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
         App.themesMapper.generateAdvancedTabs([serviceName]);
       });
     }
+    if (!this.get('preSelectedConfigVersion')) {
+      this.loadCurrentVersions();
+    }
     this.loadServiceConfigVersions();
   },
 
@@ -330,17 +315,17 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
    * @method getHash
    */
   getHash: function () {
-    if (!this.get('stepConfigs')[0]) {
+    if (!this.get('selectedService.configs.length')) {
       return null;
     }
     var hash = {};
     this.get('selectedService.configs').forEach(function (config) {
-      hash[config.get('name')] = {value: config.get('value'), overrides: [], isFinal: config.get('isFinal')};
+      hash[config.get('name')] = {value: App.config.formatPropertyValue(config), overrides: [], isFinal: config.get('isFinal')};
       if (!config.get('overrides')) return;
       if (!config.get('overrides.length')) return;
 
       config.get('overrides').forEach(function (override) {
-        hash[config.get('name')].overrides.push(override.get('value'));
+        hash[config.get('name')].overrides.push(App.config.formatPropertyValue(override));
       });
     });
     return JSON.stringify(hash);
@@ -571,17 +556,14 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
    * @method _getRecommendationsForDependenciesCallback
    */
   _onLoadComplete: function () {
-    var self = this;
     this.get('stepConfigs').forEach(function(serviceConfig){
       serviceConfig.set('initConfigsLength', serviceConfig.get('configs.length'));
     });
     this.setProperties({
       dataIsLoaded: true,
       versionLoaded: true,
-      isInit: false
-    });
-    Em.run.next(function() {
-      self.set('hash', self.getHash());
+      isInit: false,
+      hash: this.getHash()
     });
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/db1c23ac/ambari-web/app/data/HDP2.2/site_properties.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/HDP2.2/site_properties.js b/ambari-web/app/data/HDP2.2/site_properties.js
index f8b88e7..0e68eee 100644
--- a/ambari-web/app/data/HDP2.2/site_properties.js
+++ b/ambari-web/app/data/HDP2.2/site_properties.js
@@ -117,6 +117,14 @@ hdp22properties.push(
   },
   {
     "id": "site property",
+    "name": "keyserver_port",
+    "isRequired": false,
+    "category": "Advanced hadoop-env",
+    "serviceName": "HDFS",
+    "filename": "hadoop-env.xml"
+  },
+  {
+    "id": "site property",
     "name": "*.falcon.graph.blueprints.graph",
     "displayName": "*.falcon.graph.blueprints.graph",
     "category": "FalconStartupSite",

http://git-wip-us.apache.org/repos/asf/ambari/blob/db1c23ac/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 e907020..3c11fa1 100644
--- a/ambari-web/app/mappers/configs/stack_config_properties_mapper.js
+++ b/ambari-web/app/mappers/configs/stack_config_properties_mapper.js
@@ -121,7 +121,7 @@ App.stackConfigPropertiesMapper = App.QuickDataMapper.create({
     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.display_type = App.config.getPropertyIfExists('displayType', Em.get(c, 'property_value_attributes.type') || App.config.getDefaultDisplayType(c.property_name, c.type, c.property_value), advancedData, uiConfigProperty);
     config.index = App.config.getPropertyIfExists('index', null, advancedData, uiConfigProperty);
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/db1c23ac/ambari-web/app/mixins.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins.js b/ambari-web/app/mixins.js
index ca5c633..d86eccf 100644
--- a/ambari-web/app/mixins.js
+++ b/ambari-web/app/mixins.js
@@ -31,7 +31,6 @@ require('mixins/main/service/groups_mapping');
 require('mixins/main/service/themes_mapping');
 require('mixins/main/service/versions_mapping');
 require('mixins/main/service/configs/config_overridable');
-require('mixins/main/service/configs/preload_requests_chain');
 require('mixins/main/service/configs/widget_popover_support');
 require('mixins/routers/redirections');
 require('mixins/wizard/wizardProgressPageController');

http://git-wip-us.apache.org/repos/asf/ambari/blob/db1c23ac/ambari-web/app/mixins/common/configs/configs_loader.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/configs_loader.js b/ambari-web/app/mixins/common/configs/configs_loader.js
index 7d7b666..5546f6b 100644
--- a/ambari-web/app/mixins/common/configs/configs_loader.js
+++ b/ambari-web/app/mixins/common/configs/configs_loader.js
@@ -26,17 +26,17 @@ App.ConfigsLoader = Em.Mixin.create(App.GroupsMappingMixin, {
   currentDefaultVersion: null,
 
   /**
-   * the highest version number that is stored in <code>App.ServiceConfigVersion<code>
-   * @type {number}
+   * defines if service config versions are loaded to model
+   * @type {boolean}
    */
-  lastLoadedVersion: 0,
+  allVersionsLoaded: false,
 
   /**
    * this method should be used in clear step method
    * @method clearLoadInfo
    */
   clearLoadInfo: function() {
-    this.set('lastLoadedVersion', 0);
+    this.set('allVersionsLoaded', false);
   },
 
   /**
@@ -44,16 +44,10 @@ App.ConfigsLoader = Em.Mixin.create(App.GroupsMappingMixin, {
    * @returns {$.ajax}
    */
   loadServiceConfigVersions: function () {
-    App.ServiceConfigVersion.find().forEach(function (v) {
-      if (v.get('isCurrent') && v.get('serviceName') == this.get('content.serviceName') && v.get('version') > this.get('lastLoadedVersion')) {
-        this.set('lastLoadedVersion', v.get('version'));
-      }
-    }, this);
     return App.ajax.send({
-      name: 'service.serviceConfigVersions.get.not.loaded',
+      name: 'service.serviceConfigVersions.get',
       data: {
-        serviceName: this.get('content.serviceName'),
-        lastSavedVersion: this.get('lastLoadedVersion').toString()
+        serviceName: this.get('content.serviceName')
       },
       sender: this,
       success: 'loadServiceConfigVersionsSuccess'
@@ -71,12 +65,10 @@ App.ConfigsLoader = Em.Mixin.create(App.GroupsMappingMixin, {
       if (currentDefault) {
         this.set('currentDefaultVersion', currentDefault.service_config_version);
       }
-    } else {
-      this.set('currentDefaultVersion', App.ServiceConfigVersion.find().find(function(v) {
-        return v.get('isCurrent') && v.get('isDefault') && v.get('serviceName') == this.get('content.serviceName');
-      }, this).get('version'));
     }
+    this.set('allVersionsLoaded', true);
     if (this.get('preSelectedConfigVersion')) {
+      this.set('selectedVersion', this.get('preSelectedConfigVersion.version'));
       /** handling redirecting from config history page **/
       var self = this;
       this.loadConfigGroups(this.get('servicesToLoad')).done(function() {
@@ -89,7 +81,7 @@ App.ConfigsLoader = Em.Mixin.create(App.GroupsMappingMixin, {
         self.set('preSelectedConfigVersion', null);
       });
     } else {
-      this.loadCurrentVersions();
+      this.set('selectedVersion', this.get('currentDefaultVersion'));
     }
   },
 
@@ -101,7 +93,6 @@ App.ConfigsLoader = Em.Mixin.create(App.GroupsMappingMixin, {
   loadCurrentVersions: function() {
     this.set('isCompareMode', false);
     this.set('versionLoaded', false);
-    this.set('selectedVersion', this.get('currentDefaultVersion'));
     this.trackRequest(App.ajax.send({
       name: 'service.serviceConfigVersions.get.current',
       sender: this,
@@ -135,6 +126,7 @@ App.ConfigsLoader = Em.Mixin.create(App.GroupsMappingMixin, {
     version = version || this.get('currentDefaultVersion');
     if (version === this.get('currentDefaultVersion') && (!switchToGroup || switchToGroup.get('isDefault'))) {
       this.loadCurrentVersions();
+      this.set('selectedVersion', this.get('currentDefaultVersion'));
     } else {
       //version of non-default group require properties from current version of default group to correctly display page
       var versions = (this.isVersionDefault(version)) ? [version] : [this.get('currentDefaultVersion'), version];

http://git-wip-us.apache.org/repos/asf/ambari/blob/db1c23ac/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js b/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js
deleted file mode 100644
index 0a163ff..0000000
--- a/ambari-web/app/mixins/main/service/configs/preload_requests_chain.js
+++ /dev/null
@@ -1,364 +0,0 @@
-/**
- * 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');
-
-/**
- * Mixin with chain of the methods for initial configs loading
- * Used in the service configs controller
- * Entry point - <code>loadClusterEnvSite</code>
- * Chain:
- *    - loadClusterEnvSite
- *      |- (on success callback)
- *         loadServiceConfigVersions
- *           |- (on success callback)
- *              loadSelectedVersion
- *                 |- (on complete callback)
- *                    loadServiceTagsAndGroups
- * @type {Ember.Mixin}
- */
-App.PreloadRequestsChainMixin = Em.Mixin.create({
-
-  /**
-   * @type {Function}
-   */
-  trackRequest: Em.required(Function),
-
-  /**
-   * @type {Function}
-   */
-  isVersionDefault: Em.required(Function),
-
-  /**
-   * temp stores dependent groups
-   */
-  dependentConfigGroups: [],
-  /**
-   * load all tag versions of cluster-env site
-   * @returns {$.ajax}
-   * @method loadClusterEnvSite
-   */
-  loadClusterEnvSite: function () {
-    return App.ajax.send({
-      name: 'config.cluster_env_site',
-      sender: this,
-      success: 'loadClusterEnvSiteSuccess'
-    });
-  },
-
-  /**
-   * Success-callback for loadClusterEnvSite
-   * @param data
-   * @private
-   * @method loadClusterEnvSiteSuccess
-   */
-  loadClusterEnvSiteSuccess: function (data) {
-    // find the latest tag version
-    var maxVersion = Math.max.apply(this, data.items.mapProperty('version'));
-    this.set('clusterEnvTagVersion', data.items.findProperty('version', maxVersion).tag);
-    this.trackRequest(this.loadServiceConfigVersions());
-  },
-
-  /**
-   * get service config versions of current service
-   * @return {$.ajax}
-   * @private
-   * @method loadServiceConfigVersions
-   */
-  loadServiceConfigVersions: function () {
-    return App.ajax.send({
-      name: 'service.serviceConfigVersions.get',
-      data: {
-        serviceName: this.get('content.serviceName')
-      },
-      sender: this,
-      success: 'loadServiceConfigVersionsSuccess',
-      error: 'loadServiceConfigVersionsError'
-    })
-  },
-
-  /**
-   * success callback for loadServiceConfigVersions
-   * load service config versions to model
-   * set currentDefaultVersion
-   * @param data
-   * @param opt
-   * @param params
-   * @private
-   * @method loadServiceConfigVersionsSuccess
-   */
-  loadServiceConfigVersionsSuccess: function (data, opt, params) {
-    App.serviceConfigVersionsMapper.map(data);
-    this.set('currentDefaultVersion', data.items.filterProperty('group_id', -1).findProperty('is_current').service_config_version);
-    if (this.get('preSelectedConfigVersion')) {
-      this.loadSelectedVersion(this.get('preSelectedConfigVersion.version'));
-    } else {
-      this.loadSelectedVersion();
-    }
-  },
-
-  /**
-   * error callback of loadServiceConfigVersions()
-   * override defaultCallback
-   * @private
-   * @method loadServiceConfigVersionsError
-   */
-  loadServiceConfigVersionsError: Em.K,
-
-  /**
-   * get selected service config version
-   * In case selected version is undefined then take currentDefaultVersion
-   * @param version
-   * @param switchToGroup
-   * @method loadSelectedVersion
-   */
-  loadSelectedVersion: function (version, switchToGroup) {
-    var self = this;
-    this.set('versionLoaded', false);
-    version = version || this.get('currentDefaultVersion');
-    //version of non-default group require properties from current version of default group to correctly display page
-    var versions = (this.isVersionDefault(version)) ? [version] : [this.get('currentDefaultVersion'), version];
-    switchToGroup = (this.isVersionDefault(version) && !switchToGroup) ? this.get('configGroups').findProperty('isDefault') : switchToGroup;
-
-    if (self.get('dataIsLoaded') && switchToGroup) {
-      this.set('selectedConfigGroup', switchToGroup);
-    }
-    var data = {
-      serviceName: this.get('content.serviceName'),
-      serviceConfigVersions: versions
-    };
-    if (App.get('isClusterSupportsEnhancedConfigs') && this.get('dependentServiceNames.length')) {
-      data.additionalParams = '|service_name.in(' +  this.get('dependentServiceNames') + ')&is_current=true';
-    }
-    this.trackRequest(App.ajax.send({
-      name: 'service.serviceConfigVersions.get.multiple',
-      sender: this,
-      data: data,
-      success: 'loadSelectedVersionSuccess'
-    }).complete(function (xhr) {
-        if (xhr.statusText === 'abort') return;
-        if (self.get('dataIsLoaded')) {
-          self.onConfigGroupChange();
-        } else {
-          self.loadServiceTagsAndGroups();
-        }
-      }));
-  },
-
-  /**
-   * load config groups of service
-   * and dependent services
-   * @private
-   * @method loadServiceTagsAndGroups
-   */
-  loadServiceTagsAndGroups: function () {
-    this.trackRequest(App.ajax.send({
-      name: 'config.tags_and_groups',
-      sender: this,
-      data: {
-        serviceName: this.get('content.serviceName'),
-        urlParams: "&config_groups/ConfigGroup/tag.in(" + this.get('servicesToLoad').join(',') + ')'
-      },
-      success: 'loadServiceConfigsSuccess'
-    }));
-  },
-
-  /**
-   * set cluster to site tag map
-   * @param data
-   * @param opt
-   * @param params
-   * @private
-   * @method loadSelectedVersionSuccess
-   */
-  loadSelectedVersionSuccess: function (data, opt, params) {
-    var serviceConfigsDef = this.get('serviceConfigs').filter(function(serviceConfig) {
-      return this.get('servicesToLoad').contains(serviceConfig.get('serviceName'));
-    }, this);
-    var siteToTagMap = {};
-    var configTypesRendered = [];
-    serviceConfigsDef.forEach(function(s) {
-      configTypesRendered = configTypesRendered.concat(Object.keys(s.get('configTypesRendered')));
-    });
-    var selectedVersion = params.serviceConfigVersions.length > 1 ? params.serviceConfigVersions[1] : params.serviceConfigVersions[0];
-    var configurations = [];
-
-
-    configTypesRendered.forEach(function (siteName) {
-      data.items.forEach(function (item) {
-        if (item.group_id == -1) {
-          configurations = item.configurations;
-          if (item.configurations.someProperty('type', siteName)) {
-            siteToTagMap[siteName] = item.configurations.findProperty('type', siteName).tag;
-          } else if (!siteToTagMap[siteName]) {
-            siteToTagMap[siteName] = 'version1';
-          }
-        } else {
-          //set config tags of non-default config group to load overrides from selected version
-          this.loadedGroupToOverrideSiteToTagMap[item.group_name] = {};
-          item.configurations.forEach(function (config) {
-            this.loadedGroupToOverrideSiteToTagMap[item.group_name][config.type] = config.tag;
-          }, this)
-        }
-      }, this)
-    }, this);
-
-    App.router.get('configurationController').saveToDB(configurations);
-
-    // add cluster-env tag
-    siteToTagMap['cluster-env'] = this.get('clusterEnvTagVersion');
-
-    this.loadedClusterSiteToTagMap = siteToTagMap;
-    this.set('selectedVersion', selectedVersion);
-    //reset map if selected current version of default group
-    if (this.get('isCurrentSelected') && selectedVersion === this.get('currentDefaultVersion')) {
-      this.loadedGroupToOverrideSiteToTagMap = {};
-    }
-  },
-
-  /**
-   * Success-callback for loadServiceTagsAndGroups
-   * @param {object} data
-   * @param {object} opt
-   * @param {object} params
-   * @private
-   * @method loadServiceConfigsSuccess
-   */
-  loadServiceConfigsSuccess: function (data, opt, params) {
-    this.setConfigGroups(data, opt, params);
-  },
-
-  /**
-   * @param {object} data
-   * @param {object} opt
-   * @param {object} params
-   * @private
-   * @method setConfigGroups
-   */
-  setConfigGroups: function (data, opt, params) {
-    var serviceName = this.get('content.serviceName');
-    var displayName = this.get('content.displayName');
-    var selectedConfigGroup;
-    var defaultHosts = App.get('allHostNames');
-
-    //parse loaded config groups
-    var configGroups = [];
-    if (data && data.config_groups && data.config_groups.length) {
-      data.config_groups.forEach(function (item) {
-        item = item.ConfigGroup;
-        if (item.tag === this.get('content.serviceName')) {
-          var groupHosts = item.hosts.mapProperty('host_name');
-          var newConfigGroup = App.ConfigGroup.create({
-            id: item.id,
-            name: item.group_name,
-            description: item.description,
-            isDefault: false,
-            parentConfigGroup: null,
-            service: App.Service.find().findProperty('serviceName', item.tag),
-            hosts: groupHosts,
-            configSiteTags: []
-          });
-          for (var i = 0; i < groupHosts.length; i++) {
-            defaultHosts = defaultHosts.without(groupHosts[i]);
-          }
-          item.desired_configs.forEach(function (config) {
-            newConfigGroup.configSiteTags.push(App.ConfigSiteTag.create({
-              site: config.type,
-              tag: config.tag
-            }));
-          }, this);
-          // select default selected group for hosts page
-          if (!selectedConfigGroup && this.get('isHostsConfigsPage') && newConfigGroup.get('hosts').contains(this.get('host.hostName')) && this.get('content.serviceName') === item.tag) {
-            selectedConfigGroup = newConfigGroup;
-          }
-          configGroups.push(newConfigGroup);
-        } else if (this.get('dependentServiceNames').contains(item.tag)) {
-          /**
-           * Load config groups for services that has dependent properties.
-           * If user change properties that have dependencies in not default config group
-           * user should pick to which config group Ambari should save these properties
-           * @type {App.ConfigGroup}
-           */
-          var newDependentConfigGroup = App.ConfigGroup.create({
-            id: item.id,
-            name: item.group_name,
-            description: item.description,
-            isDefault: false,
-            parentConfigGroup: null,
-            serviceName: item.tag,
-            service: App.Service.find().findProperty('serviceName', item.tag),
-            hosts: item.hosts.mapProperty('host_name')
-          });
-          item.desired_configs.forEach(function (config) {
-            newDependentConfigGroup.configSiteTags.push(App.ConfigSiteTag.create({
-              site: config.type,
-              tag: config.tag
-            }));
-          }, this);
-          if (!this.get('dependentConfigGroups').findProperty('name', item.group_name)) {
-            this.get('dependentConfigGroups').push(newDependentConfigGroup);
-          }
-        }
-      }, this);
-    }
-    this.get('dependentServiceNames').forEach(function(serviceName) {
-      if (serviceName !== this.get('content.serviceName')) {
-        var service = App.Service.find().findProperty('serviceName', serviceName);
-        /**
-         * default groups for dependent services
-         * @type {App.ConfigGroup}
-         */
-        var defaultConfigGroup = App.ConfigGroup.create({
-          name: service.get('displayName') + " Default",
-          description: "Default cluster level " + serviceName + " configuration",
-          isDefault: true,
-          hosts: [],
-          parentConfigGroup: null,
-          service: service,
-          serviceName: serviceName,
-          configSiteTags: []
-        });
-        if (!this.get('dependentConfigGroups').findProperty('name', defaultConfigGroup.get('name'))) {
-          this.get('dependentConfigGroups').push(defaultConfigGroup);
-        }
-      }
-    }, this);
-    this.set('configGroups', configGroups);
-    var defaultConfigGroup = App.ConfigGroup.create({
-      name: displayName + " Default",
-      description: "Default cluster level " + serviceName + " configuration",
-      isDefault: true,
-      hosts: defaultHosts,
-      parentConfigGroup: null,
-      service: this.get('content'),
-      serviceName: serviceName,
-      configSiteTags: []
-    });
-    if (!selectedConfigGroup) {
-      selectedConfigGroup = configGroups.findProperty('name', this.get('preSelectedConfigVersion.groupName')) || defaultConfigGroup;
-    }
-
-    this.get('configGroups').sort(function (configGroupA, configGroupB) {
-      return (configGroupA.name > configGroupB.name);
-    });
-    this.get('configGroups').unshift(defaultConfigGroup);
-    this.set('selectedConfigGroup', selectedConfigGroup);
-    this.set('preSelectedConfigVersion', null);
-  }
-
-});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/db1c23ac/ambari-web/app/templates/common/configs/service_config.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/service_config.hbs b/ambari-web/app/templates/common/configs/service_config.hbs
index c3dce57..b87596b 100644
--- a/ambari-web/app/templates/common/configs/service_config.hbs
+++ b/ambari-web/app/templates/common/configs/service_config.hbs
@@ -79,7 +79,11 @@
 {{/if}}
 
 {{#if view.showConfigHistoryFeature}}
-  {{view App.ConfigHistoryFlowView serviceBinding="selectedService"}}
+  {{#if allVersionsLoaded}}
+    {{view App.ConfigHistoryFlowView serviceBinding="selectedService"}}
+  {{else}}
+    <div class="spinner"></div>
+  {{/if}}
 {{/if}}
 
 {{#if versionLoaded}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/db1c23ac/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 f3782b4..a0759d7 100644
--- a/ambari-web/app/views/common/controls_view.js
+++ b/ambari-web/app/views/common/controls_view.js
@@ -922,7 +922,7 @@ App.checkConnectionView = App.ServiceConfigTextField.extend({
     this._super();
     var kdc = this.get('categoryConfigsAll').findProperty('name', 'kdc_type');
     var propertyAppendTo = this.get('categoryConfigsAll').findProperty('name', 'domains');
-    if (propertyAppendTo) propertyAppendTo.set('additionalView', App.CheckDBConnectionView.extend({databaseName: kdc && kdc.get('value')}));
+    if (propertyAppendTo && propertyAppendTo.get('state') === 'inDOM') propertyAppendTo.set('additionalView', App.CheckDBConnectionView.extend({databaseName: kdc && kdc.get('value')}));
   }
 });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/db1c23ac/ambari-web/test/controllers/main/host/configs_service_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/host/configs_service_test.js b/ambari-web/test/controllers/main/host/configs_service_test.js
index 9f5f73b..616574c 100644
--- a/ambari-web/test/controllers/main/host/configs_service_test.js
+++ b/ambari-web/test/controllers/main/host/configs_service_test.js
@@ -101,9 +101,16 @@ describe('App.MainHostServiceConfigsController', function () {
   });
 
 	describe("#loadStep()", function () {
+    beforeEach(function() {
+      sinon.stub(controller, 'loadCurrentVersions', Em.K);
+    });
+    afterEach(function() {
+      controller.loadCurrentVersions.restore();
+    });
 		it("should set host", function () {
 			controller.set('content', {
-				host: 'host1'
+				host: 'host1',
+        dependentServiceNames: []
 			});
 			controller.loadStep();
 			expect(controller.get('host')).to.be.equal('host1');

http://git-wip-us.apache.org/repos/asf/ambari/blob/db1c23ac/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 f2198e0..6fd8e98 100644
--- a/ambari-web/test/controllers/main/service/info/config_test.js
+++ b/ambari-web/test/controllers/main/service/info/config_test.js
@@ -25,6 +25,7 @@ describe("App.MainServiceInfoConfigsController", function () {
   beforeEach(function () {
     sinon.stub(App.themesMapper, 'generateAdvancedTabs').returns(Em.K);
     mainServiceInfoConfigsController = App.MainServiceInfoConfigsController.create({
+      dependentServiceNames: [],
       loadDependentConfigs: function () {
         return {done: Em.K}
       },
@@ -734,11 +735,12 @@ describe("App.MainServiceInfoConfigsController", function () {
 
   describe("#trackRequest()", function () {
     after(function(){
-      mainServiceInfoConfigsController.set('requestInProgress', null);
+      mainServiceInfoConfigsController.get('requestsInProgress').clear();
     });
-    it("should set requestInProgress", function () {
+    it("should set requestsInProgress", function () {
+      mainServiceInfoConfigsController.get('requestsInProgress').clear();
       mainServiceInfoConfigsController.trackRequest({'request': {}});
-      expect(mainServiceInfoConfigsController.get('requestInProgress')).to.eql({'request': {}});
+      expect(mainServiceInfoConfigsController.get('requestsInProgress')[0]).to.eql({'request': {}});
     });
   });