You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2018/04/19 12:15:20 UTC

[ambari] 01/02: AMBARI-23597 Config's tags should be cached

This is an automated email from the ASF dual-hosted git repository.

atkach pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit 2df67cca2a8193b346e08ae24b7ebbfcac1faae0
Author: Andrii Tkach <at...@apache.org>
AuthorDate: Wed Apr 18 13:22:57 2018 +0300

    AMBARI-23597 Config's tags should be cached
---
 .../app/controllers/global/cluster_controller.js   |  14 +--
 .../controllers/global/configuration_controller.js |  61 ++++++++++++
 .../app/controllers/global/update_controller.js    |  30 ++----
 .../main/admin/serviceAccounts_controller.js       |  64 +-----------
 .../controllers/main/admin/service_auto_start.js   |  31 ++----
 .../app/controllers/main/service/info/summary.js   |  11 +--
 ambari-web/app/controllers/main/service/item.js    |  43 ++------
 .../app/mixins/common/configs/enhanced_configs.js  |   2 +-
 ambari-web/app/mixins/common/serverValidator.js    |   2 +-
 ambari-web/app/routes/main.js                      |   8 +-
 ambari-web/app/utils/config.js                     |  27 -----
 ambari-web/app/utils/db.js                         |   9 ++
 .../app/views/common/quick_view_link_view.js       |  64 ++----------
 .../controllers/global/cluster_controller_test.js  |  29 ++++--
 .../global/configuration_controller_test.js        | 109 +++++++++++++++++++++
 .../controllers/global/update_controller_test.js   |  11 ++-
 .../main/admin/service_auto_start_test.js          |  39 +-------
 .../mixins/common/configs/enhanced_configs_test.js |   8 +-
 .../test/views/common/quick_link_view_test.js      |  93 +++---------------
 19 files changed, 273 insertions(+), 382 deletions(-)

diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js
index 20b0e8a..ba9034e 100644
--- a/ambari-web/app/controllers/global/cluster_controller.js
+++ b/ambari-web/app/controllers/global/cluster_controller.js
@@ -185,10 +185,6 @@ App.ClusterController = Em.Controller.extend(App.ReloadPopupMixin, {
 
     //force clear filters  for hosts page to load all data
     App.db.setFilterConditions('mainHostController', null);
-
-    //load cluster-env, used by alert check tolerance
-    // TODO services auto-start
-    App.router.get('updateController').updateClusterEnv();
   },
 
   loadClusterInfo: function() {
@@ -281,9 +277,13 @@ App.ClusterController = Em.Controller.extend(App.ReloadPopupMixin, {
   loadConfigProperties: function() {
     var self = this;
 
-    App.config.loadConfigsFromStack(App.Service.find().mapProperty('serviceName')).complete(function () {
-      App.config.loadClusterConfigsFromStack().complete(function () {
-        self.set('isConfigsPropertiesLoaded', true);
+    App.config.loadConfigsFromStack(App.Service.find().mapProperty('serviceName')).always(function () {
+      App.config.loadClusterConfigsFromStack().always(function () {
+        App.router.get('configurationController').updateConfigTags().always(() => {
+          App.router.get('updateController').updateClusterEnv().always(() => {
+            self.set('isConfigsPropertiesLoaded', true);
+          });
+        });
       });
     });
   },
diff --git a/ambari-web/app/controllers/global/configuration_controller.js b/ambari-web/app/controllers/global/configuration_controller.js
index 806064a..720574e 100644
--- a/ambari-web/app/controllers/global/configuration_controller.js
+++ b/ambari-web/app/controllers/global/configuration_controller.js
@@ -43,6 +43,20 @@ App.ConfigurationController = Em.Controller.extend({
       return this.loadFromDB(tags.mapProperty('siteName'));
     }
   },
+
+  /**
+   * if no sites specified then configs from all sites will be fetched
+   * @param {Array} sites
+   * @returns {$.Deferred}
+   */
+  getCurrentConfigsBySites: function (sites = []) {
+    const dfd = $.Deferred();
+    this.getConfigTags(sites).done((tags) => {
+      this.getConfigsByTags(tags).done(dfd.resolve);
+    });
+    return dfd.promise();
+  },
+
   /**
    * check whether tag versions have been changed
    * if they are different then return true
@@ -150,5 +164,52 @@ App.ConfigurationController = Em.Controller.extend({
       }
     });
     App.db.setConfigs(storedConfigs);
+  },
+
+  /**
+   * @param {Array} sites
+   * @return {Array}
+   */
+  getConfigTags: function(sites = []) {
+    const dfd = $.Deferred();
+    if (App.db.getTags().length > 0) {
+      dfd.resolve(this.extractTagsFromLocalDB(sites));
+    } else {
+      this.updateConfigTags().always(() => {
+        dfd.resolve(this.extractTagsFromLocalDB(sites));
+      });
+    }
+    return dfd.promise();
+  },
+
+  /**
+   *
+   * @param {Array} sites
+   * @return {Array}
+   */
+  extractTagsFromLocalDB: function(sites) {
+    return App.db.getTags().filter((tag) => {
+      if (sites.length > 0) {
+        return sites.contains(tag.siteName);
+      } else {
+        return true;
+      }
+    });
+  },
+
+  /**
+   * update configs' tags from server
+   */
+  updateConfigTags: function() {
+    return this.loadConfigTags().done((data) => {
+      const tags = [];
+      for (let site in data.Clusters.desired_configs) {
+        tags.push({
+          siteName: site,
+          tagName: data.Clusters.desired_configs[site].tag
+        });
+      }
+      App.db.setTags(tags);
+    });
   }
 });
diff --git a/ambari-web/app/controllers/global/update_controller.js b/ambari-web/app/controllers/global/update_controller.js
index fbaa9bf..c288b6a 100644
--- a/ambari-web/app/controllers/global/update_controller.js
+++ b/ambari-web/app/controllers/global/update_controller.js
@@ -210,7 +210,7 @@ App.UpdateController = Em.Controller.extend({
     App.StompClient.subscribe('/events/hostcomponents', App.hostComponentStatusMapper.map.bind(App.hostComponentStatusMapper));
     App.StompClient.subscribe('/events/alerts', App.alertSummaryMapper.map.bind(App.alertSummaryMapper));
     App.StompClient.subscribe('/events/ui_topologies', App.topologyMapper.map.bind(App.topologyMapper));
-    App.StompClient.subscribe('/events/configs', this.makeCallForClusterEnv.bind(this));
+    App.StompClient.subscribe('/events/configs', this.configsChangedHandler.bind(this));
     App.StompClient.subscribe('/events/services', App.serviceStateMapper.map.bind(App.serviceStateMapper));
     App.StompClient.subscribe('/events/hosts', App.hostStateMapper.map.bind(App.hostStateMapper));
     App.StompClient.subscribe('/events/alert_definitions', App.alertDefinitionsMapperAdapter.map.bind(App.alertDefinitionsMapperAdapter));
@@ -683,25 +683,17 @@ App.UpdateController = Em.Controller.extend({
     });
   },
 
-  makeCallForClusterEnv: function(event) {
+  configsChangedHandler: function(event) {
     if (event.configs && event.configs.someProperty('type', 'cluster-env')) {
       this.updateClusterEnv();
     }
+    App.router.get('configurationController').updateConfigTags();
   },
 
   //TODO - update service auto-start to use this
-  updateClusterEnv: function (callback) {
-    this.loadClusterConfig(callback).done(function (data) {
-      var tag = [
-        {
-          siteName: 'cluster-env',
-          tagName: data.Clusters.desired_configs['cluster-env'].tag,
-          newTagName: null
-        }
-      ];
-      App.router.get('configurationController').getConfigsByTags(tag).done(function (config) {
-        App.router.get('clusterController').set('clusterEnv', config[0]);
-      });
+  updateClusterEnv: function () {
+    return App.router.get('configurationController').getCurrentConfigsBySites(['cluster-env']).done(function (config) {
+      App.router.get('clusterController').set('clusterEnv', config[0]);
     });
   },
 
@@ -750,14 +742,8 @@ App.UpdateController = Em.Controller.extend({
   },
 
   updateHDFSNameSpaces: function () {
-    if (App.Service.find().someProperty('serviceName', 'HDFS') && App.get('isHaEnabled')) {
-      const siteName = 'hdfs-site',
-        storedHdfsSiteconfigs = App.db.getConfigs().findProperty('type', siteName),
-        tagName = storedHdfsSiteconfigs && storedHdfsSiteconfigs.tag;
-      App.router.get('configurationController').getConfigsByTags([{
-        siteName,
-        tagName
-      }]).done(configs => {
+    if (App.Service.find('HDFS').get('isLoaded') && App.get('isHaEnabled')) {
+      App.router.get('configurationController').getCurrentConfigsBySites(['hdfs-site']).done(configs => {
         const properties = configs && configs[0] && configs[0].properties;
         if (properties) {
           const nameSpaceProperty = properties['dfs.nameservices'];
diff --git a/ambari-web/app/controllers/main/admin/serviceAccounts_controller.js b/ambari-web/app/controllers/main/admin/serviceAccounts_controller.js
index 5b98bf3..a2037fc 100644
--- a/ambari-web/app/controllers/main/admin/serviceAccounts_controller.js
+++ b/ambari-web/app/controllers/main/admin/serviceAccounts_controller.js
@@ -17,7 +17,6 @@
  */
 
 var App = require('app');
-var stringUtils = require('utils/string_utils');
 
 require('controllers/main/service/info/configs');
 
@@ -33,69 +32,10 @@ App.MainAdminServiceAccountsController = App.MainServiceInfoConfigsController.ex
     this.loadServiceConfig();
   },
   loadServiceConfig: function () {
-    App.ajax.send({
-      name: 'config.tags',
-      sender: this,
-      data: {
-        serviceName: this.get('selectedService'),
-        serviceConfigsDef: this.get('serviceConfigs').findProperty('serviceName', this.get('selectedService'))
-      },
-      success: 'loadServiceTagSuccess'
+    App.router.get('configurationController').getCurrentConfigsBySites().done((serverConfigs) => {
+      this.createConfigObject(serverConfigs);
     });
   },
-  loadServiceTagSuccess: function (data, opt, params) {
-    var self = this;
-    var serviceConfigsDef = params.serviceConfigsDef;
-    var loadedClusterSiteToTagMap = {};
-
-    for (var site in Em.get(data, 'Clusters.desired_configs')) {
-      if (serviceConfigsDef.get('configTypes').hasOwnProperty(site)) {
-        loadedClusterSiteToTagMap[site] = data.Clusters.desired_configs[site]['tag'];
-      }
-    }
-    this.setServiceConfigTags(loadedClusterSiteToTagMap);
-    // load server stored configurations
-    App.router.get('configurationController').getConfigsByTags(this.get('serviceConfigTags')).done(function (serverConfigs) {
-      self.createConfigObject(serverConfigs);
-    });
-  },
-
-
-  /**
-   * Changes format from Object to Array
-   *
-   * {
-   *  'core-site': 'version1',
-   *  'hdfs-site': 'version1',
-   *  ...
-   * }
-   *
-   * to
-   *
-   * [
-   *  {
-   *    siteName: 'core-site',
-   *    tagName: 'version1',
-   *    newTageName: null
-   *  },
-   *  ...
-   * ]
-   *
-   * set tagnames for configuration of the *-site.xml
-   * @private
-   * @method setServiceConfigTags
-   */
-  setServiceConfigTags: function (desiredConfigsSiteTags) {
-    var newServiceConfigTags = [];
-    for (var index in desiredConfigsSiteTags) {
-      newServiceConfigTags.pushObject({
-        siteName: index,
-        tagName: desiredConfigsSiteTags[index],
-        newTagName: null
-      }, this);
-    }
-    this.set('serviceConfigTags', newServiceConfigTags);
-  },
 
   /**
    * Generate configuration object that will be rendered
diff --git a/ambari-web/app/controllers/main/admin/service_auto_start.js b/ambari-web/app/controllers/main/admin/service_auto_start.js
index 80b6e50..66e4c9d 100644
--- a/ambari-web/app/controllers/main/admin/service_auto_start.js
+++ b/ambari-web/app/controllers/main/admin/service_auto_start.js
@@ -112,35 +112,16 @@ App.MainAdminServiceAutoStartController = Em.Controller.extend({
   },
 
   load: function() {
-    this.loadClusterConfig().done((data) => {
-      const tag = [
-        {
-          siteName: 'cluster-env',
-          tagName: data.Clusters.desired_configs['cluster-env'].tag,
-          newTagName: null
-        }
-      ];
-      App.router.get('configurationController').getConfigsByTags(tag).done((data) => {
-        this.set('clusterConfigs', data[0].properties);
-        this.set('isGeneralRecoveryEnabled', data[0].properties.recovery_enabled === 'true');
-        this.set('isGeneralRecoveryEnabledCached', this.get('isGeneralRecoveryEnabled'));
-        this.loadComponentsConfigs().then(() => {
-          this.set('isLoaded', true);
-        });
+    App.router.get('configurationController').getCurrentConfigsBySites(['cluster-env']).done((data) => {
+      this.set('clusterConfigs', data[0].properties);
+      this.set('isGeneralRecoveryEnabled', data[0].properties.recovery_enabled === 'true');
+      this.set('isGeneralRecoveryEnabledCached', this.get('isGeneralRecoveryEnabled'));
+      this.loadComponentsConfigs().then(() => {
+        this.set('isLoaded', true);
       });
     });
   },
 
-  loadClusterConfig: function () {
-    return App.ajax.send({
-      name: 'config.tags.site',
-      sender: this,
-      data: {
-        site: 'cluster-env'
-      }
-    });
-  },
-
   loadComponentsConfigs: function () {
     return App.ajax.send({
       name: 'components.get_category',
diff --git a/ambari-web/app/controllers/main/service/info/summary.js b/ambari-web/app/controllers/main/service/info/summary.js
index 1f7e4e4..26f524b 100644
--- a/ambari-web/app/controllers/main/service/info/summary.js
+++ b/ambari-web/app/controllers/main/service/info/summary.js
@@ -226,21 +226,14 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
    */
   setHiveEndPointsValue: function() {
     var self = this;
-    var tags = [
-      {
-        siteName: 'hive-site'
-      },
-      {
-        siteName: 'hive-interactive-site'
-      }
-    ];
+    const sites = ['hive-site', 'hive-interactive-site'];
 
     var siteToComponentMap = {
       'hive-site': 'HIVE_SERVER',
       'hive-interactive-site': 'HIVE_SERVER_INTERACTIVE'
     };
 
-    App.router.get('configurationController').getConfigsByTags(tags).done(function (configs) {
+    App.router.get('configurationController').getCurrentConfigsBySites(sites).done(function (configs) {
 
       var hiveSiteIndex =  configs.map(function(item){
         return item.type;
diff --git a/ambari-web/app/controllers/main/service/item.js b/ambari-web/app/controllers/main/service/item.js
index 1802152..f5c62b3 100644
--- a/ambari-web/app/controllers/main/service/item.js
+++ b/ambari-web/app/controllers/main/service/item.js
@@ -198,53 +198,28 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow
    * Load configurations for implicit usage for service actions
    * not related to configs displayed on Configs page
    */
-  loadConfigs: function(){
+  loadConfigs: function() {
     this.set('isServiceConfigsLoaded', false);
     this.set('stepConfigs', []);
-    App.ajax.send({
-      name: 'config.tags',
-      sender: this,
-      success: 'onLoadConfigsTags',
-      error: 'onTaskError'
-    });
-  },
-
-  /**
-   * Load all configs for sites from <code>serviceConfigsMap</code> for current service
-   * @param data
-   */
-  onLoadConfigsTags: function (data) {
-    var self = this;
-    App.get('router.mainController.isLoading').call(App.get('router.clusterController'), 'isConfigsPropertiesLoaded').done(function () {
-      var sitesToLoad = self.get('sitesToLoad'),
-        allConfigs = [],
-        loadedSites = data.Clusters.desired_configs,
-        siteTagsToLoad = [];
-      for (var site in loadedSites) {
-        if (sitesToLoad.contains(site)) {
-          siteTagsToLoad.push({
-            siteName: site,
-            tagName: loadedSites[site].tag
-          });
-        }
-      }
-      App.router.get('configurationController').getConfigsByTags(siteTagsToLoad).done(function (configs) {
-        configs.forEach(function (site) {
-          self.get('configs')[site.type] = site.properties;
+    App.get('router.mainController.isLoading').call(App.get('router.clusterController'), 'isConfigsPropertiesLoaded').done(() => {
+      App.router.get('configurationController').getCurrentConfigsBySites(this.get('sitesToLoad')).done((configs) => {
+        let allConfigs = [];
+        configs.forEach((site) => {
+          this.get('configs')[site.type] = site.properties;
           allConfigs = allConfigs.concat(App.config.getConfigsFromJSON(site, true));
         });
 
-        self.get('configDependentServiceNames').forEach(function(serviceName) {
+        this.get('configDependentServiceNames').forEach((serviceName) => {
           var configTypes = App.StackService.find(serviceName).get('configTypeList');
           var configsByService = allConfigs.filter(function (c) {
             return configTypes.contains(App.config.getConfigTagFromFileName(c.get('filename')));
           });
           if (App.config.get('preDefinedServiceConfigs').someProperty('serviceName', serviceName)) {
-            self.get('stepConfigs').pushObject(App.config.createServiceConfig(serviceName, [], configsByService));
+            this.get('stepConfigs').pushObject(App.config.createServiceConfig(serviceName, [], configsByService));
           }
         });
 
-        self.set('isServiceConfigsLoaded', true);
+        this.set('isServiceConfigsLoaded', true);
       });
     });
   },
diff --git a/ambari-web/app/mixins/common/configs/enhanced_configs.js b/ambari-web/app/mixins/common/configs/enhanced_configs.js
index fbccb3b..78902e8 100644
--- a/ambari-web/app/mixins/common/configs/enhanced_configs.js
+++ b/ambari-web/app/mixins/common/configs/enhanced_configs.js
@@ -250,7 +250,7 @@ App.EnhancedConfigsMixin = Em.Mixin.create(App.ConfigWithOverrideRecommendationP
    */
   loadAdditionalSites: function(sites, stepConfigs, recommendations, dataToSend, onComplete) {
     var self = this;
-    App.config.getConfigsByTypes(sites).done(function (configs) {
+    App.router.get('configurationController').getCurrentConfigsBySites(sites).done(function (configs) {
       stepConfigs = stepConfigs.concat(configs);
 
       self.addRecommendationRequestParams(recommendations, dataToSend, stepConfigs);
diff --git a/ambari-web/app/mixins/common/serverValidator.js b/ambari-web/app/mixins/common/serverValidator.js
index c44a6be..f7b65eb 100644
--- a/ambari-web/app/mixins/common/serverValidator.js
+++ b/ambari-web/app/mixins/common/serverValidator.js
@@ -226,7 +226,7 @@ App.ServerValidatorMixin = Em.Mixin.create({
     var dfd = $.Deferred();
     // check if we have configs from 'cluster-env', if not, then load them, as they are mandatory for validation request
     if (!serviceConfigs.findProperty('serviceName', 'MISC')) {
-      App.config.getConfigsByTypes([{site: 'cluster-env', serviceName: 'MISC'}]).done(function(configs) {
+      App.router.get('configurationController').getCurrentConfigsBySites(['cluster-env']).done(function(configs) {
         dfd.resolve(blueprintUtils.buildConfigsJSON(serviceConfigs.concat(configs)));
       });
     } else {
diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js
index e827fe5..5eac067 100644
--- a/ambari-web/app/routes/main.js
+++ b/ambari-web/app/routes/main.js
@@ -251,21 +251,19 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
         connectOutlets: function (router, context) {
           router.get('mainController').dataLoading().done(function() {
             var controller = router.get('mainHostDetailsController');
-            var tags =[{
-            	siteName: 'hive-env'
-            	}];
+            var tags = ['hive-env'];
             if ( App.Service.find().mapProperty('serviceName').contains('OOZIE')) {
               controller.loadConfigs('loadOozieConfigs');
               controller.isOozieConfigLoaded.always(function () {
                 if(App.Service.find().mapProperty('serviceName').contains('HIVE')){
-                  App.router.get('configurationController').getConfigsByTags(tags).always(function () {
+                  App.router.get('configurationController').getCurrentConfigsBySites(tags).always(function () {
             	    controller.connectOutlet('mainHostSummary');
             	  });
             	} else
               controller.connectOutlet('mainHostSummary');
               });
             } else if(App.Service.find().mapProperty('serviceName').contains('HIVE')) {
-              App.router.get('configurationController').getConfigsByTags(tags).always(function () {
+              App.router.get('configurationController').getCurrentConfigsBySites(tags).always(function () {
                 controller.connectOutlet('mainHostSummary');
               });
             } else {
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index 5419bcc..cd2a224 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -1316,33 +1316,6 @@ App.config = Em.Object.create({
   },
 
   /**
-   * Load cluster-env configs mapped to array
-   * @return {*|{then}}
-   */
-  getConfigsByTypes: function (sites) {
-    const dfd = $.Deferred();
-    if (_.isEqual(sites.mapProperty('site'), ['cluster-env'])) {
-      // if only cluster-env requested the use cached data
-      dfd.resolve(this.getMappedConfigs([App.router.get('clusterController.clusterEnv')], sites));
-    } else {
-      App.ajax.send({
-        name: 'config.tags.selected',
-        sender: this,
-        data: {
-          tags: sites.mapProperty('site').join(',')
-        }
-      }).done((data) => {
-        App.router.get('configurationController').getConfigsByTags(data.items.map(function (item) {
-          return {siteName: item.type, tagName: item.tag};
-        })).done((configs) => {
-          dfd.resolve(this.getMappedConfigs(configs, sites));
-        });
-      });
-    }
-    return dfd.promise();
-  },
-
-  /**
    *
    * @param configs
    * @param sites
diff --git a/ambari-web/app/utils/db.js b/ambari-web/app/utils/db.js
index f45ba24..2faffb4 100644
--- a/ambari-web/app/utils/db.js
+++ b/ambari-web/app/utils/db.js
@@ -22,6 +22,7 @@ var InitialData = {
     'loginName': '',
     'authenticated': false,
     'configs': [],
+    'tags': [],
     'tables': {
       'filterConditions': {},
       'displayLength': {},
@@ -268,6 +269,10 @@ App.db.setConfigs = function (configs) {
   App.db.set('app', 'configs', configs);
 };
 
+App.db.setTags = function (tags) {
+  App.db.set('app', 'tags', tags);
+};
+
 /**
  * Set current step value for specified Wizard Type
  * @param wizardType
@@ -525,6 +530,10 @@ App.db.getConfigs = function () {
   return App.db.get('app', 'configs');
 };
 
+App.db.getTags = function () {
+  return App.db.get('app', 'tags');
+};
+
 App.db.getReassignMasterWizardReassignHosts = function () {
   return App.db.get('ReassignMaster', 'reassignHosts');
 };
diff --git a/ambari-web/app/views/common/quick_view_link_view.js b/ambari-web/app/views/common/quick_view_link_view.js
index 0c37b56..ffdeb2e 100644
--- a/ambari-web/app/views/common/quick_view_link_view.js
+++ b/ambari-web/app/views/common/quick_view_link_view.js
@@ -56,11 +56,6 @@ App.QuickLinksView = Em.View.extend({
   quickLinks: [],
 
   /**
-   * @type {string[]}
-   */
-  actualTags: [],
-
-  /**
    * @type {object[]}
    */
   configProperties: [],
@@ -98,7 +93,6 @@ App.QuickLinksView = Em.View.extend({
 
   willDestroyElement: function () {
     this.get('configProperties').clear();
-    this.get('actualTags').clear();
     this.get('quickLinks').clear();
     this.get('requiredSiteNames').clear();
   },
@@ -113,7 +107,10 @@ App.QuickLinksView = Em.View.extend({
    */
   setQuickLinks: function () {
     if (App.get('router.clusterController.isServiceMetricsLoaded')) {
-      this.loadTags();
+      this.setConfigProperties().done((configProperties) => {
+        this.get('configProperties').pushObjects(configProperties);
+        this.getQuickLinksHosts();
+      });
     }
   }.observes(
     'App.currentStackVersionNumber',
@@ -122,52 +119,7 @@ App.QuickLinksView = Em.View.extend({
     'App.router.clusterController.quickLinksUpdateCounter'
   ),
 
-  /**
-   * call for configuration tags
-   *
-   * @returns {$.ajax}
-   */
-  loadTags: function () {
-    return App.ajax.send({
-      name: 'config.tags',
-      sender: this,
-      success: 'loadTagsSuccess',
-      error: 'loadTagsError'
-    });
-  },
-
-  /**
-   * Success-callback for load-tags request
-   *
-   * @param {object} data
-   * @method loadTagsSuccess
-   */
-  loadTagsSuccess: function (data) {
-    this.get('actualTags').clear();
-    var self = this;
-    var tags = Object.keys(data.Clusters.desired_configs).map(function (prop) {
-      return Em.Object.create({
-        siteName: prop,
-        tagName: data.Clusters.desired_configs[prop].tag
-      });
-    });
-    this.get('actualTags').pushObjects(tags);
-    this.setConfigProperties().done(function (configProperties) {
-      self.get('configProperties').pushObjects(configProperties);
-      self.getQuickLinksHosts();
-    });
-  },
-
-  /**
-   * Error-callback for load-tags request
-   *
-   * @method loadTagsError
-   */
-  loadTagsError: function () {
-    this.getQuickLinksHosts();
-  },
-
-  /**
+   /**
    * Request for quick-links config
    *
    * @returns {$.ajax}
@@ -334,11 +286,7 @@ App.QuickLinksView = Em.View.extend({
    */
   setConfigProperties: function () {
     this.get('configProperties').clear();
-    var requiredSiteNames = this.get('requiredSiteNames');
-    var tags = this.get('actualTags').filter(function (tag) {
-      return requiredSiteNames.contains(tag.siteName);
-    });
-    return App.router.get('configurationController').getConfigsByTags(tags);
+    return App.router.get('configurationController').getCurrentConfigsBySites(this.get('requiredSiteNames'));
   },
 
   /**
diff --git a/ambari-web/test/controllers/global/cluster_controller_test.js b/ambari-web/test/controllers/global/cluster_controller_test.js
index fcbad62..839fbbb 100644
--- a/ambari-web/test/controllers/global/cluster_controller_test.js
+++ b/ambari-web/test/controllers/global/cluster_controller_test.js
@@ -846,12 +846,10 @@ describe('App.clusterController', function () {
       sinon.stub(App.router.get('errorsHandlerController'), 'loadErrorLogs');
       sinon.stub(App.router.get('wizardWatcherController'), 'getUser');
       sinon.stub(App.db, 'setFilterConditions');
-      sinon.stub(App.router.get('updateController'), 'updateClusterEnv');
       controller.set('isLoaded', false);
     });
 
     afterEach(function() {
-      App.router.get('updateController').updateClusterEnv.restore();
       App.db.setFilterConditions.restore();
       App.router.get('wizardWatcherController').getUser.restore();
       App.router.get('errorsHandlerController').loadErrorLogs.restore();
@@ -909,11 +907,6 @@ describe('App.clusterController', function () {
       expect(controller.loadClusterDataToModel.calledOnce).to.be.true;
     });
 
-    it('updateClusterEnv should be called', function() {
-      controller.loadClusterData();
-      expect(App.router.get('updateController').updateClusterEnv.calledOnce).to.be.true;
-    });
-
     it('startPolling should be called', function() {
       controller.set('isLoaded', true);
       controller.loadClusterData();
@@ -1031,16 +1024,24 @@ describe('App.clusterController', function () {
 
     beforeEach(function() {
       sinon.stub(App.config, 'loadConfigsFromStack').returns({
-        complete: Em.clb
+        always: Em.clb
       });
       sinon.stub(App.config, 'loadClusterConfigsFromStack').returns({
-        complete: Em.clb
+        always: Em.clb
+      });
+      sinon.stub(App.router.get('configurationController'), 'updateConfigTags').returns({
+        always: Em.clb
+      });
+      sinon.stub(App.router.get('updateController'), 'updateClusterEnv').returns({
+        always: Em.clb
       });
     });
 
     afterEach(function() {
       App.config.loadClusterConfigsFromStack.restore();
       App.config.loadConfigsFromStack.restore();
+      App.router.get('configurationController').updateConfigTags.restore();
+      App.router.get('updateController').updateClusterEnv.restore();
     });
 
     it('App.config.loadConfigsFromStack should be called', function() {
@@ -1053,6 +1054,16 @@ describe('App.clusterController', function () {
       expect(App.config.loadClusterConfigsFromStack.calledOnce).to.be.true;
     });
 
+    it('updateConfigTags should be called', function() {
+      controller.loadConfigProperties();
+      expect(App.router.get('configurationController').updateConfigTags.calledOnce).to.be.true;
+    });
+
+    it('updateClusterEnv should be called', function() {
+      controller.loadConfigProperties();
+      expect(App.router.get('updateController').updateClusterEnv.calledOnce).to.be.true;
+    });
+
     it('isConfigsPropertiesLoaded should be true', function() {
       controller.loadConfigProperties();
       expect(controller.get('isConfigsPropertiesLoaded')).to.be.true;
diff --git a/ambari-web/test/controllers/global/configuration_controller_test.js b/ambari-web/test/controllers/global/configuration_controller_test.js
index 11dfe0d..1f86c1c 100644
--- a/ambari-web/test/controllers/global/configuration_controller_test.js
+++ b/ambari-web/test/controllers/global/configuration_controller_test.js
@@ -294,4 +294,113 @@ describe('App.ConfigurationController', function () {
       ]));
     });
   });
+
+  describe('#getCurrentConfigsBySites', function() {
+    beforeEach(function() {
+      sinon.stub(controller, 'getConfigTags').returns({
+        done: Em.clb
+      });
+      sinon.stub(controller, 'getConfigsByTags').returns({
+        done: Em.clb
+      });
+    });
+    afterEach(function() {
+      controller.getConfigTags.restore();
+      controller.getConfigsByTags.restore();
+    });
+
+    it('getConfigTags should be called', function() {
+      controller.getCurrentConfigsBySites();
+      expect(controller.getConfigTags.calledOnce).to.be.true;
+    });
+
+    it('getConfigsByTags should be called', function() {
+      controller.getCurrentConfigsBySites();
+      expect(controller.getConfigsByTags.calledOnce).to.be.true;
+    });
+  });
+
+  describe('#getConfigTags', function() {
+    beforeEach(function() {
+      sinon.stub(controller, 'extractTagsFromLocalDB');
+      sinon.stub(controller, 'updateConfigTags').returns({
+        always: Em.clb
+      });
+      this.mock = sinon.stub(App.db, 'getTags');
+    });
+    afterEach(function() {
+      controller.extractTagsFromLocalDB.restore();
+      controller.updateConfigTags.restore();
+      this.mock.restore();
+    });
+
+    it('should get configs from localDB', function() {
+      this.mock.returns([{}]);
+      controller.getConfigTags();
+      expect(controller.extractTagsFromLocalDB.calledOnce).to.be.true;
+    });
+
+    it('should load configs from server', function() {
+      this.mock.returns([]);
+      controller.getConfigTags();
+      expect(controller.updateConfigTags.calledOnce).to.be.true;
+      expect(controller.extractTagsFromLocalDB.calledOnce).to.be.true;
+    });
+  });
+
+  describe('#extractTagsFromLocalDB', function() {
+    beforeEach(function() {
+      sinon.stub(App.db, 'getTags').returns([{siteName: 'site1'}, {siteName: 'site2'}]);
+    });
+    afterEach(function() {
+      App.db.getTags.restore();
+    });
+
+    it('should return all tags', function() {
+      expect(controller.extractTagsFromLocalDB([])).to.be.eql([
+        {siteName: 'site1'},
+        {siteName: 'site2'}
+      ]);
+    });
+
+    it('should return specified tags', function() {
+      expect(controller.extractTagsFromLocalDB(['site1'])).to.be.eql([
+        {siteName: 'site1'}
+      ]);
+    });
+  });
+
+  describe('#updateConfigTags', function() {
+    beforeEach(function() {
+      sinon.stub(controller, 'loadConfigTags').returns({
+        done: function(callback) {
+          callback({
+            Clusters: {
+              desired_configs: {
+                "site1": {
+                  tag: 1
+                }
+              }
+            }
+          })
+        }
+      });
+      sinon.stub(App.db, 'setTags');
+    });
+    afterEach(function() {
+      controller.loadConfigTags.restore();
+      App.db.setTags.restore();
+    });
+
+    it('App.db.setTags should be called', function() {
+      controller.updateConfigTags();
+      expect(App.db.setTags.calledWith([
+        {
+          siteName: 'site1',
+          tagName: 1
+        }
+      ])).to.be.true;
+    });
+  });
+
 });
\ No newline at end of file
diff --git a/ambari-web/test/controllers/global/update_controller_test.js b/ambari-web/test/controllers/global/update_controller_test.js
index 6165af9..26b1067 100644
--- a/ambari-web/test/controllers/global/update_controller_test.js
+++ b/ambari-web/test/controllers/global/update_controller_test.js
@@ -528,17 +528,24 @@ describe('App.UpdateController', function () {
     });
   });
 
-  describe('#makeCallForClusterEnv', function() {
+  describe('#configsChangedHandler', function() {
     beforeEach(function() {
       sinon.stub(c, 'updateClusterEnv');
+      sinon.stub(App.router.get('configurationController'), 'updateConfigTags');
     });
     afterEach(function() {
       c.updateClusterEnv.restore();
+      App.router.get('configurationController').updateConfigTags.restore();
     });
 
     it('updateClusterEnv should be called', function() {
-      c.makeCallForClusterEnv({configs: [{type: 'cluster-env'}]});
+      c.configsChangedHandler({configs: [{type: 'cluster-env'}]});
       expect(c.updateClusterEnv.calledOnce).to.be.true;
     });
+
+    it('updateConfigTags should be called', function() {
+      c.configsChangedHandler({configs: [{type: 'cluster-env'}]});
+      expect(App.router.get('configurationController').updateConfigTags.calledOnce).to.be.true;
+    });
   });
 });
diff --git a/ambari-web/test/controllers/main/admin/service_auto_start_test.js b/ambari-web/test/controllers/main/admin/service_auto_start_test.js
index 2fb1894..248bf44 100644
--- a/ambari-web/test/controllers/main/admin/service_auto_start_test.js
+++ b/ambari-web/test/controllers/main/admin/service_auto_start_test.js
@@ -67,8 +67,9 @@ describe('App.MainAdminServiceAutoStartController', function() {
   });
 
   describe('#load', function() {
-    var mock = {
-      getConfigsByTags: sinon.stub().returns({
+
+    beforeEach(function() {
+      sinon.stub(App.router.get('configurationController'), 'getCurrentConfigsBySites').returns({
         done: function(callback) {
           callback([
             {
@@ -78,31 +79,14 @@ describe('App.MainAdminServiceAutoStartController', function() {
             }
           ]);
         }
-      })
-    };
-    beforeEach(function() {
-      sinon.stub(controller, 'loadClusterConfig').returns({
-        done: function(callback) {
-          callback({
-            Clusters: {
-              desired_configs: {
-                'cluster-env': {
-                  tag: 1
-                }
-              }
-            }
-          });
-        }
       });
-      sinon.stub(App.router, 'get').returns(mock);
       sinon.stub(controller, 'loadComponentsConfigs').returns({
         then: Em.clb
       });
       controller.load();
     });
     afterEach(function() {
-      controller.loadClusterConfig.restore();
-      App.router.get.restore();
+      App.router.get('configurationController').getCurrentConfigsBySites.restore();
       controller.loadComponentsConfigs.restore();
     });
 
@@ -125,21 +109,6 @@ describe('App.MainAdminServiceAutoStartController', function() {
     });
   });
 
-  describe('#loadClusterConfig()', function() {
-
-    it('App.ajax.send should be called', function() {
-      controller.loadClusterConfig();
-      var args = testHelpers.findAjaxRequest('name', 'config.tags.site');
-      expect(args[0]).to.be.eql({
-        name: 'config.tags.site',
-        sender: controller,
-        data: {
-          site: 'cluster-env'
-        }
-      });
-    });
-  });
-
   describe('#loadComponentsConfigs()', function() {
 
     it('App.ajax.send should be called', function() {
diff --git a/ambari-web/test/mixins/common/configs/enhanced_configs_test.js b/ambari-web/test/mixins/common/configs/enhanced_configs_test.js
index 98f3182..1cf7620 100644
--- a/ambari-web/test/mixins/common/configs/enhanced_configs_test.js
+++ b/ambari-web/test/mixins/common/configs/enhanced_configs_test.js
@@ -599,7 +599,7 @@ describe('App.EnhancedConfigsMixin', function () {
   describe("#loadAdditionalSites()", function () {
 
     beforeEach(function() {
-      sinon.stub(App.config, 'getConfigsByTypes').returns({
+      sinon.stub(App.router.get('configurationController'), 'getCurrentConfigsBySites').returns({
         done: function(callback) {callback([]);}
       });
       sinon.stub(mixin, 'addRecommendationRequestParams');
@@ -608,13 +608,13 @@ describe('App.EnhancedConfigsMixin', function () {
     });
 
     afterEach(function() {
-      App.config.getConfigsByTypes.restore();
+      App.router.get('configurationController').getCurrentConfigsBySites.restore();
       mixin.addRecommendationRequestParams.restore();
       mixin.getRecommendationsRequest.restore();
     });
 
-    it("App.config.getConfigsByTypes should be called", function() {
-      expect(App.config.getConfigsByTypes.calledOnce).to.be.true;
+    it("getCurrentConfigsBySites should be called", function() {
+      expect(App.router.get('configurationController').getCurrentConfigsBySites.calledOnce).to.be.true;
     });
 
     it("addRecommendationRequestParams should be called", function() {
diff --git a/ambari-web/test/views/common/quick_link_view_test.js b/ambari-web/test/views/common/quick_link_view_test.js
index 15bd07c..a23b831 100644
--- a/ambari-web/test/views/common/quick_link_view_test.js
+++ b/ambari-web/test/views/common/quick_link_view_test.js
@@ -58,7 +58,6 @@ describe('App.QuickViewLinks', function () {
     beforeEach(function () {
       quickViewLinks.setProperties({
         configProperties: [{}],
-        actualTags: [""],
         quickLinks: [{}]
       });
       quickViewLinks.willDestroyElement();
@@ -68,10 +67,6 @@ describe('App.QuickViewLinks', function () {
       expect(quickViewLinks.get('configProperties')).to.be.empty;
     });
 
-    it("actualTags empty", function () {
-      expect(quickViewLinks.get('actualTags')).to.be.empty;
-    });
-
     it("quickLinks empty", function () {
       expect(quickViewLinks.get('quickLinks')).to.be.empty;
     });
@@ -79,84 +74,24 @@ describe('App.QuickViewLinks', function () {
 
   describe("#setQuickLinks()", function () {
     beforeEach(function () {
-      this.mock = sinon.stub(App, 'get');
-      sinon.stub(quickViewLinks, 'loadTags', Em.K);
-    });
-    afterEach(function () {
-      this.mock.restore();
-      quickViewLinks.loadTags.restore();
-    });
-    it("data loaded", function () {
-      this.mock.returns(true);
-      quickViewLinks.setQuickLinks();
-      expect(quickViewLinks.loadTags.calledOnce).to.be.true;
-    });
-    it("data not loaded", function () {
-      this.mock.returns(false);
-      quickViewLinks.setQuickLinks();
-      expect(quickViewLinks.loadTags.called).to.be.false;
-    });
-  });
-
-  describe("#loadTags()", function () {
-
-    it("call $.ajax", function () {
-      quickViewLinks.loadTags();
-      var args = testHelpers.findAjaxRequest('name', 'config.tags');
-      expect(args[0]).exists;
-      expect(args[0].sender).to.be.eql(quickViewLinks);
-    });
-  });
-
-  describe("#loadTagsSuccess()", function () {
-    beforeEach(function () {
-      sinon.stub(quickViewLinks, 'setConfigProperties', function () {
-        return {
-          done: Em.clb
-        }
-      });
-      sinon.stub(quickViewLinks, 'getQuickLinksHosts');
-      var data = {
-        Clusters: {
-          desired_configs: {
-            site1: {
-              tag: 'tag1'
-            }
-          }
-        }
+      var mock = {
+        done: Em.clb
       };
-      quickViewLinks.loadTagsSuccess(data);
+      sinon.stub(quickViewLinks, 'setConfigProperties').returns(mock);
+      sinon.stub(quickViewLinks, 'getQuickLinksHosts');
+      sinon.stub(App, 'get').returns(true);
     });
     afterEach(function () {
       quickViewLinks.setConfigProperties.restore();
       quickViewLinks.getQuickLinksHosts.restore();
+      App.get.restore();
     });
-    it("actualTags is valid", function () {
-      expect(quickViewLinks.get('actualTags')[0]).to.eql(Em.Object.create({
-        siteName: 'site1',
-        tagName: 'tag1'
-      }));
-    });
-    it("setConfigProperties is called once", function () {
-      expect(quickViewLinks.setConfigProperties.calledOnce).to.be.true;
-    });
-    it("getQuickLinksHosts is called once", function () {
+    it("getQuickLinksHosts should be called", function () {
+      quickViewLinks.setQuickLinks();
       expect(quickViewLinks.getQuickLinksHosts.calledOnce).to.be.true;
     });
   });
 
-  describe("#loadTagsError()", function () {
-    beforeEach(function () {
-      sinon.stub(quickViewLinks, 'getQuickLinksHosts');
-    });
-    afterEach(function () {
-      quickViewLinks.getQuickLinksHosts.restore();
-    });
-    it("call loadQuickLinksConfigurations", function () {
-      quickViewLinks.loadTagsError();
-      expect(quickViewLinks.getQuickLinksHosts.calledOnce).to.be.true;
-    });
-  });
 
   describe("#loadQuickLinksConfigSuccessCallback()", function () {
     var mock;
@@ -334,20 +269,16 @@ describe('App.QuickViewLinks', function () {
   });
 
   describe("#setConfigProperties()", function () {
-    var mock = {getConfigsByTags: Em.K};
     beforeEach(function () {
-      sinon.stub(App.router, 'get').returns(mock);
-      sinon.spy(mock, 'getConfigsByTags');
+      sinon.stub(App.router.get('configurationController'), 'getCurrentConfigsBySites');
     });
     afterEach(function () {
-      mock.getConfigsByTags.restore();
-      App.router.get.restore();
+      App.router.get('configurationController').getCurrentConfigsBySites.restore();
     });
-    it("getConfigsByTags called with correct data", function () {
-      quickViewLinks.set('actualTags', [{siteName: 'hdfs-site'}]);
+    it("getCurrentConfigsBySites called with correct data", function () {
       quickViewLinks.set('requiredSiteNames', ['hdfs-site']);
       quickViewLinks.setConfigProperties();
-      expect(mock.getConfigsByTags.calledWith([{siteName: 'hdfs-site'}])).to.be.true;
+      expect(App.router.get('configurationController').getCurrentConfigsBySites.calledWith(['hdfs-site'])).to.be.true;
     });
   });
 

-- 
To stop receiving notification emails like this one, please contact
atkach@apache.org.