ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From yus...@apache.org
Subject [6/6] git commit: AMBARI-6430. Make new services pluggable to the wizard. (jaimin via yusaku)
Date Wed, 09 Jul 2014 04:29:49 GMT
AMBARI-6430. Make new services pluggable to the wizard. (jaimin via yusaku)


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

Branch: refs/heads/trunk
Commit: 00f8d5c5c41fc3b2590aec3b2cbbd485c53142d7
Parents: ed65cfd
Author: Yusaku Sako <yusaku@hortonworks.com>
Authored: Tue Jul 8 21:28:12 2014 -0700
Committer: Yusaku Sako <yusaku@hortonworks.com>
Committed: Tue Jul 8 21:29:58 2014 -0700

----------------------------------------------------------------------
 ambari-web/app/app.js                           | 170 +----
 .../controllers/global/cluster_controller.js    |   9 +-
 ambari-web/app/controllers/installer.js         |  63 +-
 .../app/controllers/main/admin/cluster.js       |  78 +-
 .../admin/highAvailability/step2_controller.js  |  25 +-
 .../admin/highAvailability/wizard_controller.js |  33 +-
 .../controllers/main/admin/misc_controller.js   |   2 +-
 .../app/controllers/main/host/add_controller.js |  51 +-
 ambari-web/app/controllers/main/service.js      |  42 +-
 .../controllers/main/service/add_controller.js  |  71 +-
 .../controllers/main/service/info/configs.js    |  29 +-
 ambari-web/app/controllers/main/service/item.js |  12 +-
 .../main/service/reassign/step2_controller.js   |   2 +-
 .../main/service/reassign_controller.js         |  33 +-
 ambari-web/app/controllers/wizard.js            | 121 ++-
 .../app/controllers/wizard/step4_controller.js  | 280 +++----
 .../app/controllers/wizard/step5_controller.js  | 278 +++----
 .../app/controllers/wizard/step6_controller.js  | 164 ++--
 .../app/controllers/wizard/step7_controller.js  |  83 +-
 .../app/controllers/wizard/step8_controller.js  | 154 ++--
 .../app/controllers/wizard/step9_controller.js  |  36 +-
 ambari-web/app/data/HDP2/global_properties.js   | 118 ++-
 ambari-web/app/data/HDP2/site_properties.js     | 138 ++--
 ambari-web/app/data/global_properties.js        |  99 ++-
 ambari-web/app/data/review_configs.js           | 368 ---------
 ambari-web/app/data/service_configs.js          | 279 +------
 ambari-web/app/data/services.js                 | 189 -----
 ambari-web/app/data/site_properties.js          |  46 +-
 ambari-web/app/mappers.js                       |   2 +-
 .../app/mappers/service_metrics_mapper.js       |   5 +-
 .../mappers/stack_service_component_mapper.js   |  44 --
 ambari-web/app/mappers/stack_service_mapper.js  |  90 +++
 ambari-web/app/messages.js                      |  22 +-
 ambari-web/app/mixins.js                        |   3 +-
 ambari-web/app/mixins/models/service_mixin.js   |  30 +
 ambari-web/app/models.js                        |   1 +
 ambari-web/app/models/host_component.js         |   6 +-
 ambari-web/app/models/service.js                |  57 +-
 ambari-web/app/models/stack_service.js          | 382 ++++++++++
 .../app/models/stack_service_component.js       | 146 +++-
 ambari-web/app/routes/add_host_routes.js        |   2 -
 ambari-web/app/routes/add_service_routes.js     |   3 +-
 ambari-web/app/routes/installer.js              |   5 +-
 ambari-web/app/routes/main.js                   |   2 +-
 .../main/admin/highAvailability/step2.hbs       |  75 +-
 ambari-web/app/templates/main/service/item.hbs  |   2 +-
 ambari-web/app/templates/wizard/step4.hbs       |  14 +-
 ambari-web/app/templates/wizard/step5.hbs       |  49 +-
 ambari-web/app/templates/wizard/step6.hbs       |  61 +-
 ambari-web/app/templates/wizard/step8.hbs       |   2 +-
 ambari-web/app/utils/ajax/ajax.js               |   2 +-
 ambari-web/app/utils/component.js               |  68 --
 ambari-web/app/utils/config.js                  | 248 +++---
 ambari-web/app/utils/helper.js                  | 112 ++-
 ambari-web/app/utils/string_utils.js            |  36 +
 .../app/views/common/configs/services_config.js |   3 +-
 ambari-web/app/views/main/host.js               |   5 +
 .../app/views/main/host/addHost/step4_view.js   |   9 +-
 .../app/views/main/host/configs_service_menu.js |   7 +-
 .../app/views/main/service/info/summary.js      |   6 +-
 ambari-web/app/views/main/service/item.js       |  10 +-
 ambari-web/app/views/main/service/menu.js       |  22 +-
 ambari-web/app/views/main/service/service.js    |   5 +-
 ambari-web/app/views/wizard/step5_view.js       |  27 +-
 ambari-web/app/views/wizard/step6_view.js       |  13 +-
 ambari-web/test/app_test.js                     |  16 +-
 .../main/host/add_controller_test.js            |  20 +-
 .../test/controllers/main/host/details_test.js  |   1 +
 .../test/controllers/wizard/step4_test.js       | 175 +----
 .../test/controllers/wizard/step5_test.js       | 759 +++++++------------
 .../test/controllers/wizard/step6_test.js       |   6 -
 .../test/controllers/wizard/step8_test.js       | 153 ++++
 .../test/controllers/wizard/step9_test.js       |   2 +
 ambari-web/test/init_model_test.js              |  12 +-
 ambari-web/test/service_components.js           | 679 +++++++++++++++--
 ambari-web/test/utils/component_test.js         |  71 --
 ambari-web/test/utils/helper_test.js            |  86 +++
 ambari-web/test/views/wizard/step5_view_test.js |   4 +-
 78 files changed, 3155 insertions(+), 3378 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/app.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/app.js b/ambari-web/app/app.js
