You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2015/08/25 12:57:27 UTC

[2/2] ambari git commit: AMBARI-12852. FE: step transitions in Add Service Wizard are slow (onechiporenko)

AMBARI-12852. FE: step transitions in Add Service Wizard are slow (onechiporenko)


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

Branch: refs/heads/branch-2.1
Commit: bd92f96505a9c8899a45423612bb9a1730eacd90
Parents: 44488a5
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Tue Aug 25 13:52:51 2015 +0300
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Tue Aug 25 13:56:20 2015 +0300

----------------------------------------------------------------------
 .../main/alerts/alert_instances_controller.js   |   2 +
 ambari-web/app/controllers/wizard.js            |  50 ++++++---
 .../app/controllers/wizard/step6_controller.js  | 108 +++++++++++--------
 ambari-web/app/mixins/common/localStorage.js    |  19 +++-
 .../mixins/wizard/assign_master_components.js   |  33 +++---
 ambari-web/app/utils/db.js                      |  38 +++++++
 .../main/alerts/manage_alert_groups_view.js     |   1 +
 ambari-web/app/views/wizard/step6_view.js       |   2 +-
 .../main/service/add_controller_test.js         |  12 ++-
 ambari-web/test/controllers/wizard_test.js      |  34 +++---
 10 files changed, 204 insertions(+), 95 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/bd92f965/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alerts/alert_instances_controller.js b/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
index 234fba0..c7312a0 100644
--- a/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
+++ b/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
@@ -345,6 +345,8 @@ App.MainAlertInstancesController = Em.Controller.extend({
 
         didInsertElement: function () {
           this.filter();
+          this.addObserver('filteringComplete', this, this.overlayObserver);
+          this.overlayObserver();
           return this._super();
         }
       })

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd92f965/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index b9e863f..9d018c5 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -304,9 +304,11 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
   clearInstallOptions: function () {
     var installOptions = this.getInstallOptions();
     this.set('content.installOptions', installOptions);
-    this.setDBProperty('installOptions', installOptions);
     this.set('content.hosts', {});
-    this.setDBProperty('hosts', {});
+    this.setDBProperties({
+      installOptions: installOptions,
+      hosts: {}
+    });
   },
 
   toObject: function (object) {
@@ -548,9 +550,11 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
   },
 
   clearStorageData: function () {
+    var hash = {};
     this.get('dbPropertiesToClean').forEach(function (key) {
-      this.setDBProperty(key, undefined);
+      hash[key] = undefined;
     }, this);
+    this.setDBProperties(hash);
   },
 
   getInstallOptions: function() {
@@ -601,8 +605,9 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
   },
 
   loadServiceComponentsSuccessCallback: function (jsonData) {
-    var savedSelectedServices = this.getDBProperty('selectedServiceNames');
-    var savedInstalledServices = this.getDBProperty('installedServiceNames');
+    var props = this.getDBProperties(['selectedServiceNames', 'installedServiceNames']);
+    var savedSelectedServices = props.selectedServiceNames;
+    var savedInstalledServices = props.installedServiceNames;
     this.set('content.selectedServiceNames', savedSelectedServices);
     this.set('content.installedServiceNames', savedInstalledServices);
     if (!savedSelectedServices) {
@@ -644,8 +649,9 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
    * Load config groups from local DB
    */
   loadServiceConfigGroups: function () {
-    var serviceConfigGroups = this.getDBProperty('serviceConfigGroups'),
-      hosts = this.getDBProperty('hosts'),
+    var props = this.getDBProperties(['serviceConfigGroups', 'hosts']);
+    var serviceConfigGroups = props.serviceConfigGroups,
+      hosts = props.hosts,
       host_names = Em.keys(hosts);
     if (Em.isNone(serviceConfigGroups)) {
       serviceConfigGroups = [];
@@ -752,13 +758,13 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
 
     hosts.forEach(function (host) {
 
-      var checkboxes = host.get('checkboxes');
+      var checkboxes = host.checkboxes;
       headers.forEach(function (header) {
         var cb = checkboxes.findProperty('title', header.get('label'));
-        if (cb.get('checked')) {
+        if (cb.checked) {
           formattedHosts.get(header.get('name')).push({
             group: 'Default',
-            isInstalled: cb.get('isInstalled'),
+            isInstalled: cb.isInstalled,
             host_id: dbHosts[host.hostName].id
           });
         }
@@ -850,14 +856,25 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
   saveServiceConfigProperties: function (stepController) {
     var serviceConfigProperties = [];
     var fileNamesToUpdate = [];
+    var installedServiceNames = stepController.get('installedServiceNames') || [];
+    var installedServiceNamesMap = {};
+    var notAllowed = ['masterHost', 'masterHosts', 'slaveHosts', 'slaveHost'];
+    installedServiceNames.forEach(function(name) {
+      installedServiceNamesMap[name] = true;
+    });
     stepController.get('stepConfigs').forEach(function (_content) {
 
       if (_content.serviceName === 'YARN') {
         _content.set('configs', App.config.textareaIntoFileConfigs(_content.get('configs'), 'capacity-scheduler.xml'));
       }
-
       _content.get('configs').forEach(function (_configProperties) {
-        var configProperty = App.config.createDefaultConfig(_configProperties.get('name'), _configProperties.get('serviceName'), _configProperties.get('filename'), _configProperties.get('isUserProperty'), {value: _configProperties.get('value')});
+        var configProperty = App.config.createDefaultConfig(
+          _configProperties.get('name'),
+          _configProperties.get('serviceName'),
+          _configProperties.get('filename'),
+          _configProperties.get('isUserProperty'),
+          {value: _configProperties.get('value')}
+        );
         configProperty = App.config.mergeStaticProperties(configProperty, _configProperties, ['name', 'filename']);
 
         if (this.isExcludedConfig(configProperty)) {
@@ -866,11 +883,10 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
         serviceConfigProperties.push(configProperty);
       }, this);
       // check for configs that need to update for installed services
-      if (stepController.get('installedServiceNames') && stepController.get('installedServiceNames').contains(_content.get('serviceName'))) {
+      if (installedServiceNames[_content.get('serviceName')]) {
         // get only modified configs
         var configs = _content.get('configs').filter(function (config) {
           if (config.get('isNotDefaultValue') || (config.get('savedValue') === null)) {
-            var notAllowed = ['masterHost', 'masterHosts', 'slaveHosts', 'slaveHost'];
             return !notAllowed.contains(config.get('displayType')) && !!config.filename;
           }
           return false;
@@ -881,9 +897,11 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
         }
       }
     }, this);
-    this.setDBProperty('serviceConfigProperties', serviceConfigProperties);
+    this.setDBProperties({
+      fileNamesToUpdate: fileNamesToUpdate,
+      serviceConfigProperties: serviceConfigProperties
+    });
     this.set('content.serviceConfigProperties', serviceConfigProperties);
-    this.setDBProperty('fileNamesToUpdate', fileNamesToUpdate);
   },
 
   isExcludedConfig: function (configProperty) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd92f965/ambari-web/app/controllers/wizard/step6_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step6_controller.js b/ambari-web/app/controllers/wizard/step6_controller.js
index 893ec24..26b9f76 100644
--- a/ambari-web/app/controllers/wizard/step6_controller.js
+++ b/ambari-web/app/controllers/wizard/step6_controller.js
@@ -136,14 +136,14 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
    * true if validation has any error message (general or host specific)
    */
   anyErrors: function() {
-    return this.get('anyGeneralErrors') || this.get('hosts').some(function(h) { return h.get('errorMessages.length') > 0; });
+    return this.get('anyGeneralErrors') || this.get('hosts').some(function(h) { return h.errorMessages.length > 0; });
   }.property('anyGeneralErrors', 'hosts.@each.errorMessages'),
 
   /**
    * true if validation has any warning message (general or host specific)
    */
   anyWarnings: function() {
-    return this.get('anyGeneralWarnings') || this.get('hosts').some(function(h) { return h.get('warnMessages.length') > 0; });
+    return this.get('anyGeneralWarnings') || this.get('hosts').some(function(h) { return h.warnMessages.length > 0; });
   }.property('anyGeneralWarnings', 'hosts.@each.warnMessages'),
 
   openSlavesAndClientsIssues: function () {
@@ -173,9 +173,9 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
       headersMap[header.name] = true;
     });
     hosts.forEach(function (host) {
-      host.get('checkboxes').forEach(function (checkbox) {
-        if (headersMap[checkbox.get('component')]) {
-          headersMap[checkbox.get('component')] = !checkbox.get('checked');
+      host.checkboxes.forEach(function (checkbox) {
+        if (headersMap[checkbox.component]) {
+          headersMap[checkbox.component] = !checkbox.checked;
         }
       });
     });
@@ -191,7 +191,7 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
       hosts.forEach(function (host) {
         isError = false;
         headers.forEach(function (header) {
-          isError |= host.get('checkboxes').findProperty('title', header.get('label')).checked;
+          isError |= host.checkboxes.findProperty('title', header.get('label')).checked;
         });
         isError = !isError;
         if (!isError) {
@@ -246,9 +246,9 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
    */
   setAllNodes: function (component, checked) {
     this.get('hosts').forEach(function (host) {
-      host.get('checkboxes').filterProperty('isInstalled', false).forEach(function (checkbox) {
-        if (checkbox.get('component') === component) {
-          checkbox.set('checked', checked);
+      host.checkboxes.filterProperty('isInstalled', false).forEach(function (checkbox) {
+        if (checkbox.component === component) {
+          Em.set(checkbox, 'checked', checked);
         }
       });
     });
@@ -268,10 +268,10 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
       var allTrue = true;
       var allFalse = true;
       hosts.forEach(function (host) {
-        host.get('checkboxes').forEach(function (checkbox) {
-          if (checkbox.get('component') === component && !checkbox.get('isInstalled')) {
-            allTrue = allTrue && checkbox.get('checked');
-            allFalse = allFalse && !checkbox.get('checked');
+        host.checkboxes.forEach(function (checkbox) {
+          if (checkbox.component === component && !checkbox.isInstalled) {
+            allTrue = allTrue && checkbox.checked;
+            allFalse = allFalse && !checkbox.checked;
           }
         });
       });
@@ -361,26 +361,28 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
     var hostsObj = [],
       masterHosts = [],
       headers = this.get('headers'),
-      masterHostNames = this.get('content.masterComponentHosts').mapProperty('hostName').uniq();
+      masterHostNames = this.get('content.masterComponentHosts').mapProperty('hostName').uniq(),
+      masterHostNamesMap = {};
+    masterHostNames.forEach(function(hostName) {
+      masterHostNamesMap[hostName] = true;
+    });
 
     this.getHostNames().forEach(function (_hostName) {
-      var hasMaster = masterHostNames.contains(_hostName);
+      var hasMaster = masterHostNamesMap[_hostName];
 
-      var obj = Em.Object.create({
+      var obj = {
         hostName: _hostName,
         hasMaster: hasMaster,
-        checkboxes: []
-      });
-
-      headers.forEach(function (header) {
-        obj.checkboxes.pushObject(Em.Object.create({
-          component: header.name,
-          title: header.label,
-          checked: false,
-          isInstalled: false,
-          isDisabled: header.get('isDisabled')
-        }));
-      });
+        checkboxes: headers.map(function (header) {
+          return{
+            component: header.name,
+            title: header.label,
+            checked: false,
+            isInstalled: false,
+            isDisabled: header.get('isDisabled')
+          };
+        })
+      };
 
       if (hasMaster) {
         masterHosts.pushObject(obj)
@@ -426,7 +428,7 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
       var clientComponents = App.get('components.clients');
 
       hostsObj.forEach(function (host) {
-        var checkboxes = host.get('checkboxes');
+        var checkboxes = host.checkboxes;
         checkboxes.forEach(function (checkbox) {
           var recommended = componentHostPairs.some(function (pair) {
             var componentMatch = pair.component === checkbox.component;
@@ -439,14 +441,24 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
         });
       });
     } else {
+
+      var slaveComponentsMap = {};
+      slaveComponents.forEach(function(slave) {
+        slaveComponentsMap[Em.get(slave, 'componentName')] = slave;
+      });
+      var hostsObjMap = {};
+      hostsObj.forEach(function(host) {
+        hostsObjMap[Em.get(host, 'hostName')] = host;
+      });
+
       this.get('headers').forEach(function (header) {
-        var nodes = slaveComponents.findProperty('componentName', header.get('name'));
+        var nodes = slaveComponentsMap[header.get('name')];
         if (nodes) {
           nodes.hosts.forEach(function (_node) {
-            var node = hostsObj.findProperty('hostName', _node.hostName);
+            var node = hostsObjMap[_node.hostName];
             if (node) {
-              node.get('checkboxes').findProperty('title', header.get('label')).set('checked', true);
-              node.get('checkboxes').findProperty('title', header.get('label')).set('isInstalled', _node.isInstalled);
+              Em.set(node.checkboxes.findProperty('title', header.get('label')), 'checked', true);
+              Em.set(node.checkboxes.findProperty('title', header.get('label')), 'isInstalled', _node.isInstalled);
             }
           });
         }
@@ -465,9 +477,9 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
     if (!this.get('isClientsSet')) {
       var nonMasterHost = hostsObj.findProperty('hasMaster', false);
       var clientHost = !!nonMasterHost ? nonMasterHost : hostsObj[hostsObj.length - 1]; // last host
-      var clientCheckBox = clientHost.get('checkboxes').findProperty('component', 'CLIENT');
+      var clientCheckBox = clientHost.checkboxes.findProperty('component', 'CLIENT');
       if (clientCheckBox) {
-        clientCheckBox.set('checked', true);
+        Em.set(clientCheckBox, 'checked', true);
       }
       this.set('isClientsSet', true);
     }
@@ -625,24 +637,28 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
         });
       });
       if (host) {
-        host.set('anyMessage', true);
+        Em.set(host, 'anyMessage', true);
 
         if (item.level === 'ERROR') {
           anyErrors = true;
-          host.get('errorMessages').push(item.message);
-          checkboxWithIssue.set('hasErrorMessage', true);
-        } else if (item.level === 'WARN') {
-          host.get('warnMessages').push(item.message);
-          checkboxWithIssue.set('hasWarnMessage', true);
+          host.errorMessages.pushObject(item.message);
+          Em.set(checkboxWithIssue, 'hasErrorMessage', true);
         }
-      } else {
+        else
+          if (item.level === 'WARN') {
+            host.warnMessages.pushObject(item.message);
+            Em.set(checkboxWithIssue, 'hasWarnMessage', true);
+          }
+      }
+      else {
         var component;
         if (isGeneralClientValidationItem) {
           if (!anyGeneralClientErrors) {
             anyGeneralClientErrors = true;
             component = "Client";
           }
-        } else {
+        }
+        else {
           component = item['component-name'];
         }
 
@@ -655,9 +671,11 @@ App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
           if (item.level === 'ERROR') {
             anyErrors = true;
             self.get('generalErrorMessages').push(item.message + details);
-          } else if (item.level === 'WARN') {
-            self.get('generalWarningMessages').push(item.message + details);
           }
+          else
+            if (item.level === 'WARN') {
+              self.get('generalWarningMessages').push(item.message + details);
+            }
         }
       }
     });

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd92f965/ambari-web/app/mixins/common/localStorage.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/localStorage.js b/ambari-web/app/mixins/common/localStorage.js
index 5cd9484..8312001 100644
--- a/ambari-web/app/mixins/common/localStorage.js
+++ b/ambari-web/app/mixins/common/localStorage.js
@@ -47,15 +47,32 @@ App.LocalStorage = Em.Mixin.create({
   },
 
   /**
+   * get properties from local storage
+   * @param {String[]} listOfProperties
+   * @return {*}
+   */
+  getDBProperties: function(listOfProperties){
+    return App.db.getProperties(this.get('dbNamespace'), listOfProperties);
+  },
+
+  /**
    * set property to local storage
    * @param {String} key
    * @param {*} value
    */
-  setDBProperty: function(key, value){
+  setDBProperty: function(key, value) {
     App.db.set(this.get('dbNamespace'), key, value);
   },
 
   /**
+   * set properties to local storage
+   * @param {object} hash
+   */
+  setDBProperties: function(hash) {
+    App.db.setProperties(this.get('dbNamespace'), hash);
+  },
+
+  /**
    * Delete the dbNamespace from the localStorage
    * Usually this function is called on quiting/completing the wizard
    */

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd92f965/ambari-web/app/mixins/wizard/assign_master_components.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/wizard/assign_master_components.js b/ambari-web/app/mixins/wizard/assign_master_components.js
index 0ba5eb1..2b393df 100644
--- a/ambari-web/app/mixins/wizard/assign_master_components.js
+++ b/ambari-web/app/mixins/wizard/assign_master_components.js
@@ -660,6 +660,10 @@ App.AssignMasterComponents = Em.Mixin.create({
         return component.get('isShownOnAddServiceAssignMasterPage') || self.get('mastersToShow').contains(component.get('componentName'));
       });
     }
+    var masterComponentsMap = {};
+    masterComponents.forEach(function(masterComponent) {
+      masterComponentsMap[masterComponent.get('componentName')] = masterComponent;
+    });
 
     var masterHosts = self.get('content.masterComponentHosts'); //saved to local storage info
     var selectedNotInstalledServices = self.get('content.services').filterProperty('isSelected').filterProperty('isInstalled', false).mapProperty('serviceName');
@@ -668,13 +672,23 @@ App.AssignMasterComponents = Em.Mixin.create({
     var resultComponents = [];
     var multipleComponentHasBeenAdded = {};
 
+    var existingHostComponentsMap = {};
+    App.HostComponent.find().forEach(function(c) {
+      existingHostComponentsMap[c.get('componentName')] = c;
+    });
+
+    var hostGroupsMap = {};
+    recommendations.blueprint_cluster_binding.host_groups.forEach(function(group) {
+      hostGroupsMap[group.name] = group;
+    });
     recommendations.blueprint.host_groups.forEach(function(host_group) {
-      var hosts = recommendations.blueprint_cluster_binding.host_groups.findProperty('name', host_group.name).hosts;
+      var hosts = hostGroupsMap[host_group.name] ? hostGroupsMap[host_group.name].hosts : [];
 
       hosts.forEach(function(host) {
         host_group.components.forEach(function(component) {
           var willBeAdded = true;
-          var fullComponent = masterComponents.findProperty('componentName', component.name);
+          //var fullComponent = masterComponents.findProperty('componentName', component.name);
+          var fullComponent = masterComponentsMap[component.name];
           // If it's master component which should be shown
           if (fullComponent) {
             // If service is already installed and not being added as a new service then render on UI only those master components
@@ -682,7 +696,7 @@ App.AssignMasterComponents = Em.Mixin.create({
             // NOTE: On upgrade there might be a prior installed service with non-installed newly introduced serviceComponent
             var isNotSelectedService = !selectedNotInstalledServices.contains(fullComponent.get('serviceName'));
             if (isNotSelectedService) {
-              willBeAdded = App.HostComponent.find().someProperty('componentName', component.name);
+              willBeAdded = existingHostComponentsMap[component.name];
             }
 
             if (willBeAdded) {
@@ -696,7 +710,8 @@ App.AssignMasterComponents = Em.Mixin.create({
                     resultComponents.push(self.createComponentInstallationObject(fullComponent, host.fqdn.toLowerCase(), saved));
                   });
                 }
-              } else {
+              }
+              else {
                 var savedComponent = masterHosts.findProperty('component', component.name);
                 resultComponents.push(self.createComponentInstallationObject(fullComponent, host.fqdn.toLowerCase(), savedComponent));
               }
@@ -723,14 +738,8 @@ App.AssignMasterComponents = Em.Mixin.create({
     componentObj.display_name = App.format.role(fullComponent.get('componentName'));
     componentObj.serviceId = fullComponent.get('serviceName');
     componentObj.isServiceCoHost = App.StackServiceComponent.find().findProperty('componentName', componentName).get('isCoHostedComponent') && !this.get('mastersToMove').contains(componentName);
-    if (savedComponent) {
-      componentObj.selectedHost = savedComponent.hostName;
-      componentObj.isInstalled = savedComponent.isInstalled;
-    } else {
-      componentObj.selectedHost = hostName;
-      componentObj.isInstalled = false;
-    }
-
+    componentObj.selectedHost = savedComponent ? savedComponent.hostName : hostName;
+    componentObj.isInstalled = savedComponent ? savedComponent.isInstalled : false;
     return componentObj;
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd92f965/ambari-web/app/utils/db.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/db.js b/ambari-web/app/utils/db.js
index 6006539..6d044f2 100644
--- a/ambari-web/app/utils/db.js
+++ b/ambari-web/app/utils/db.js
@@ -133,6 +133,26 @@ App.db.get = function (namespace, key) {
   return App.db.data[namespace][key];
 };
 
+/**
+ *
+ * @param {string} namespace
+ * @param {string[]} listOfProperties
+ * @returns {object}
+ */
+App.db.getProperties = function (namespace, listOfProperties) {
+  App.db.data = localStorage.getObject('ambari');
+  if (!App.db.data[namespace]) {
+    App.db.data[namespace] = {};
+  }
+  var ret = {};
+  for (var k in listOfProperties) {
+    if (listOfProperties.hasOwnProperty(k)) {
+      ret[k] = App.db.data[namespace][k];
+    }
+  }
+  return ret;
+};
+
 App.db.set = function (namespace, key, value) {
   console.log('TRACE: Entering db:set' + key + ';value: ', value);
   App.db.data = localStorage.getObject('ambari');
@@ -142,6 +162,24 @@ App.db.set = function (namespace, key, value) {
   App.db.data[namespace][key] = value;
   localStorage.setObject('ambari', App.db.data);
 };
+
+/**
+ *
+ * @param {string} namespace
+ * @param {{key: value}} hash
+ */
+App.db.setProperties = function (namespace, hash) {
+  App.db.data = localStorage.getObject('ambari');
+  if (!App.db.data[namespace]) {
+    App.db.data[namespace] = {};
+  }
+  for (var k in hash) {
+    if (hash.hasOwnProperty(k)) {
+      App.db.data[namespace][k] = hash[k];
+    }
+  }
+  localStorage.setObject('ambari', App.db.data);
+};
 /*
  * setter methods
  */

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd92f965/ambari-web/app/views/main/alerts/manage_alert_groups_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/alerts/manage_alert_groups_view.js b/ambari-web/app/views/main/alerts/manage_alert_groups_view.js
index 6775680..069d531 100644
--- a/ambari-web/app/views/main/alerts/manage_alert_groups_view.js
+++ b/ambari-web/app/views/main/alerts/manage_alert_groups_view.js
@@ -57,6 +57,7 @@ App.MainAlertsManageAlertGroupView = Em.View.extend({
    */
   onLoad: function () {
     if (this.get('controller.isLoaded')) {
+      this.set('selectedAlertGroup', [this.get('controller.alertGroups.firstObject')]);
       this.setTooltips();
     }
   }.observes('controller.isLoaded'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd92f965/ambari-web/app/views/wizard/step6_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/wizard/step6_view.js b/ambari-web/app/views/wizard/step6_view.js
index 379912e..e038d18 100644
--- a/ambari-web/app/views/wizard/step6_view.js
+++ b/ambari-web/app/views/wizard/step6_view.js
@@ -82,7 +82,7 @@ App.WizardStep6View = App.TableView.extend({
 
   checkboxClick: function(e) {
     var checkbox = e.context;
-    checkbox.toggleProperty('checked');
+    Em.set(checkbox, 'checked', !checkbox.checked);
     this.get('controller').checkCallback(checkbox.component);
     this.get('controller').callValidation();
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd92f965/ambari-web/test/controllers/main/service/add_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/add_controller_test.js b/ambari-web/test/controllers/main/service/add_controller_test.js
index bb30ac5..68a6cf7 100644
--- a/ambari-web/test/controllers/main/service/add_controller_test.js
+++ b/ambari-web/test/controllers/main/service/add_controller_test.js
@@ -470,6 +470,7 @@ describe('App.AddServiceController', function() {
   describe('#loadServiceConfigGroups', function () {
 
     var dbMock,
+      dbMock2,
       cases = [
         {
           serviceConfigGroups: null,
@@ -484,16 +485,23 @@ describe('App.AddServiceController', function() {
       ];
 
     beforeEach(function () {
-      dbMock = sinon.stub(addServiceController, 'getDBProperty');
+      dbMock = sinon.stub(addServiceController, 'getDBProperties');
+      dbMock2 = sinon.stub(addServiceController, 'getDBProperty');
     });
 
     afterEach(function () {
       dbMock.restore();
+      dbMock2.restore();
     });
 
     cases.forEach(function (item) {
       it(item.title, function () {
-        dbMock.withArgs('hosts').returns({}).withArgs('serviceConfigGroups').returns(item.serviceConfigGroups);
+        dbMock.withArgs(['serviceConfigGroups', 'hosts']).returns({
+          hosts: {},
+          serviceConfigGroups: item.serviceConfigGroups
+        });
+        dbMock2.withArgs('hosts').returns({}).
+          withArgs('serviceConfigGroups').returns(item.serviceConfigGroups);
         addServiceController.loadServiceConfigGroups();
         expect(addServiceController.get('areInstalledConfigGroupsLoaded')).to.equal(item.areInstalledConfigGroupsLoaded);
       });

http://git-wip-us.apache.org/repos/asf/ambari/blob/bd92f965/ambari-web/test/controllers/wizard_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard_test.js b/ambari-web/test/controllers/wizard_test.js
index 1ae4cf5..2bf1a97 100644
--- a/ambari-web/test/controllers/wizard_test.js
+++ b/ambari-web/test/controllers/wizard_test.js
@@ -167,24 +167,23 @@ describe('App.WizardController', function () {
 
   describe('#loadServiceConfigGroups', function () {
      beforeEach(function () {
-      sinon.stub(wizardController, 'getDBProperty', function(message){
-        if (message == 'serviceConfigGroups') {
-          return [
+      sinon.stub(wizardController, 'getDBProperties', function() {
+        return {
+          serviceConfigGroups: [
             {
               hosts: ['h1']
             }
-          ];
-        } else {
-          return Em.Object.create({
+          ],
+          hosts: Em.Object.create({
             h1: Em.Object.create({
               id: 'h1'
             })
-          });
-        }
+          })
+        };
       });
     });
     afterEach(function () {
-      wizardController.getDBProperty.restore();
+      wizardController.getDBProperties.restore();
     });
     it('should load service confgig group', function () {
       wizardController.loadServiceConfigGroups();
@@ -787,17 +786,16 @@ describe('App.WizardController', function () {
 
   describe('#loadServiceComponentsSuccessCallback', function () {
     beforeEach(function () {
-      sinon.stub(wizardController, 'getDBProperty', function(message) {
-        if (message == 'selectedServiceNames') {
-          return ['a','b'];
-        } else {
-          return ['c','d'];
-        }
+      sinon.stub(wizardController, 'getDBProperties', function() {
+        return {
+          selectedServiceNames: ['a','b'],
+          installedServiceNames: ['c','d']
+        };
       });
       sinon.stub(App.stackServiceMapper, 'mapStackServices', Em.K); 
     });
     afterEach(function () {
-      wizardController.getDBProperty.restore();
+      wizardController.getDBProperties.restore();
       App.stackServiceMapper.mapStackServices.restore();
     });
     it('should load json data', function () {
@@ -915,12 +913,12 @@ describe('App.WizardController', function () {
 
     beforeEach(function () {
       c.set('content', {});
-      sinon.stub(c, 'setDBProperty', Em.K);
+      sinon.stub(c, 'setDBProperties', Em.K);
       sinon.stub(App.config, 'shouldSupportFinal').returns(true);
     });
 
     afterEach(function () {
-      c.setDBProperty.restore();
+      c.setDBProperties.restore();
       App.config.shouldSupportFinal.restore();
     });