index 81ee5d5..5e31627 100644
--- a/ambari-web/app/app.js
+++ b/ambari-web/app/app.js
@@ -88,154 +88,28 @@ module.exports = Em.Application.create({
   }.property('router.clusterController.isLoaded', 'isHadoop2Stack'),
 
   /**
-   * List of disabled components for the current stack with related info.
-   * Each element has followed structure:
-   * @type {Em.Enumerable.<Em.Object>}
-   *   @property componentName {String} - name of the component
-   *   @property properties {Object} - mapped properties by site files,
-   *    for example:
-   *      properties: { global_properties: [], site_properties: [], etc. }
-   *   @property reviewConfigs {Ember.Object} - reference review_configs.js
+   * Object with utility functions for list of service names with similar behavior
    */
-  stackDependedComponents: [],
+  services: Em.Object.create({
+    all: function () {
+      return App.StackService.find().mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
 
-  /**
-   * Restore component data that was excluded from stack.
-   *
-   * @param component {Ember.Object} - #stackDependedComponents item
-   */
-  enableComponent: function (component) {
-    var propertyFileNames = ['global_properties', 'site_properties'];
-    var requirePrefix = this.get('isHadoop2Stack') ? 'data/HDP2/' : 'data/';
-    // add properties
-    propertyFileNames.forEach(function (fileName) {
-      require(requirePrefix + fileName).configProperties = require(requirePrefix + fileName).configProperties.concat(component.get('properties.' + fileName));
-    });
-    var reviewConfigsService = require('data/review_configs')
-      .findProperty('config_name', 'services').config_value
-      .findProperty('service_name', component.get('serviceName'));
-    reviewConfigsService.get('service_components').pushObject(component.get('reviewConfigs'));
-  },
-  /**
-   * Disabling component. Remove related data from lists such as
-   * properties, review configs, service components.
-   *
-   * @param component {Object} - stack service component
-   *
-   * @return {Ember.Object} - item of <code>stackDependedComponents</code> property
-   */
-  disableComponent: function (component) {
-    var componentCopy, propertyFileNames;
-    var service_configs = require('data/service_configs');
-    propertyFileNames = ['global_properties', 'site_properties'];
-    componentCopy = Em.Object.create({
-      componentName: component.get('componentName'),
-      serviceName: component.get('serviceName'),
-      properties: {},
-      reviewConfigs: {},
-      configCategory: {}
-    });
+    clientOnly: function () {
+      return App.StackService.find().filterProperty('isClientOnlyService').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
 
-    var serviceConfigsCategoryName, requirePrefix, serviceConfig;
-    // get service category name related to component
-    serviceConfig = service_configs.findProperty('serviceName', component.get('serviceName'));
-    serviceConfig.configCategories = serviceConfig.configCategories.filter(function (configCategory) {
-      if (configCategory.get('hostComponentNames')) {
-        serviceConfigsCategoryName = configCategory.get('name');
-        if (configCategory.get('hostComponentNames').contains(component.get('componentName'))) {
-          componentCopy.set('configCategory', configCategory);
-        }
-      }
-      return true;
-    });
-    requirePrefix = this.get('isHadoop2Stack') ? 'data/HDP2/' : 'data/';
-    var propertyObj = {};
-    propertyFileNames.forEach(function (propertyFileName) {
-      propertyObj[propertyFileName] = [];
-    });
-    // remove config properties related to this component
-    propertyFileNames.forEach(function (propertyFileName) {
-      var properties = require(requirePrefix + propertyFileName);
-      properties.configProperties = properties.configProperties.filter(function (property) {
-        if (property.category == serviceConfigsCategoryName) {
-          propertyObj[propertyFileName].push(property);
-          return false;
-        } else {
-          return true;
-        }
-      });
-    });
-    componentCopy.set('properties', propertyObj);
-    // remove component from review configs
-    var reviewConfigsService = require('data/review_configs')
-      .findProperty('config_name', 'services').config_value
-      .findProperty('service_name', component.get('serviceName'));
-    //review_configs might not contain particular service
-    if (reviewConfigsService) {
-      reviewConfigsService.set('service_components', reviewConfigsService.get('service_components').filter(function (serviceComponent) {
-        if (serviceComponent.get('component_name') != component.get('componentName')) {
-          return true;
-        } else {
-          componentCopy.set('reviewConfigs', serviceComponent);
-          return false;
-        }
-      }));
-    }
-    return componentCopy;
-  },
-  /**
-   * Resolve dependency in components.
-   * if component with config category from "data/service_configs" doesn't match components from stack
-   * then disable it and push to stackDependedComponents
-   * otherwise enable component and remove it from stackDependedComponents
-   * Check forbidden/allowed components and
-   * remove/restore related data.
-   *
-   * @method handleStackDependedComponents
-   */
-  handleStackDependedComponents: function () {
-    // need for unit testing and test mode
-    if (this.get('handleStackDependencyTest') || this.testMode) return;
-    var stackDependedComponents = this.get('stackDependedComponents');
-    var service_configs = require('data/service_configs');
-    var stackServiceComponents = this.StackServiceComponent.find();
-    var stackServices = stackServiceComponents.mapProperty('serviceName').uniq();
-    if (!stackServiceComponents.mapProperty('componentName').length) {
-      return;
-    }
-    // disable components
-    service_configs.forEach(function (service) {
-      service.configCategories.forEach(function (serviceConfigCategory) {
-        var categoryComponents = serviceConfigCategory.get('hostComponentNames');
-        if (categoryComponents && categoryComponents.length) {
-          categoryComponents.forEach(function (categoryComponent) {
-            var stackServiceComponent = stackServiceComponents.findProperty('componentName', categoryComponent);
-            // populate App.stackDependedComponents if the service config category for the serviceComponent
-            // exists in the 'data/service_configs.js' and the service to which the component belongs also exists in the
-            // stack but the serviceComponent does not exists in the stack. Also check App.stackDependedComponents doesn't already have the componentName
-            if (!stackServiceComponent && stackServices.contains(service.serviceName) && !stackDependedComponents.mapProperty('componentName').contains['categoryComponent']) {
-              var _stackServiceComponent = Ember.Object.create({
-                componentName: categoryComponent,
-                serviceName: service.serviceName
-              });
-              stackDependedComponents.push(this.disableComponent(_stackServiceComponent));
-            }
-          }, this);
-        }
-      }, this);
-    }, this);
+    hasClient: function () {
+      return App.StackService.find().filterProperty('hasClient').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
 
-    // enable components
-    if (stackDependedComponents.length > 0) {
-      stackDependedComponents.forEach(function (component) {
-        if (stackServiceComponents.someProperty('componentName', component.get('componentName'))) {
-          this.enableComponent(component);
-          stackDependedComponents.removeObject(component);
-        }
-      }, this);
-    }
-    this.set('stackDependedComponents', stackDependedComponents);
-  },
+    noConfigTypes: function () {
+      return App.StackService.find().filterProperty('isNoConfigTypes').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded'),
+    monitoring: function () {
+      return App.StackService.find().filterProperty('isMonitoringService').mapProperty('serviceName');
+    }.property('App.router.clusterController.isLoaded')
+  }),
 
   /**
    * List of components with allowed action for them
@@ -274,6 +148,14 @@ module.exports = Em.Application.create({
       return App.StackServiceComponent.find().filterProperty('isAddableToHost', true).mapProperty('componentName')
     }.property('App.router.clusterController.isLoaded'),
 
+    addableMasterInstallerWizard: function () {
+      return App.StackServiceComponent.find().filterProperty('isMasterWithMultipleInstances', true).mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
+    addableMasterHaWizard: function () {
+      return App.StackServiceComponent.find().filterProperty('isMasterWithMultipleInstancesHaWizard', true).mapProperty('componentName')
+    }.property('App.router.clusterController.isLoaded'),
+
     slaves: function () {
       return App.StackServiceComponent.find().filterProperty('isMaster', false).filterProperty('isClient', false).mapProperty('componentName')
     }.property('App.router.clusterController.isLoaded'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/global/cluster_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js
index df70820..b68ddab 100644
--- a/ambari-web/app/controllers/global/cluster_controller.js
+++ b/ambari-web/app/controllers/global/cluster_controller.js
@@ -305,9 +305,14 @@ App.ClusterController = Em.Controller.extend({
      * 10. update stale_configs of host-components (depends on App.supports.hostOverrides)
      */
     this.loadStackServiceComponents(function (data) {
+      data.items.forEach(function(service) {
+        service.StackServices.is_selected = true;
+        service.StackServices.is_installed = false;
+      },this);
+      App.stackServiceMapper.map(data);
+      App.config.setPreDefinedGlobalProperties();
+      App.config.setPreDefinedServiceConfigs();
       var updater = App.router.get('updateController');
-
-      require('utils/component').loadStackServiceComponentModel(data);
       self.updateLoadStatus('stackComponents');
       updater.updateServices(function () {
         self.updateLoadStatus('services');

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/installer.js b/ambari-web/app/controllers/installer.js
index d339433..940cf77 100644
--- a/ambari-web/app/controllers/installer.js
+++ b/ambari-web/app/controllers/installer.js
@@ -122,18 +122,11 @@ App.InstallerController = App.WizardController.extend({
    * Load services data. Will be used at <code>Select services(step4)</code> step
    */
   loadServices: function () {
-    var servicesInfo = this.getDBProperty('service');
-    if(servicesInfo && servicesInfo.length) {
-      servicesInfo.forEach(function (item, index) {
-        servicesInfo[index] = Em.Object.create(item);
-        servicesInfo[index].isInstalled = false;
-      });
-      this.set('content.services', servicesInfo);
-      console.log('installerController.loadServices: loaded data ', JSON.stringify(servicesInfo));
-      console.log('selected services ', servicesInfo.filterProperty('isSelected', true).mapProperty('serviceName'));
-    } else {
-      console.log("Failed to load Services");
-   }
+    var stackServices = App.StackService.find().mapProperty('serviceName');
+    if (!(stackServices && !!stackServices.length && App.StackService.find().objectAt(0).get('stackVersion') == App.get('currentStackVersionNumber'))) {
+      this.loadServiceComponents();
+      this.set('content.services', App.StackService.find());
+    }
   },
 
   /**
@@ -207,18 +200,6 @@ App.InstallerController = App.WizardController.extend({
     return hosts;
   }.property('content.hosts'),
 
-  /**
-   * Load service components.
-   */
-  loadServiceComponentsDb: function () {
-    var serviceComponents = this.getDBProperty('serviceComponents');
-    if(serviceComponents && serviceComponents.items && serviceComponents.items.length) {
-      App.stackServiceComponentMapper.map(serviceComponents);
-    } else {
-      console.log("Failed to load Service components");
-    }
-  },
-
   stacks: [],
 
   /**
@@ -391,11 +372,19 @@ App.InstallerController = App.WizardController.extend({
    * @param stepController App.WizardStep4Controller
    */
   saveServices: function (stepController) {
-    this.setDBProperty('service', stepController.get('content'));
-    var serviceNames = stepController.filterProperty('isSelected', true).mapProperty('serviceName');
-    this.set('content.selectedServiceNames', serviceNames);
-    this.setDBProperty('selectedServiceNames', serviceNames);
-    console.log('installerController.saveServices: saved data ', serviceNames);
+    var selectedServiceNames = [];
+    var installedServiceNames = [];
+    stepController.filterProperty('isSelected').forEach(function (item) {
+      selectedServiceNames.push(item.get('serviceName'));
+    });
+    stepController.filterProperty('isInstalled').forEach(function (item) {
+      installedServiceNames.push(item.get('serviceName'));
+    });
+    this.set('content.services', App.StackService.find());
+    this.set('content.selectedServiceNames', selectedServiceNames);
+    this.setDBProperty('selectedServiceNames', selectedServiceNames);
+    this.set('content.installedServiceNames', installedServiceNames);
+    this.setDBProperty('installedServiceNames', installedServiceNames);
   },
 
   /**
@@ -486,21 +475,19 @@ App.InstallerController = App.WizardController.extend({
   saveClients: function (stepController) {
     var clients = [];
     var serviceComponents = App.StackServiceComponent.find();
-
+    var services =
     stepController.get('content').filterProperty('isSelected', true).forEach(function (_service) {
-      var client = serviceComponents.filterProperty('serviceName', _service.serviceName).findProperty('isClient', true);
-      if (client) {
+      var client = _service.get('serviceComponents').filterProperty('isClient', true);
+      client.forEach(function(clientComponent){
         clients.pushObject({
-          component_name: client.get('componentName'),
-          display_name: client.get('displayName'),
+          component_name: clientComponent.get('componentName'),
+          display_name: clientComponent.get('displayName'),
           isInstalled: false
         });
-      }
+      },this);
     }, this);
-
     this.setDBProperty('clientInfo', clients);
     this.set('content.clients', clients);
-    console.log("InstallerController.saveClients: saved list ", clients);
   },
 
   /**
@@ -614,8 +601,8 @@ App.InstallerController = App.WizardController.extend({
         this.loadMasterComponentHosts();
         this.loadConfirmedHosts();
       case '4':
+        this.loadStacks();
         this.loadServices();
-        this.loadServiceComponentsDb();
       case '3':
         this.loadConfirmedHosts();
       case '2':

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/admin/cluster.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/cluster.js b/ambari-web/app/controllers/main/admin/cluster.js
index 6e105da..264b4e9 100644
--- a/ambari-web/app/controllers/main/admin/cluster.js
+++ b/ambari-web/app/controllers/main/admin/cluster.js
@@ -20,15 +20,15 @@ var App = require('app');
 var stringUtils = require('utils/string_utils');
 
 App.MainAdminClusterController = Em.Controller.extend({
-  name:'mainAdminClusterController',
+  name: 'mainAdminClusterController',
   services: [],
   allRepos: [],
   upgradeVersion: '',
   /**
    * get the newest version of HDP from server
    */
-  updateUpgradeVersion: function(){
-    if(App.router.get('clusterController.isLoaded')){
+  updateUpgradeVersion: function () {
+    if (App.router.get('clusterController.isLoaded')) {
       App.ajax.send({
         name: 'cluster.update_upgrade_version',
         sender: this,
@@ -36,25 +36,25 @@ App.MainAdminClusterController = Em.Controller.extend({
         error: 'updateUpgradeVersionErrorCallback'
       });
     }
-  }.observes('App.router.clusterController.isLoaded', 'App.currentStackVersion','App.router.mainServiceController.content.length'),
+  }.observes('App.router.clusterController.isLoaded', 'App.currentStackVersion', 'App.router.mainServiceController.content.length'),
 
-  updateUpgradeVersionSuccessCallback: function(data) {
+  updateUpgradeVersionSuccessCallback: function (data) {
     var upgradeVersion = this.get('upgradeVersion') || App.defaultStackVersion;
     var currentVersion = App.get('currentStackVersionNumber');
     upgradeVersion = upgradeVersion.replace(/HDP-/, '');
-    data.items.mapProperty('Versions.stack_version').forEach(function(version){
+    data.items.mapProperty('Versions.stack_version').forEach(function (version) {
       upgradeVersion = (stringUtils.compareVersions(upgradeVersion, version) === -1) ? version : upgradeVersion;
     });
     var currentStack = data.items.findProperty('Versions.stack_version', currentVersion);
     var upgradeStack = data.items.findProperty('Versions.stack_version', upgradeVersion);
     var minUpgradeVersion = upgradeStack.Versions.min_upgrade_version;
-    if(minUpgradeVersion && (stringUtils.compareVersions(minUpgradeVersion, currentVersion) === 1)){
+    if (minUpgradeVersion && (stringUtils.compareVersions(minUpgradeVersion, currentVersion) === 1)) {
       upgradeVersion = currentVersion;
       upgradeStack = currentStack;
     }
     upgradeVersion = 'HDP-' + upgradeVersion;
     this.set('upgradeVersion', upgradeVersion);
-    if(currentStack && upgradeStack) {
+    if (currentStack && upgradeStack) {
       this.parseServicesInfo(currentStack, upgradeStack);
     }
     else {
@@ -62,7 +62,7 @@ App.MainAdminClusterController = Em.Controller.extend({
     }
   },
 
-  updateUpgradeVersionErrorCallback: function(request, ajaxOptions, error) {
+  updateUpgradeVersionErrorCallback: function (request, ajaxOptions, error) {
     console.log('Error message is: ' + request.responseText);
     console.log('HDP stack doesn\'t have services with defaultStackVersion');
   },
@@ -70,8 +70,8 @@ App.MainAdminClusterController = Em.Controller.extend({
   /**
    * get the installed repositories of HDP from server
    */
-  loadRepositories: function(){
-    if(App.router.get('clusterController.isLoaded')){
+  loadRepositories: function () {
+    if (App.router.get('clusterController.isLoaded')) {
       var nameVersionCombo = App.get('currentStackVersion');
       var stackName = nameVersionCombo.split('-')[0];
       var stackVersion = nameVersionCombo.split('-')[1];
@@ -119,7 +119,7 @@ App.MainAdminClusterController = Em.Controller.extend({
     this.set('allRepos', allRepos);
   },
 
-  loadRepositoriesErrorCallback: function(request, ajaxOptions, error) {
+  loadRepositoriesErrorCallback: function (request, ajaxOptions, error) {
     console.log('Error message is: ' + request.responseText);
   },
 
@@ -129,42 +129,32 @@ App.MainAdminClusterController = Em.Controller.extend({
   parseServicesInfo: function (currentStack, upgradeStack) {
     var result = [];
     var installedServices = App.Service.find().mapProperty('serviceName');
-    var displayOrderConfig = require('data/services');
-    if(currentStack.stackServices.length && upgradeStack.stackServices.length){
+    var displayOrder = App.StackService.displayOrder;
+    if (currentStack.stackServices.length && upgradeStack.stackServices.length) {
       // loop through all the service components
-      for (var i = 0; i < displayOrderConfig.length; i++) {
+      displayOrder.forEach(function (_stackServiceName) {
         var entry = currentStack.stackServices.
-          findProperty("StackServices.service_name", displayOrderConfig[i].serviceName);
-        if (entry) {
-          entry = entry.StackServices;
-          if (installedServices.contains(entry.service_name)) {
-            var myService = Em.Object.create({
-              serviceName: entry.service_name,
-              displayName: displayOrderConfig[i].displayName,
-              isDisabled: displayOrderConfig[i].isDisabled,
-              isSelected: true,
-              isInstalled: false,
-              isHidden: displayOrderConfig[i].isHidden,
-              description: entry.comments,
-              version: entry.service_version,
-              newVersion: ''
-            });
-            // it's possible that there is no corresponding service in the new stack
-            var matchedService = upgradeStack.stackServices.findProperty("StackServices.service_name", displayOrderConfig[i].serviceName);
-            if (matchedService) {
-              myService.newVersion = matchedService.StackServices.service_version;
-            }
-            //From 1.3.0 for Hive we display only "Hive" (but it install HCat and WebHCat as well)
-            if (this.get('upgradeVersion').replace(/HDP-/, '') >= '1.3.0' && displayOrderConfig[i].serviceName == 'HIVE') {
-              myService.set('displayName', 'Hive');
-            }
-            result.push(myService);
+          findProperty("StackServices.service_name", _stackServiceName);
+        var stackService = App.StackService.find().findProperty('serviceName', _stackServiceName);
+        if (!!stackService) {
+          var myService = Em.Object.create({
+            serviceName: stackService.get('serviceName'),
+            displayName: stackService.get('displayNameOnSelectServicePage'),
+            isSelected: true,
+            isInstalled: false,
+            isHidden:  stackService.get('isHiddenOnSelectServicePage'),
+            description: stackService.get('comments'),
+            version: stackService.get('serviceVersion'),
+            newVersion: ''
+          });
+          // it's possible that there is no corresponding service in the new stack
+          var matchedService = upgradeStack.stackServices.findProperty("StackServices.service_name", stackService.get('serviceName'));
+          if (matchedService) {
+            myService.newVersion = matchedService.StackServices.service_version;
           }
+          result.push(myService);
         }
-        else {
-          console.warn('Service not found - ', displayOrderConfig[i].serviceName);
-        }
-      }
+      }, this);
     }
     this.set('services', result);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
index d58d7dd..e7e77bb 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
@@ -25,9 +25,15 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
   name:"highAvailabilityWizardStep2Controller",
 
   /**
-   * master components which could be assigned to multiple hosts
+   * master components which could be assigned to multiple hosts in HA wizard
    */
-  multipleComponents: ['NAMENODE', 'JOURNALNODE'],
+  multipleComponentsHaWizard: ['NAMENODE', 'JOURNALNODE'],
+
+  /**
+   * master components supported by Ambari
+   */
+
+  multipleComponents: ['NAMENODE', 'JOURNALNODE','ZOOKEEPER_SERVER','HBASE_MASTER'],
 
   /**
    * overrides method in wizardStep5Controller
@@ -53,7 +59,7 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
 
       var masterServices = self.get("selectedServicesMasters").filterProperty("selectedHost", item);
       masterServices.forEach(function(item){
-        if(this.get('multipleComponents').contains(item.component_name)){
+        if(this.get('multipleComponentsHaWizard').contains(item.component_name)){
           item.set('color','green');
         }else{
           item.set('color','grey');
@@ -77,14 +83,13 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
    * @param masterComponents
    */
   renderComponents:function (masterComponents) {
-    var services = this.get('content.services')
-      .filterProperty('isInstalled', true).filterProperty('isInstalled', true).mapProperty('serviceName'); //list of shown services
+    var services = this.get('content.services').filterProperty('isInstalled', true).mapProperty('serviceName'); //list of shown services
 
     var result = [];
 
     var curNameNode = masterComponents.findProperty('component_name',"NAMENODE");
     curNameNode.isCurNameNode = true;
-    curNameNode.zId = 0;
+    curNameNode.serviceComponentId = 0;
 
     //Create JOURNALNODE
     for (var index = 0; index < 3; index++) {
@@ -92,11 +97,11 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
         {
           component_name: "JOURNALNODE",
           display_name: "JournalNode",
-          isHiveCoHost: false,
+          isServiceCoHost: false,
           isInstalled: false,
           selectedHost: this.get("hosts")[index].get("host_name"),
           serviceId: "HDFS",
-          zId: index
+          serviceComponentId: index
         }
       )
     }
@@ -105,12 +110,12 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
       {
         component_name: "NAMENODE",
         display_name: "NameNode",
-        isHiveCoHost: false,
+        isServiceCoHost: false,
         isInstalled: false,
         selectedHost: this.get("hosts").mapProperty('host_name').without(curNameNode.selectedHost)[0],
         serviceId: "HDFS",
         isAddNameNode: true,
-        zId: 1
+        serviceComponentId: 1
       }
     );
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
index a6e35b1..22791bf 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
@@ -66,14 +66,31 @@ App.HighAvailabilityWizardController = App.WizardController.extend({
    * Load services data from server.
    */
   loadServicesFromServer: function() {
-    var apiService = this.loadServiceComponents();
-    apiService.forEach(function(item, index){
-      apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
-      apiService[index].isDisabled = apiService[index].isSelected;
-      apiService[index].isInstalled = apiService[index].isSelected;
-    });
-    this.set('content.services', apiService);
-    App.db.setService(apiService);
+    var services = this.getDBProperty('services');
+    if (!services) {
+      services = {
+        selectedServices: [],
+        installedServices: []
+      };
+      App.StackService.find().forEach(function(item){
+        var isInstalled = App.Service.find().someProperty('id', item.get('serviceName'));
+        item.set('isSelected', isInstalled);
+        item.set('isInstalled', isInstalled);
+        if (isInstalled) {
+          services.selectedServices.push(item.get('serviceName'));
+          services.installedServices.push(item.get('serviceName'));
+        }
+      },this);
+      this.setDBProperty('services',services);
+    } else {
+      App.StackService.find().forEach(function(item) {
+        var isSelected =   services.selectedServices.contains(item.get('serviceName'));
+        var isInstalled = services.installedServices.contains(item.get('serviceName'));
+        item.set('isSelected', isSelected);
+        item.set('isInstalled', isInstalled);
+      },this);
+    }
+    this.set('content.services', App.StackService.find());
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/admin/misc_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/misc_controller.js b/ambari-web/app/controllers/main/admin/misc_controller.js
index 6ebdd7c..628d813 100644
--- a/ambari-web/app/controllers/main/admin/misc_controller.js
+++ b/ambari-web/app/controllers/main/admin/misc_controller.js
@@ -49,7 +49,7 @@ App.MainAdminMiscController = App.MainServiceInfoConfigsController.extend({
     var loadedClusterSiteToTagMap = {};
 
     for (var site in data.Clusters.desired_configs) {
-      if (serviceConfigsDef.sites.indexOf(site) > -1) {
+      if (serviceConfigsDef.configTypes.contains(site)) {
         loadedClusterSiteToTagMap[site] = data.Clusters.desired_configs[site]['tag'];
       }
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/host/add_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host/add_controller.js b/ambari-web/app/controllers/main/host/add_controller.js
index 8af72a1..a0f08bd 100644
--- a/ambari-web/app/controllers/main/host/add_controller.js
+++ b/ambari-web/app/controllers/main/host/add_controller.js
@@ -100,32 +100,34 @@ App.AddHostController = App.WizardController.extend({
   },
 
   /**
-   * Load services data from server.
-   * TODO move to mixin
-   */
-  loadServicesFromServer: function () {
-    var apiService = this.loadServiceComponents();
-    apiService.forEach(function (item, index) {
-      apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
-      apiService[index].isDisabled = apiService[index].isSelected;
-      apiService[index].isInstalled = apiService[index].isSelected;
-    });
-    this.set('content.services', apiService);
-    this.setDBProperty('service', apiService);
-  },
-
-  /**
    * Load services data. Will be used at <code>Select services(step4)</code> step
    */
   loadServices: function () {
-    var servicesInfo = this.getDBProperty('service');
-    console.log('AddHostController.loadServices: loaded data ', servicesInfo);
-    servicesInfo.forEach(function (item, index) {
-      servicesInfo[index] = Em.Object.create(item);
-    });
-    this.set('content.services', servicesInfo);
-    var serviceNames = servicesInfo.filterProperty('isSelected', true).mapProperty('serviceName');
-    console.log('selected services ', serviceNames);
+    var services = this.getDBProperty('services');
+    if (!services) {
+      services = {
+        selectedServices: [],
+        installedServices: []
+      };
+      App.StackService.find().forEach(function(item){
+        var isInstalled = App.Service.find().someProperty('id', item.get('serviceName'));
+        item.set('isSelected', isInstalled);
+        item.set('isInstalled', isInstalled);
+        if (isInstalled) {
+          services.selectedServices.push(item.get('serviceName'));
+          services.installedServices.push(item.get('serviceName'));
+        }
+      },this);
+      this.setDBProperty('services',services);
+    } else {
+      App.StackService.find().forEach(function(item) {
+        var isSelected =   services.selectedServices.contains(item.get('serviceName'));
+        var isInstalled = services.installedServices.contains(item.get('serviceName'));
+        item.set('isSelected', isSelected);
+        item.set('isInstalled', isInstalled);
+      },this);
+    }
+    this.set('content.services', App.StackService.find());
   },
 
   /**
@@ -171,7 +173,7 @@ App.AddHostController = App.WizardController.extend({
     }
 
     this.get('content.services').filterProperty('isSelected').forEach(function (_service) {
-      var client = serviceComponents.filterProperty('serviceName', _service.serviceName).findProperty('isClient');
+      var client = serviceComponents.filterProperty('serviceName', _service.get('serviceName')).findProperty('isClient');
       if (client) {
         clients.push({
           component_name: client.get('componentName'),
@@ -180,7 +182,6 @@ App.AddHostController = App.WizardController.extend({
         });
       }
     }, this);
-
     this.setDBProperty('clientInfo', clients);
     this.set('content.clients', clients);
     console.log("AddHostController.saveClients: saved list ", clients);

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service.js b/ambari-web/app/controllers/main/service.js
index fba94b1..1c9d774 100644
--- a/ambari-web/app/controllers/main/service.js
+++ b/ambari-web/app/controllers/main/service.js
@@ -20,7 +20,6 @@ var App = require('app');
 
 App.MainServiceController = Em.ArrayController.extend({
   name:'mainServiceController',
-  stackServices: [],
   content: function(){
     if(!App.router.get('clusterController.isLoaded')){
       return [];
@@ -37,46 +36,22 @@ App.MainServiceController = Em.ArrayController.extend({
 
   isAllServicesInstalled: function() {
     if (!this.get('content.content')) return false;
-    if (!this.get('stackServices').length) {
-      this.loadAvailableServices();
-    }
+
+    var availableServices = App.StackService.find().mapProperty('serviceName');
     if (!App.supports.hue) {
-      var stackServices = this.get('stackServices').without('HUE');
-      this.set('stackServices',stackServices);
+      availableServices = availableServices.without('HUE');
     }
-    return this.get('content.content').length == this.get('stackServices').length;
+    return this.get('content.content').length == availableServices.length;
   }.property('content.content.@each', 'content.content.length'),
 
-  loadAvailableServices: function() {
-    App.ajax.send({
-      name: 'wizard.service_components',
-      sender: this,
-      data: {
-        stackUrl: App.get('stackVersionURL'),
-        stackVersion: App.get('currentStackVersionNumber')
-      },
-      success: 'loadAvailableServicesSuccessCallback'
-    });
-  },
-
-  loadAvailableServicesSuccessCallback: function(jsonData) {
-    var data = [];
-    var displayOrderConfig = require('data/services');
-    for (var i = 0; i < displayOrderConfig.length; i++) {
-      var entry = jsonData.items.findProperty("StackServices.service_name", displayOrderConfig[i].serviceName);
-      if (entry) {
-        data.push(entry.StackServices.service_name);
-      }
-    }
-    this.set('stackServices',data);
-  },
-
   isStartAllDisabled: function(){
     if(this.get('isStartStopAllClicked') == true) {
       return true;
     }
-    var stoppedServiceLength = this.get('content').filterProperty('healthStatus','red').filterProperty('isClientsOnly', false).length;
-    return (stoppedServiceLength === 0); // all green status
+    var stoppedServices =  this.get('content').filter(function(_service){
+      return (_service.get('healthStatus') === 'red' && !App.get('services.clientOnly').contains(_service.get('serviceName')));
+    });
+    return (stoppedServices.length === 0); // all green status
   }.property('isStartStopAllClicked', 'content.@each.healthStatus'),
   isStopAllDisabled: function(){
     if(this.get('isStartStopAllClicked') == true) {
@@ -158,5 +133,4 @@ App.MainServiceController = Em.ArrayController.extend({
     }
     App.router.transitionTo('main.serviceAdd');
   }
-
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/service/add_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/add_controller.js b/ambari-web/app/controllers/main/service/add_controller.js
index 2f353c8..89669ff 100644
--- a/ambari-web/app/controllers/main/service/add_controller.js
+++ b/ambari-web/app/controllers/main/service/add_controller.js
@@ -22,8 +22,6 @@ App.AddServiceController = App.WizardController.extend({
 
   name: 'addServiceController',
 
-  serviceConfigs:require('data/service_configs'),
-
   totalSteps: 7,
 
   /**
@@ -80,7 +78,6 @@ App.AddServiceController = App.WizardController.extend({
       return;
     }
     var apiService = this.loadServiceComponents();
-    //
     apiService.forEach(function(item, index){
       apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
       apiService[index].isDisabled = apiService[index].isSelected;
@@ -94,20 +91,38 @@ App.AddServiceController = App.WizardController.extend({
    * Load services data. Will be used at <code>Select services(step4)</code> step
    */
   loadServices: function () {
-    var servicesInfo = this.getDBProperty('service');
-    servicesInfo.forEach(function (item, index) {
-      servicesInfo[index] = Em.Object.create(item);
-    });
-    this.set('content.services', servicesInfo);
-    console.log('AddServiceController.loadServices: loaded data ', servicesInfo);
-
-    var serviceNames = servicesInfo.filterProperty('isSelected', true).filterProperty('isDisabled', false).mapProperty('serviceName');
-    console.log('selected services ', serviceNames);
-
-    this.set('content.skipSlavesStep', !serviceNames.contains('MAPREDUCE') && !serviceNames.contains('HBASE')  && !serviceNames.contains('STORM') && !serviceNames.contains('YARN'));
-    if (this.get('content.skipSlavesStep')) {
-      this.get('isStepDisabled').findProperty('step', 3).set('value', this.get('content.skipSlavesStep'));
+    var services = this.getDBProperty('services');
+    if (!services) {
+      services = {
+        selectedServices: [],
+        installedServices: []
+      };
+      App.StackService.find().forEach(function(item){
+        var isInstalled = App.Service.find().someProperty('id', item.get('serviceName'));
+        item.set('isSelected', isInstalled);
+        item.set('isInstalled', isInstalled);
+        if (isInstalled) {
+          services.selectedServices.push(item.get('serviceName'));
+          services.installedServices.push(item.get('serviceName'));
+        }
+      },this);
+      this.setDBProperty('services',services);
+    } else {
+      App.StackService.find().forEach(function(item) {
+        var isSelected =   services.selectedServices.contains(item.get('serviceName'));
+        var isInstalled = services.installedServices.contains(item.get('serviceName'));
+        item.set('isSelected', isSelected);
+        item.set('isInstalled', isInstalled);
+      },this);
+      var serviceNames = App.StackService.find().filterProperty('isSelected', true).filterProperty('isInstalled', false).mapProperty('serviceName');
+      console.log('selected services ', serviceNames);
+
+      this.set('content.skipSlavesStep', !serviceNames.contains('MAPREDUCE') && !serviceNames.contains('HBASE')  && !serviceNames.contains('STORM') && !serviceNames.contains('YARN'));
+      if (this.get('content.skipSlavesStep')) {
+        this.get('isStepDisabled').findProperty('step', 3).set('value', this.get('content.skipSlavesStep'));
+      }
     }
+    this.set('content.services', App.StackService.find());
   },
 
   /**
@@ -116,14 +131,18 @@ App.AddServiceController = App.WizardController.extend({
    */
   saveServices: function (stepController) {
     var serviceNames = [];
-    this.setDBProperty('service', stepController.get('content'));
+    var services = {
+      selectedServices: [],
+      installedServices: []
+    };
+    var selectedServices = stepController.get('content').filterProperty('isSelected',true).filterProperty('isInstalled', false).mapProperty('serviceName');
+    services.selectedServices.pushObjects(selectedServices);
+    services.installedServices.pushObjects(stepController.get('content').filterProperty('isInstalled',true).mapProperty('serviceName'));
+    this.setDBProperty('services',services);
     console.log('AddServiceController.saveServices: saved data', stepController.get('content'));
-    stepController.filterProperty('isSelected', true).filterProperty('isInstalled', false).forEach(function (item) {
-      serviceNames.push(item.serviceName);
-    });
-    this.set('content.selectedServiceNames', serviceNames);
-    this.setDBProperty('selectedServiceNames',serviceNames);
-    console.log('AddServiceController.selectedServiceNames:', serviceNames);
+
+    this.set('content.selectedServiceNames', selectedServices);
+    this.setDBProperty('selectedServiceNames',selectedServices);
 
     this.set('content.skipSlavesStep', !serviceNames.contains('MAPREDUCE') && !serviceNames.contains('HBASE') && !serviceNames.contains('STORM') && !serviceNames.contains('YARN'));
     if (this.get('content.skipSlavesStep')) {
@@ -172,8 +191,8 @@ App.AddServiceController = App.WizardController.extend({
    * @param {string} serviceName
    * @returns {boolean}
    */
-  isServiceConfigurable: function(serviceName) {
-    return this.get('serviceConfigs').mapProperty('serviceName').contains(serviceName);
+  isServiceNotConfigurable: function(serviceName) {
+    return App.get('services.noConfigTypes').contains(serviceName);
   },
 
   /**
@@ -184,7 +203,7 @@ App.AddServiceController = App.WizardController.extend({
     var skipConfigStep = true;
     var selectedServices = this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false).mapProperty('serviceName');
     selectedServices.map(function(serviceName) {
-      skipConfigStep = skipConfigStep && !this.isServiceConfigurable(serviceName);
+      skipConfigStep = skipConfigStep && this.isServiceNotConfigurable(serviceName);
     }, this);
     return skipConfigStep;
   },

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/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 ee1336f..0db4b50 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -34,7 +34,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
   globalConfigs: [],
   uiConfigs: [],
   customConfig: [],
-  serviceConfigsData: require('data/service_configs'),
   isApplyingChanges: false,
   saveConfigsFlag: true,
   putClusterConfigsCallsNumber: null,
@@ -228,7 +227,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     var selectedConfigGroup;
     var siteToTagMap = {};
     var hostsLength = App.router.get('mainHostController.hostsCountMap.TOTAL');
-    serviceConfigsDef.sites.forEach(function(siteName){
+    serviceConfigsDef.get('configTypes').forEach(function(siteName){
       if(data.Clusters.desired_configs[siteName]){
         siteToTagMap[siteName] = data.Clusters.desired_configs[siteName].tag;
       } else {
@@ -537,7 +536,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    * @method loadConfigs
    */
   loadConfigs: function(configs, componentConfig) {
-    var serviceConfigsData = this.get('serviceConfigsData').findProperty('serviceName', this.get('content.serviceName'));
+    var serviceConfigsData = App.StackService.find().findProperty('serviceName', this.get('content.serviceName'));
     var defaultGroupSelected = this.get('selectedConfigGroup.isDefault');
     configs.forEach(function (_serviceConfigProperty) {
       var serviceConfigProperty = this.createConfigProperty(_serviceConfigProperty, defaultGroupSelected, serviceConfigsData);
@@ -594,18 +593,20 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    * @mrethod setRecommendedDefaults
    */
   setRecommendedDefaults: function (advancedConfigs) {
-    var s = this.get('serviceConfigsData').findProperty('serviceName', this.get('content.serviceName'));
+    var s = App.StackService.find().findProperty('serviceName', this.get('content.serviceName'));
     var dfd = $.Deferred();
-    if (!s.defaultsProviders) {
+    var defaultsProvider = s.get('defaultsProviders');
+    var configsValidator = s.get('configsValidator');
+    if (!defaultsProvider) {
       dfd.resolve();
       return dfd.promise();
     }
-    this.getInfoForDefaults(s.defaultsProviders);
+    this.getInfoForDefaults(defaultsProvider);
     this.addObserver('defaultsInfo.hosts.length', this, function() {
       var localDB = this.get('defaultsInfo');
       var recommendedDefaults = {};
-      if (s.defaultsProviders) {
-        s.defaultsProviders.forEach(function (defaultsProvider) {
+      if (defaultsProvider) {
+        defaultsProvider.forEach(function (defaultsProvider) {
           var d = defaultsProvider.getDefaults(localDB);
           for (var name in d) {
             if (!!d[name]) {
@@ -619,8 +620,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
           }
         });
       }
-      if (s.configsValidator) {
-        s.configsValidator.set('recommendedDefaults', recommendedDefaults);
+      if (configsValidator) {
+        configsValidator.set('recommendedDefaults', recommendedDefaults);
       }
       dfd.resolve();
     });
@@ -650,10 +651,10 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    */
   setValidator: function(serviceConfigProperty, serviceConfigsData) {
     if (serviceConfigProperty.get('serviceName') === this.get('content.serviceName')) {
-      if (serviceConfigsData.configsValidator) {
-        for (var validatorName in serviceConfigsData.configsValidator.get('configValidators')) {
+      if (serviceConfigsData.get('configsValidator')) {
+        for (var validatorName in serviceConfigsData.get('configsValidator.configValidators')) {
           if (serviceConfigProperty.get("name") == validatorName) {
-            serviceConfigProperty.set('serviceValidator', serviceConfigsData.configsValidator);
+            serviceConfigProperty.set('serviceValidator', serviceConfigsData.get('configsValidator'));
           }
         }
       }
@@ -1798,7 +1799,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    */
   setHostForService: function(serviceName, componentName, hostProperty, multiple) {
     var globalConfigs = this.get('globalConfigs');
-    var serviceConfigs = this.get('serviceConfigs').findProperty('serviceName', serviceName).configs;
+    var serviceConfigs = this.get('serviceConfigs').findProperty('serviceName', serviceName).get('configs');
     var hostConfig = serviceConfigs.findProperty('name', hostProperty);
     if (hostConfig) {
       hostConfig.defaultValue = this.getMasterComponentHostValue(componentName, multiple);

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/service/item.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/item.js b/ambari-web/app/controllers/main/service/item.js
index c93259e..89e6c60 100644
--- a/ambari-web/app/controllers/main/service/item.js
+++ b/ambari-web/app/controllers/main/service/item.js
@@ -43,6 +43,15 @@ App.MainServiceItemController = Em.Controller.extend({
       's': 'stop'
     }
   },
+
+  isClientsOnlyService: function() {
+    return App.get('services.clientOnly').contains(this.get('content.serviceName'));
+  }.property('content.serviceName'),
+
+  isConfigurable: function () {
+    return !App.get('services.noConfigTypes').concat('HCATALOG').contains('content.serviceName');
+  }.property('App.services.noConfigTypes','content.serviceName'),
+
   /**
    * Common method for ajax (start/stop service) responses
    * @param data
@@ -301,8 +310,7 @@ App.MainServiceItemController = Em.Controller.extend({
    */
   refreshConfigs: function () {
     var self = this;
-
-    if (this.get('content.isClientsOnly')) {
+    if (this.get('isClientsOnlyService')) {
       return App.showConfirmationFeedBackPopup(function (query) {
         batchUtils.getComponentsFromServer({
           services: [self.get('content.serviceName')]

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/service/reassign/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/reassign/step2_controller.js b/ambari-web/app/controllers/main/service/reassign/step2_controller.js
index 8964c1b..977cb4e 100644
--- a/ambari-web/app/controllers/main/service/reassign/step2_controller.js
+++ b/ambari-web/app/controllers/main/service/reassign/step2_controller.js
@@ -55,7 +55,7 @@ App.ReassignMasterWizardStep2Controller = App.WizardStep5Controller.extend({
         selectedHost: master.hostName,
         isInstalled: true,
         serviceId: App.HostComponent.find().findProperty('componentName', master.component).get('serviceName'),
-        isHiveCoHost: ['HIVE_METASTORE', 'WEBHCAT_SERVER'].contains(master.component),
+        isServiceCoHost: ['HIVE_METASTORE', 'WEBHCAT_SERVER'].contains(master.component),
         color: color
       });
     }, this);

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/main/service/reassign_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/reassign_controller.js b/ambari-web/app/controllers/main/service/reassign_controller.js
index 167e179..febe092 100644
--- a/ambari-web/app/controllers/main/service/reassign_controller.js
+++ b/ambari-web/app/controllers/main/service/reassign_controller.js
@@ -141,14 +141,31 @@ App.ReassignMasterController = App.WizardController.extend({
    * Load services data from server.
    */
   loadServicesFromServer: function () {
-    var apiService = this.loadServiceComponents();
-    apiService.forEach(function (item, index) {
-      apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
-      apiService[index].isDisabled = apiService[index].isSelected;
-      apiService[index].isInstalled = apiService[index].isSelected;
-    });
-    this.set('content.services', apiService);
-    App.db.setService(apiService);
+    var services = this.getDBProperty('services');
+    if (!services) {
+      services = {
+        selectedServices: [],
+        installedServices: []
+      };
+      App.StackService.find().forEach(function(item){
+        var isInstalled = App.Service.find().someProperty('id', item.get('serviceName'));
+        item.set('isSelected', isInstalled);
+        item.set('isInstalled', isInstalled);
+        if (isInstalled) {
+          services.selectedServices.push(item.get('serviceName'));
+          services.installedServices.push(item.get('serviceName'));
+        }
+      },this);
+      this.setDBProperty('services',services);
+    } else {
+      App.StackService.find().forEach(function(item) {
+        var isSelected =   services.selectedServices.contains(item.get('serviceName'));
+        var isInstalled = services.installedServices.contains(item.get('serviceName'));
+        item.set('isSelected', isSelected);
+        item.set('isInstalled', isInstalled);
+      },this);
+    }
+    this.set('content.services', App.StackService.find());
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index b48b6d9..c21ee96 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -55,7 +55,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
   },
 
   slaveComponents: function () {
-    return App.StackServiceComponent.find().filterProperty('isSlave',true);
+    return App.StackServiceComponent.find().filterProperty('isSlave', true);
   }.property('App.router.clusterController.isLoaded'),
 
   allHosts: function () {
@@ -511,10 +511,20 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
   loadedServiceComponents: null,
 
   /**
+   * Clean store from already loaded data.
+   **/
+  clearStackModels: function () {
+    if (App.StackService.find().get('content').length) {
+      App.StackServiceComponent.find().set('content', []);
+      App.StackService.find().set('content', []);
+    }
+  },
+  /**
    * Generate serviceComponents as pr the stack definition  and save it to localdata
    * called form stepController step4WizardController
    */
   loadServiceComponents: function () {
+    this.clearStackModels();
     App.ajax.send({
       name: 'wizard.service_components',
       sender: this,
@@ -526,14 +536,40 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
       success: 'loadServiceComponentsSuccessCallback',
       error: 'loadServiceComponentsErrorCallback'
     });
-    return this.get('loadedServiceComponents');
   },
 
   loadServiceComponentsSuccessCallback: function (jsonData) {
-    this.setServices(jsonData);
-    this.setServiceComponents(jsonData);
-    console.log("TRACE: getService ajax call  -> In success function for the getServiceComponents call");
-    console.log("TRACE: jsonData.services : " + jsonData.items);
+    var savedSelectedServices = this.getDBProperty('selectedServiceNames');
+    var savedInstalledServices = this.getDBProperty('installedServiceNames');
+    this.set('content.selectedServiceNames', savedSelectedServices);
+    this.set('content.installedServiceNames', savedInstalledServices);
+    if (!savedSelectedServices) {
+      jsonData.items.forEach(function (service) {
+        service.StackServices.is_selected = true;
+      }, this);
+    } else {
+      jsonData.items.forEach(function (service) {
+        if (savedSelectedServices.contains(service.StackServices.service_name))
+          service.StackServices.is_selected = true;
+        else
+          service.StackServices.is_selected = false;
+      }, this);
+    }
+
+    if (!savedInstalledServices) {
+      jsonData.items.forEach(function (service) {
+        service.StackServices.is_installed = false;
+      }, this);
+    } else {
+      jsonData.items.forEach(function (service) {
+        if (savedInstalledServices.contains(service.StackServices.service_name))
+          service.StackServices.is_installed = true;
+        else
+          service.StackServices.is_installed = false;
+      }, this);
+    }
+
+    App.stackServiceMapper.map(jsonData);
   },
 
   loadServiceComponentsErrorCallback: function (request, ajaxOptions, error) {
@@ -543,64 +579,6 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
   },
 
   /**
-   *
-   * @param jsonData
-   */
-  setServices: function(jsonData) {
-    var displayOrderConfig = require('data/services');
-    // Creating Model
-    var Service = Ember.Object.extend({
-      serviceName: null,
-      displayName: null,
-      isDisabled: true,
-      isSelected: true,
-      isInstalled: false,
-      description: null,
-      version: null
-    });
-
-    var data = [];
-    // loop through all the service components
-    for (var i = 0; i < displayOrderConfig.length; i++) {
-      var entry = jsonData.items.findProperty("StackServices.service_name", displayOrderConfig[i].serviceName);
-      if (entry) {
-        var myService = Service.create({
-          serviceName: entry.StackServices.service_name,
-          displayName: displayOrderConfig[i].displayName,
-          isDisabled: displayOrderConfig[i].isDisabled,
-          isSelected: displayOrderConfig[i].isSelected,
-          canBeSelected: displayOrderConfig[i].canBeSelected,
-          isInstalled: false,
-          isHidden: displayOrderConfig[i].isHidden,
-          description: entry.StackServices.comments,
-          version: entry.StackServices.service_version
-        });
-
-        data.push(myService);
-      }
-      else {
-        console.warn('Service not found - ', displayOrderConfig[i].serviceName);
-      }
-    }
-
-    this.set('loadedServiceComponents', data);
-  },
-
-  /**
-   *
-   * @param jsonData
-   */
-  setServiceComponents: function(jsonData) {
-    var serviceComponents = require('utils/component').loadStackServiceComponentModel(jsonData);
-    this.setDBProperty('serviceComponents', serviceComponents);
-  },
-
-  loadServicesFromServer: function () {
-    var apiService = this.loadServiceComponents();
-    this.set('content.services', apiService);
-    this.setDBProperty('service', apiService);
-  },
-  /**
    * Load config groups from local DB
    */
   loadServiceConfigGroups: function () {
@@ -800,10 +778,13 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
    */
   loadAdvancedConfigs: function (dependentController) {
     var self = this;
-    var counter = this.get('content.services').filterProperty('isSelected').length;
+    var stackServices = this.get('content.services').filter(function(service){
+      return service.get('isInstalled') || service.get('isSelected');
+    }).mapProperty('serviceName');
+    var counter = stackServices.length;
     var loadAdvancedConfigResult = [];
     dependentController.set('isAdvancedConfigLoaded', false);
-    this.get('content.services').filterProperty('isSelected').mapProperty('serviceName').forEach(function (_serviceName) {
+    stackServices.forEach(function (_serviceName) {
       App.config.loadAdvancedConfig(_serviceName, function (properties) {
         loadAdvancedConfigResult.pushObjects(properties);
         counter--;
@@ -857,18 +838,18 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
       // check for configs that need to update for installed services
       if (stepController.get('installedServiceNames') && stepController.get('installedServiceNames').contains(_content.get('serviceName'))) {
         // get only modified configs
-        var configs = _content.get('configs').filterProperty('isNotDefaultValue').filter(function(config) {
+        var configs = _content.get('configs').filterProperty('isNotDefaultValue').filter(function (config) {
           var notAllowed = ['masterHost', 'masterHosts', 'slaveHosts', 'slaveHost'];
           return !notAllowed.contains(config.get('displayType'));
         });
         // if modified configs detected push all service's configs for update
         if (configs.length)
-          updateServiceConfigProperties = updateServiceConfigProperties.concat(serviceConfigProperties.filterProperty('serviceName',_content.get('serviceName')));
+          updateServiceConfigProperties = updateServiceConfigProperties.concat(serviceConfigProperties.filterProperty('serviceName', _content.get('serviceName')));
         // watch for properties that are not modified but have to be updated
         if (_content.get('configs').someProperty('forceUpdate')) {
           // check for already added modified properties
           if (!updateServiceConfigProperties.findProperty('serviceName', _content.get('serviceName'))) {
-            updateServiceConfigProperties = updateServiceConfigProperties.concat(serviceConfigProperties.filterProperty('serviceName',_content.get('serviceName')));
+            updateServiceConfigProperties = updateServiceConfigProperties.concat(serviceConfigProperties.filterProperty('serviceName', _content.get('serviceName')));
           }
         }
       }
@@ -923,7 +904,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
     var components = this.get('slaveComponents');
     var result = [];
     var installedServices = App.Service.find().mapProperty('serviceName');
-    var selectedServices = this.get('content.services').filterProperty('isSelected', true).mapProperty('serviceName');
+    var selectedServices = App.StackService.find().filterProperty('isSelected', true).mapProperty('serviceName');
     var installedComponentsMap = {};
     var uninstalledComponents = [];
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/00f8d5c5/ambari-web/app/controllers/wizard/step4_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step4_controller.js b/ambari-web/app/controllers/wizard/step4_controller.js
index 9b8acac..65213ff 100644
--- a/ambari-web/app/controllers/wizard/step4_controller.js
+++ b/ambari-web/app/controllers/wizard/step4_controller.js
@@ -42,7 +42,7 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @type {bool}
    */
   isAll: function () {
-    return this.filterProperty('canBeSelected', true).everyProperty('isSelected', true);
+    return this.everyProperty('isSelected', true);
   }.property('@each.isSelected'),
 
   /**
@@ -50,96 +50,15 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @type {bool}
    */
   isMinimum: function () {
-    return this.filterProperty('isDisabled', false).everyProperty('isSelected', false);
+    return this.everyProperty('isSelected', false);
   }.property('@each.isSelected'),
 
   /**
-   * submit checks describe dependency rules between services
-   * checkCallback - callback, which check for dependency
-   * popupParams - parameters for popup
-   * @type {{checkCallback: string, popupParams: Ember.Enumerable}[]}
-   */
-  submitChecks: [
-    {
-      checkCallback: 'needToAddMapReduce',
-      popupParams: [
-        {serviceName: 'MAPREDUCE', selected: true},
-        'mapreduceCheck'
-      ]
-    },
-    {
-      checkCallback: 'noDFSs',
-      popupParams: [
-        {serviceName: 'HDFS', selected: true},
-        'hdfsCheck'
-      ]
-    },
-    {
-      checkCallback: 'needToAddYarnMapReduce2',
-      popupParams: [
-        {serviceName: 'YARN', selected: true},
-        'yarnCheck'
-      ]
-    },
-    {
-      checkCallback: 'needToAddZooKeeper',
-      popupParams: [
-        {serviceName: 'ZOOKEEPER', selected: true},
-        'zooKeeperCheck'
-      ]
-    },
-    {
-      checkCallback: 'multipleDFSs',
-      popupParams: [
-        [
-          {serviceName: 'HDFS', selected: true},
-          {serviceName: 'GLUSTERFS', selected: false}
-        ],
-        'multipleDFS'
-      ]
-    },
-    {
-      checkCallback: 'needToAddOozie',
-      popupParams: [
-        {serviceName: 'OOZIE', selected: true},
-        'oozieCheck'
-      ]
-    },
-    {
-      checkCallback: 'needToAddTez',
-      popupParams: [
-        {serviceName: 'TEZ', selected: true},
-        'tezCheck'
-      ]
-    }
-  ],
-
-  /**
-   * Update hidden services. Make them to have the same status as master ones.
-   * @method checkDependencies
-   */
-  checkDependencies: function () {
-    var services = {};
-    this.forEach(function (service) {
-      services[service.get('serviceName')] = service;
-    });
-
-    // prevent against getting error when not all elements have been loaded yet
-    if (services['HBASE'] && services['ZOOKEEPER'] && services['HIVE'] && services['HCATALOG'] && services['WEBHCAT']) {
-      if (services['YARN'] && services['MAPREDUCE2']) {
-        services['MAPREDUCE2'].set('isSelected', services['YARN'].get('isSelected'));
-      }
-      services['HCATALOG'].set('isSelected', services['HIVE'].get('isSelected'));
-      services['WEBHCAT'].set('isSelected', services['HIVE'].get('isSelected'));
-    }
-  }.observes('@each.isSelected'),
-
-  /**
    * Onclick handler for <code>select all</code> link
    * @method selectAll
    */
   selectAll: function () {
-    this.filterProperty('canBeSelected', true).setEach('isSelected', true);
+    this.setEach('isSelected', true);
   },
 
   /**
@@ -147,76 +66,7 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method selectMinimum
    */
   selectMinimum: function () {
-    this.filterProperty('isDisabled', false).setEach('isSelected', false);
-  },
-
-  /**
-   * Check whether we should turn on <code>serviceName</code> service according to selected <code>dependentServices</code>
-   * @param serviceName checked service
-   * @param dependentServices list of dependent services
-   * @returns {bool}
-   * @method needAddService
-   */
-  needAddService: function (serviceName, dependentServices) {
-    if (!(dependentServices instanceof Array)) {
-      dependentServices = [dependentServices];
-    }
-    if (this.findProperty('serviceName', serviceName) && this.findProperty('serviceName', serviceName).get('isSelected') === false) {
-      var ds = this.filter(function (item) {
-        return dependentServices.contains(item.get('serviceName')) && item.get('isSelected');
-      });
-      return (ds.get('length') > 0);
-    }
-    return false;
-  },
-
-  /**
-   * Check whether we should turn on <code>Oozie</code> service
-   * @return {bool}
-   * @method needToAddOozie
-   */
-  needToAddOozie: function () {
-    return this.needAddService('OOZIE', ['FALCON']);
-  },
-
-  /**
-   * Check whether we should turn on <code>MapReduce</code> service
-   * @return {bool}
-   * @method needToAddMapReduce
-   */
-  needToAddMapReduce: function () {
-    return this.needAddService('MAPREDUCE', ['PIG', 'OOZIE', 'HIVE']);
-  },
-
-  /**
-   * Check whether we should turn on <code>MapReduce2</code> service
-   * @return {bool}
-   * @method needToAddYarnMapReduce2
-   */
-  needToAddYarnMapReduce2: function () {
-    return this.needAddService('YARN', ['PIG', 'OOZIE', 'HIVE', 'TEZ']);
-  },
-
-  /**
-   * Check whether we should turn on <code>Tez</code> service
-   * @return {bool}
-   * @method needToAddTez
-   */
-  needToAddTez: function () {
-    return this.needAddService('TEZ', ['YARN']);
-  },
-
-  /**
-   * Check whether we should turn on <code>ZooKeeper</code> service
-   * @return {bool}
-   * @method needToAddZooKeeper
-   */
-  needToAddZooKeeper: function () {
-    if (App.get('isHadoop2Stack')) {
-      return this.findProperty('serviceName', 'ZOOKEEPER') && this.findProperty('serviceName', 'ZOOKEEPER').get('isSelected') === false;
-    } else {
-      return this.needAddService('ZOOKEEPER', ['HBASE', 'HIVE', 'WEBHCAT', 'STORM']);
-    }
+    this.setEach('isSelected', false);
   },
 
   /**
@@ -225,8 +75,7 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method noDFSs
    */
   noDFSs: function () {
-    return (this.findProperty('serviceName', 'HDFS').get('isSelected') === false &&
-      (!this.findProperty('serviceName', 'GLUSTERFS') || this.findProperty('serviceName', 'GLUSTERFS').get('isSelected') === false));
+    return  !this.filterProperty('isDFS',true).someProperty('isSelected',true);
   },
 
   /**
@@ -235,8 +84,8 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method multipleDFSs
    */
   multipleDFSs: function () {
-    return (this.findProperty('serviceName', 'HDFS').get('isSelected') === true &&
-      (this.findProperty('serviceName', 'GLUSTERFS') && this.findProperty('serviceName', 'GLUSTERFS').get('isSelected') === true));
+    var dfsServices = this.filterProperty('isDFS',true).filterProperty('isSelected',true);
+	  return  dfsServices.length > 1;
   },
 
   /**
@@ -244,8 +93,9 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @return {bool}
    * @method gangliaOrNagiosNotSelected
    */
-  gangliaOrNagiosNotSelected: function () {
-    return (this.findProperty('serviceName', 'GANGLIA').get('isSelected') === false || this.findProperty('serviceName', 'NAGIOS').get('isSelected') === false);
+  isMonitoringServiceNotSelected: function () {
+    var stackMonitoringServices = this.filterProperty('isMonitoringService',true);
+    return stackMonitoringServices.someProperty('isSelected',false);
   },
 
   /**
@@ -253,8 +103,12 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method validateMonitoring
    */
   validateMonitoring: function () {
-    if (this.gangliaOrNagiosNotSelected()) {
-      this.monitoringCheckPopup();
+    var monitoringServices =  this.filterProperty('isMonitoringService',true);
+    var notSelectedService = monitoringServices.filterProperty('isSelected',false);
+    if (!!notSelectedService.length) {
+      notSelectedService = stringUtils.getFormattedStringFromArray(notSelectedService.mapProperty('displayNameOnSelectServicePage'));
+      monitoringServices = stringUtils.getFormattedStringFromArray(monitoringServices.mapProperty('displayNameOnSelectServicePage'));
+      this.monitoringCheckPopup(notSelectedService,monitoringServices);
     } else {
       App.router.send('next');
     }
@@ -265,22 +119,88 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method submit
    */
   submit: function () {
-    var submitChecks = this.get('submitChecks');
-    var doValidateMonitoring = true;
-    if (!this.get("isSubmitDisabled")) {
-      for (var i = 0; i < submitChecks.length; i++) {
-        if (this[submitChecks[i].checkCallback].call(this)) {
-          doValidateMonitoring = false;
-          this.needToAddServicePopup.apply(this, submitChecks[i].popupParams);
-          break;
+    this.setGroupedServices();
+    if (!this.get("isSubmitDisabled") && !this.isSubmitChecksFailed()) {
+      this.validateMonitoring();
+    }
+  },
+
+  /**
+   * @method  {isSubmitChecksFailed} Do the required checks on Next button click event
+   * @returns {boolean}
+   */
+  isSubmitChecksFailed: function() {
+    return this.isFileSystemCheckFailed() || this.isServiceDependencyCheckFailed();
+  },
+
+  /**
+   * @method: isFileSystemCheckFailed - Checks if a filesystem is selected and only one filesystem is selected
+   * @return: {boolean}
+   */
+  isFileSystemCheckFailed: function() {
+    var isCheckFailed = false;
+    var primaryDFS = this.findProperty('isPrimaryDFS',true);
+    var primaryDfsDisplayName = primaryDFS.get('displayNameOnSelectServicePage');
+    var primaryDfsServiceName = primaryDFS.get('serviceName');
+     if (this.noDFSs()) {
+       isCheckFailed = true;
+       this.needToAddServicePopup.apply(this, [{serviceName: primaryDfsServiceName, selected: true},'fsCheck',primaryDfsDisplayName]);
+     } else if (this.multipleDFSs()) {
+       var dfsServices = this.filterProperty('isDFS',true).filterProperty('isSelected',true).mapProperty('serviceName');
+       var services = dfsServices.map(function (item){
+         var mappedObj = {
+           serviceName: item,
+           selected: false
+         };
+         if (item ===  primaryDfsServiceName) {
+           mappedObj.selected = true;
+         }
+         return mappedObj;
+       });
+       isCheckFailed = true;
+       this.needToAddServicePopup.apply(this, [services,'multipleDFS',primaryDfsDisplayName]);
+     }
+    return isCheckFailed;
+  },
+
+  /**
+   * @method: isServiceDependencyCheckFailed - Checks if a dependent service is selected without selecting the main service
+   * @return {boolean}
+   */
+  isServiceDependencyCheckFailed: function() {
+    var isCheckFailed = false;
+    var notSelectedServices = this.filterProperty('isSelected',false);
+    notSelectedServices.forEach(function(service){
+      var showWarningPopup;
+      var dependentServices =  service.get('dependentServices');
+      if (!!dependentServices) {
+        showWarningPopup = false;
+        dependentServices.forEach(function(_dependentService){
+          var dependentService = this.findProperty('serviceName', _dependentService);
+          if (dependentService.get('isSelected') === true) {
+            showWarningPopup = true;
+            isCheckFailed = true;
+          }
+        },this);
+        if (showWarningPopup) {
+          this.needToAddServicePopup.apply(this, [{serviceName: service.get('serviceName'), selected: true},'serviceCheck',service.get('displayNameOnSelectServicePage')]);
         }
       }
-      if (doValidateMonitoring) {
-        this.validateMonitoring();
-      }
-    }
+    },this);
+    return isCheckFailed;
   },
 
+  setGroupedServices: function() {
+    this.forEach(function(service){
+      var coSelectedServices = service.get('coSelectedServices');
+      coSelectedServices.forEach(function(groupedServiceName) {
+        var groupedService = this.findProperty('serviceName', groupedServiceName);
+        groupedService.set('isSelected',service.get('isSelected'));
+      },this);
+    },this);
+  },
+
+
   /**
    * Select/deselect services
    * @param services array of objects
@@ -294,17 +214,19 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    *    ]
    *  </code>
    * @param {string} i18nSuffix
+   * @param {string} serviceName
    * @return {App.ModalPopup}
    * @method needToAddServicePopup
    */
-  needToAddServicePopup: function (services, i18nSuffix) {
+
+  needToAddServicePopup: function(services, i18nSuffix, serviceName) {
     if (!(services instanceof Array)) {
       services = [services];
     }
     var self = this;
     return App.ModalPopup.show({
-      header: Em.I18n.t('installer.step4.' + i18nSuffix + '.popup.header'),
-      body: Em.I18n.t('installer.step4.' + i18nSuffix + '.popup.body'),
+      header: Em.I18n.t('installer.step4.' + i18nSuffix + '.popup.header').format(serviceName),
+      body: Em.I18n.t('installer.step4.' + i18nSuffix + '.popup.body').format(serviceName),
       onPrimary: function () {
         services.forEach(function (service) {
           self.findProperty('serviceName', service.serviceName).set('isSelected', service.selected);
@@ -320,10 +242,10 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @return {App.ModalPopup}
    * @method monitoringCheckPopup
    */
-  monitoringCheckPopup: function () {
+  monitoringCheckPopup: function (notSelectedServiceNames,monitoringServicesNames) {
     return App.ModalPopup.show({
       header: Em.I18n.t('installer.step4.monitoringCheck.popup.header'),
-      body: Em.I18n.t('installer.step4.monitoringCheck.popup.body'),
+      body: Em.I18n.t('installer.step4.monitoringCheck.popup.body').format(notSelectedServiceNames,monitoringServicesNames),
       onPrimary: function () {
         this.hide();
         App.router.send('next');


Mime
View raw message