Browse Source

AMBARI-6430. Make new services pluggable to the wizard. (jaimin via yusaku)

Yusaku Sako 11 years ago
parent
commit
00f8d5c5c4
77 changed files with 2984 additions and 3266 deletions
  1. 26 144
      ambari-web/app/app.js
  2. 7 2
      ambari-web/app/controllers/global/cluster_controller.js
  3. 25 38
      ambari-web/app/controllers/installer.js
  4. 34 44
      ambari-web/app/controllers/main/admin/cluster.js
  5. 15 10
      ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js
  6. 25 8
      ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
  7. 1 1
      ambari-web/app/controllers/main/admin/misc_controller.js
  8. 26 25
      ambari-web/app/controllers/main/host/add_controller.js
  9. 8 34
      ambari-web/app/controllers/main/service.js
  10. 45 26
      ambari-web/app/controllers/main/service/add_controller.js
  11. 15 14
      ambari-web/app/controllers/main/service/info/configs.js
  12. 10 2
      ambari-web/app/controllers/main/service/item.js
  13. 1 1
      ambari-web/app/controllers/main/service/reassign/step2_controller.js
  14. 25 8
      ambari-web/app/controllers/main/service/reassign_controller.js
  15. 51 70
      ambari-web/app/controllers/wizard.js
  16. 101 179
      ambari-web/app/controllers/wizard/step4_controller.js
  17. 124 154
      ambari-web/app/controllers/wizard/step5_controller.js
  18. 48 116
      ambari-web/app/controllers/wizard/step6_controller.js
  19. 43 40
      ambari-web/app/controllers/wizard/step7_controller.js
  20. 103 51
      ambari-web/app/controllers/wizard/step8_controller.js
  21. 5 31
      ambari-web/app/controllers/wizard/step9_controller.js
  22. 58 60
      ambari-web/app/data/HDP2/global_properties.js
  23. 69 69
      ambari-web/app/data/HDP2/site_properties.js
  24. 49 50
      ambari-web/app/data/global_properties.js
  25. 0 368
      ambari-web/app/data/review_configs.js
  26. 7 272
      ambari-web/app/data/service_configs.js
  27. 0 189
      ambari-web/app/data/services.js
  28. 23 23
      ambari-web/app/data/site_properties.js
  29. 1 1
      ambari-web/app/mappers.js
  30. 3 2
      ambari-web/app/mappers/service_metrics_mapper.js
  31. 90 0
      ambari-web/app/mappers/stack_service_mapper.js
  32. 7 15
      ambari-web/app/messages.js
  33. 2 1
      ambari-web/app/mixins.js
  34. 10 24
      ambari-web/app/mixins/models/service_mixin.js
  35. 1 0
      ambari-web/app/models.js
  36. 1 5
      ambari-web/app/models/host_component.js
  37. 2 55
      ambari-web/app/models/service.js
  38. 382 0
      ambari-web/app/models/stack_service.js
  39. 142 4
      ambari-web/app/models/stack_service_component.js
  40. 0 2
      ambari-web/app/routes/add_host_routes.js
  41. 1 2
      ambari-web/app/routes/add_service_routes.js
  42. 3 2
      ambari-web/app/routes/installer.js
  43. 1 1
      ambari-web/app/routes/main.js
  44. 38 37
      ambari-web/app/templates/main/admin/highAvailability/step2.hbs
  45. 1 1
      ambari-web/app/templates/main/service/item.hbs
  46. 7 7
      ambari-web/app/templates/wizard/step4.hbs
  47. 22 27
      ambari-web/app/templates/wizard/step5.hbs
  48. 32 29
      ambari-web/app/templates/wizard/step6.hbs
  49. 1 1
      ambari-web/app/templates/wizard/step8.hbs
  50. 1 1
      ambari-web/app/utils/ajax/ajax.js
  51. 0 68
      ambari-web/app/utils/component.js
  52. 146 102
      ambari-web/app/utils/config.js
  53. 44 68
      ambari-web/app/utils/helper.js
  54. 36 0
      ambari-web/app/utils/string_utils.js
  55. 1 2
      ambari-web/app/views/common/configs/services_config.js
  56. 5 0
      ambari-web/app/views/main/host.js
  57. 1 8
      ambari-web/app/views/main/host/addHost/step4_view.js
  58. 4 3
      ambari-web/app/views/main/host/configs_service_menu.js
  59. 4 2
      ambari-web/app/views/main/service/info/summary.js
  60. 5 5
      ambari-web/app/views/main/service/item.js
  61. 16 6
      ambari-web/app/views/main/service/menu.js
  62. 3 2
      ambari-web/app/views/main/service/service.js
  63. 22 5
      ambari-web/app/views/wizard/step5_view.js
  64. 3 10
      ambari-web/app/views/wizard/step6_view.js
  65. 2 14
      ambari-web/test/app_test.js
  66. 10 10
      ambari-web/test/controllers/main/host/add_controller_test.js
  67. 1 0
      ambari-web/test/controllers/main/host/details_test.js
  68. 27 148
      ambari-web/test/controllers/wizard/step4_test.js
  69. 229 415
      ambari-web/test/controllers/wizard/step5_test.js
  70. 0 6
      ambari-web/test/controllers/wizard/step6_test.js
  71. 153 0
      ambari-web/test/controllers/wizard/step8_test.js
  72. 2 0
      ambari-web/test/controllers/wizard/step9_test.js
  73. 3 9
      ambari-web/test/init_model_test.js
  74. 486 65
      ambari-web/test/service_components.js
  75. 0 71
      ambari-web/test/utils/component_test.js
  76. 86 0
      ambari-web/test/utils/helper_test.js
  77. 3 1
      ambari-web/test/views/wizard/step5_view_test.js

+ 26 - 144
ambari-web/app/app.js

@@ -88,154 +88,28 @@ module.exports = Em.Application.create({
   }.property('router.clusterController.isLoaded', 'isHadoop2Stack'),
   }.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
    * 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')
       return App.StackServiceComponent.find().filterProperty('isAddableToHost', true).mapProperty('componentName')
     }.property('App.router.clusterController.isLoaded'),
     }.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 () {
     slaves: function () {
       return App.StackServiceComponent.find().filterProperty('isMaster', false).filterProperty('isClient', false).mapProperty('componentName')
       return App.StackServiceComponent.find().filterProperty('isMaster', false).filterProperty('isClient', false).mapProperty('componentName')
     }.property('App.router.clusterController.isLoaded'),
     }.property('App.router.clusterController.isLoaded'),

+ 7 - 2
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)
      * 10. update stale_configs of host-components (depends on App.supports.hostOverrides)
      */
      */
     this.loadStackServiceComponents(function (data) {
     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');
       var updater = App.router.get('updateController');
-
-      require('utils/component').loadStackServiceComponentModel(data);
       self.updateLoadStatus('stackComponents');
       self.updateLoadStatus('stackComponents');
       updater.updateServices(function () {
       updater.updateServices(function () {
         self.updateLoadStatus('services');
         self.updateLoadStatus('services');

+ 25 - 38
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
    * Load services data. Will be used at <code>Select services(step4)</code> step
    */
    */
   loadServices: function () {
   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;
     return hosts;
   }.property('content.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: [],
   stacks: [],
 
 
   /**
   /**
@@ -391,11 +372,19 @@ App.InstallerController = App.WizardController.extend({
    * @param stepController App.WizardStep4Controller
    * @param stepController App.WizardStep4Controller
    */
    */
   saveServices: function (stepController) {
   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) {
   saveClients: function (stepController) {
     var clients = [];
     var clients = [];
     var serviceComponents = App.StackServiceComponent.find();
     var serviceComponents = App.StackServiceComponent.find();
-
+    var services =
     stepController.get('content').filterProperty('isSelected', true).forEach(function (_service) {
     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({
         clients.pushObject({
-          component_name: client.get('componentName'),
-          display_name: client.get('displayName'),
+          component_name: clientComponent.get('componentName'),
+          display_name: clientComponent.get('displayName'),
           isInstalled: false
           isInstalled: false
         });
         });
-      }
+      },this);
     }, this);
     }, this);
-
     this.setDBProperty('clientInfo', clients);
     this.setDBProperty('clientInfo', clients);
     this.set('content.clients', 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.loadMasterComponentHosts();
         this.loadConfirmedHosts();
         this.loadConfirmedHosts();
       case '4':
       case '4':
+        this.loadStacks();
         this.loadServices();
         this.loadServices();
-        this.loadServiceComponentsDb();
       case '3':
       case '3':
         this.loadConfirmedHosts();
         this.loadConfirmedHosts();
       case '2':
       case '2':

+ 34 - 44
ambari-web/app/controllers/main/admin/cluster.js

@@ -20,15 +20,15 @@ var App = require('app');
 var stringUtils = require('utils/string_utils');
 var stringUtils = require('utils/string_utils');
 
 
 App.MainAdminClusterController = Em.Controller.extend({
 App.MainAdminClusterController = Em.Controller.extend({
-  name:'mainAdminClusterController',
+  name: 'mainAdminClusterController',
   services: [],
   services: [],
   allRepos: [],
   allRepos: [],
   upgradeVersion: '',
   upgradeVersion: '',
   /**
   /**
    * get the newest version of HDP from server
    * 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({
       App.ajax.send({
         name: 'cluster.update_upgrade_version',
         name: 'cluster.update_upgrade_version',
         sender: this,
         sender: this,
@@ -36,25 +36,25 @@ App.MainAdminClusterController = Em.Controller.extend({
         error: 'updateUpgradeVersionErrorCallback'
         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 upgradeVersion = this.get('upgradeVersion') || App.defaultStackVersion;
     var currentVersion = App.get('currentStackVersionNumber');
     var currentVersion = App.get('currentStackVersionNumber');
     upgradeVersion = upgradeVersion.replace(/HDP-/, '');
     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;
       upgradeVersion = (stringUtils.compareVersions(upgradeVersion, version) === -1) ? version : upgradeVersion;
     });
     });
     var currentStack = data.items.findProperty('Versions.stack_version', currentVersion);
     var currentStack = data.items.findProperty('Versions.stack_version', currentVersion);
     var upgradeStack = data.items.findProperty('Versions.stack_version', upgradeVersion);
     var upgradeStack = data.items.findProperty('Versions.stack_version', upgradeVersion);
     var minUpgradeVersion = upgradeStack.Versions.min_upgrade_version;
     var minUpgradeVersion = upgradeStack.Versions.min_upgrade_version;
-    if(minUpgradeVersion && (stringUtils.compareVersions(minUpgradeVersion, currentVersion) === 1)){
+    if (minUpgradeVersion && (stringUtils.compareVersions(minUpgradeVersion, currentVersion) === 1)) {
       upgradeVersion = currentVersion;
       upgradeVersion = currentVersion;
       upgradeStack = currentStack;
       upgradeStack = currentStack;
     }
     }
     upgradeVersion = 'HDP-' + upgradeVersion;
     upgradeVersion = 'HDP-' + upgradeVersion;
     this.set('upgradeVersion', upgradeVersion);
     this.set('upgradeVersion', upgradeVersion);
-    if(currentStack && upgradeStack) {
+    if (currentStack && upgradeStack) {
       this.parseServicesInfo(currentStack, upgradeStack);
       this.parseServicesInfo(currentStack, upgradeStack);
     }
     }
     else {
     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('Error message is: ' + request.responseText);
     console.log('HDP stack doesn\'t have services with defaultStackVersion');
     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
    * 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 nameVersionCombo = App.get('currentStackVersion');
       var stackName = nameVersionCombo.split('-')[0];
       var stackName = nameVersionCombo.split('-')[0];
       var stackVersion = nameVersionCombo.split('-')[1];
       var stackVersion = nameVersionCombo.split('-')[1];
@@ -119,7 +119,7 @@ App.MainAdminClusterController = Em.Controller.extend({
     this.set('allRepos', allRepos);
     this.set('allRepos', allRepos);
   },
   },
 
 
-  loadRepositoriesErrorCallback: function(request, ajaxOptions, error) {
+  loadRepositoriesErrorCallback: function (request, ajaxOptions, error) {
     console.log('Error message is: ' + request.responseText);
     console.log('Error message is: ' + request.responseText);
   },
   },
 
 
@@ -129,42 +129,32 @@ App.MainAdminClusterController = Em.Controller.extend({
   parseServicesInfo: function (currentStack, upgradeStack) {
   parseServicesInfo: function (currentStack, upgradeStack) {
     var result = [];
     var result = [];
     var installedServices = App.Service.find().mapProperty('serviceName');
     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
       // loop through all the service components
-      for (var i = 0; i < displayOrderConfig.length; i++) {
+      displayOrder.forEach(function (_stackServiceName) {
         var entry = currentStack.stackServices.
         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);
     this.set('services', result);
   }
   }

+ 15 - 10
ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js

@@ -25,9 +25,15 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
   name:"highAvailabilityWizardStep2Controller",
   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
    * overrides method in wizardStep5Controller
@@ -53,7 +59,7 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
 
 
       var masterServices = self.get("selectedServicesMasters").filterProperty("selectedHost", item);
       var masterServices = self.get("selectedServicesMasters").filterProperty("selectedHost", item);
       masterServices.forEach(function(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');
           item.set('color','green');
         }else{
         }else{
           item.set('color','grey');
           item.set('color','grey');
@@ -77,14 +83,13 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
    * @param masterComponents
    * @param masterComponents
    */
    */
   renderComponents:function (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 result = [];
 
 
     var curNameNode = masterComponents.findProperty('component_name',"NAMENODE");
     var curNameNode = masterComponents.findProperty('component_name',"NAMENODE");
     curNameNode.isCurNameNode = true;
     curNameNode.isCurNameNode = true;
-    curNameNode.zId = 0;
+    curNameNode.serviceComponentId = 0;
 
 
     //Create JOURNALNODE
     //Create JOURNALNODE
     for (var index = 0; index < 3; index++) {
     for (var index = 0; index < 3; index++) {
@@ -92,11 +97,11 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
         {
         {
           component_name: "JOURNALNODE",
           component_name: "JOURNALNODE",
           display_name: "JournalNode",
           display_name: "JournalNode",
-          isHiveCoHost: false,
+          isServiceCoHost: false,
           isInstalled: false,
           isInstalled: false,
           selectedHost: this.get("hosts")[index].get("host_name"),
           selectedHost: this.get("hosts")[index].get("host_name"),
           serviceId: "HDFS",
           serviceId: "HDFS",
-          zId: index
+          serviceComponentId: index
         }
         }
       )
       )
     }
     }
@@ -105,12 +110,12 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
       {
       {
         component_name: "NAMENODE",
         component_name: "NAMENODE",
         display_name: "NameNode",
         display_name: "NameNode",
-        isHiveCoHost: false,
+        isServiceCoHost: false,
         isInstalled: false,
         isInstalled: false,
         selectedHost: this.get("hosts").mapProperty('host_name').without(curNameNode.selectedHost)[0],
         selectedHost: this.get("hosts").mapProperty('host_name').without(curNameNode.selectedHost)[0],
         serviceId: "HDFS",
         serviceId: "HDFS",
         isAddNameNode: true,
         isAddNameNode: true,
-        zId: 1
+        serviceComponentId: 1
       }
       }
     );
     );
 
 

+ 25 - 8
ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js

@@ -66,14 +66,31 @@ App.HighAvailabilityWizardController = App.WizardController.extend({
    * Load services data from server.
    * Load services data from server.
    */
    */
   loadServicesFromServer: function() {
   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());
   },
   },
 
 
   /**
   /**

+ 1 - 1
ambari-web/app/controllers/main/admin/misc_controller.js

@@ -49,7 +49,7 @@ App.MainAdminMiscController = App.MainServiceInfoConfigsController.extend({
     var loadedClusterSiteToTagMap = {};
     var loadedClusterSiteToTagMap = {};
 
 
     for (var site in data.Clusters.desired_configs) {
     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'];
         loadedClusterSiteToTagMap[site] = data.Clusters.desired_configs[site]['tag'];
       }
       }
     }
     }

+ 26 - 25
ambari-web/app/controllers/main/host/add_controller.js

@@ -99,33 +99,35 @@ App.AddHostController = App.WizardController.extend({
     this.setDBProperty('hosts', dbHosts);
     this.setDBProperty('hosts', dbHosts);
   },
   },
 
 
-  /**
-   * 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
    * Load services data. Will be used at <code>Select services(step4)</code> step
    */
    */
   loadServices: function () {
   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) {
     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) {
       if (client) {
         clients.push({
         clients.push({
           component_name: client.get('componentName'),
           component_name: client.get('componentName'),
@@ -180,7 +182,6 @@ App.AddHostController = App.WizardController.extend({
         });
         });
       }
       }
     }, this);
     }, this);
-
     this.setDBProperty('clientInfo', clients);
     this.setDBProperty('clientInfo', clients);
     this.set('content.clients', clients);
     this.set('content.clients', clients);
     console.log("AddHostController.saveClients: saved list ", clients);
     console.log("AddHostController.saveClients: saved list ", clients);

+ 8 - 34
ambari-web/app/controllers/main/service.js

@@ -20,7 +20,6 @@ var App = require('app');
 
 
 App.MainServiceController = Em.ArrayController.extend({
 App.MainServiceController = Em.ArrayController.extend({
   name:'mainServiceController',
   name:'mainServiceController',
-  stackServices: [],
   content: function(){
   content: function(){
     if(!App.router.get('clusterController.isLoaded')){
     if(!App.router.get('clusterController.isLoaded')){
       return [];
       return [];
@@ -37,46 +36,22 @@ App.MainServiceController = Em.ArrayController.extend({
 
 
   isAllServicesInstalled: function() {
   isAllServicesInstalled: function() {
     if (!this.get('content.content')) return false;
     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) {
     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'),
   }.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(){
   isStartAllDisabled: function(){
     if(this.get('isStartStopAllClicked') == true) {
     if(this.get('isStartStopAllClicked') == true) {
       return 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'),
   }.property('isStartStopAllClicked', 'content.@each.healthStatus'),
   isStopAllDisabled: function(){
   isStopAllDisabled: function(){
     if(this.get('isStartStopAllClicked') == true) {
     if(this.get('isStartStopAllClicked') == true) {
@@ -158,5 +133,4 @@ App.MainServiceController = Em.ArrayController.extend({
     }
     }
     App.router.transitionTo('main.serviceAdd');
     App.router.transitionTo('main.serviceAdd');
   }
   }
-
 });
 });

+ 45 - 26
ambari-web/app/controllers/main/service/add_controller.js

@@ -22,8 +22,6 @@ App.AddServiceController = App.WizardController.extend({
 
 
   name: 'addServiceController',
   name: 'addServiceController',
 
 
-  serviceConfigs:require('data/service_configs'),
-
   totalSteps: 7,
   totalSteps: 7,
 
 
   /**
   /**
@@ -80,7 +78,6 @@ App.AddServiceController = App.WizardController.extend({
       return;
       return;
     }
     }
     var apiService = this.loadServiceComponents();
     var apiService = this.loadServiceComponents();
-    //
     apiService.forEach(function(item, index){
     apiService.forEach(function(item, index){
       apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
       apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
       apiService[index].isDisabled = apiService[index].isSelected;
       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
    * Load services data. Will be used at <code>Select services(step4)</code> step
    */
    */
   loadServices: function () {
   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) {
   saveServices: function (stepController) {
     var serviceNames = [];
     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'));
     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'));
     this.set('content.skipSlavesStep', !serviceNames.contains('MAPREDUCE') && !serviceNames.contains('HBASE') && !serviceNames.contains('STORM') && !serviceNames.contains('YARN'));
     if (this.get('content.skipSlavesStep')) {
     if (this.get('content.skipSlavesStep')) {
@@ -172,8 +191,8 @@ App.AddServiceController = App.WizardController.extend({
    * @param {string} serviceName
    * @param {string} serviceName
    * @returns {boolean}
    * @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 skipConfigStep = true;
     var selectedServices = this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false).mapProperty('serviceName');
     var selectedServices = this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false).mapProperty('serviceName');
     selectedServices.map(function(serviceName) {
     selectedServices.map(function(serviceName) {
-      skipConfigStep = skipConfigStep && !this.isServiceConfigurable(serviceName);
+      skipConfigStep = skipConfigStep && this.isServiceNotConfigurable(serviceName);
     }, this);
     }, this);
     return skipConfigStep;
     return skipConfigStep;
   },
   },

+ 15 - 14
ambari-web/app/controllers/main/service/info/configs.js

@@ -34,7 +34,6 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
   globalConfigs: [],
   globalConfigs: [],
   uiConfigs: [],
   uiConfigs: [],
   customConfig: [],
   customConfig: [],
-  serviceConfigsData: require('data/service_configs'),
   isApplyingChanges: false,
   isApplyingChanges: false,
   saveConfigsFlag: true,
   saveConfigsFlag: true,
   putClusterConfigsCallsNumber: null,
   putClusterConfigsCallsNumber: null,
@@ -228,7 +227,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     var selectedConfigGroup;
     var selectedConfigGroup;
     var siteToTagMap = {};
     var siteToTagMap = {};
     var hostsLength = App.router.get('mainHostController.hostsCountMap.TOTAL');
     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]){
       if(data.Clusters.desired_configs[siteName]){
         siteToTagMap[siteName] = data.Clusters.desired_configs[siteName].tag;
         siteToTagMap[siteName] = data.Clusters.desired_configs[siteName].tag;
       } else {
       } else {
@@ -537,7 +536,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    * @method loadConfigs
    * @method loadConfigs
    */
    */
   loadConfigs: function(configs, componentConfig) {
   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');
     var defaultGroupSelected = this.get('selectedConfigGroup.isDefault');
     configs.forEach(function (_serviceConfigProperty) {
     configs.forEach(function (_serviceConfigProperty) {
       var serviceConfigProperty = this.createConfigProperty(_serviceConfigProperty, defaultGroupSelected, serviceConfigsData);
       var serviceConfigProperty = this.createConfigProperty(_serviceConfigProperty, defaultGroupSelected, serviceConfigsData);
@@ -594,18 +593,20 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    * @mrethod setRecommendedDefaults
    * @mrethod setRecommendedDefaults
    */
    */
   setRecommendedDefaults: function (advancedConfigs) {
   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();
     var dfd = $.Deferred();
-    if (!s.defaultsProviders) {
+    var defaultsProvider = s.get('defaultsProviders');
+    var configsValidator = s.get('configsValidator');
+    if (!defaultsProvider) {
       dfd.resolve();
       dfd.resolve();
       return dfd.promise();
       return dfd.promise();
     }
     }
-    this.getInfoForDefaults(s.defaultsProviders);
+    this.getInfoForDefaults(defaultsProvider);
     this.addObserver('defaultsInfo.hosts.length', this, function() {
     this.addObserver('defaultsInfo.hosts.length', this, function() {
       var localDB = this.get('defaultsInfo');
       var localDB = this.get('defaultsInfo');
       var recommendedDefaults = {};
       var recommendedDefaults = {};
-      if (s.defaultsProviders) {
-        s.defaultsProviders.forEach(function (defaultsProvider) {
+      if (defaultsProvider) {
+        defaultsProvider.forEach(function (defaultsProvider) {
           var d = defaultsProvider.getDefaults(localDB);
           var d = defaultsProvider.getDefaults(localDB);
           for (var name in d) {
           for (var name in d) {
             if (!!d[name]) {
             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();
       dfd.resolve();
     });
     });
@@ -650,10 +651,10 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    */
    */
   setValidator: function(serviceConfigProperty, serviceConfigsData) {
   setValidator: function(serviceConfigProperty, serviceConfigsData) {
     if (serviceConfigProperty.get('serviceName') === this.get('content.serviceName')) {
     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) {
           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) {
   setHostForService: function(serviceName, componentName, hostProperty, multiple) {
     var globalConfigs = this.get('globalConfigs');
     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);
     var hostConfig = serviceConfigs.findProperty('name', hostProperty);
     if (hostConfig) {
     if (hostConfig) {
       hostConfig.defaultValue = this.getMasterComponentHostValue(componentName, multiple);
       hostConfig.defaultValue = this.getMasterComponentHostValue(componentName, multiple);

+ 10 - 2
ambari-web/app/controllers/main/service/item.js

@@ -43,6 +43,15 @@ App.MainServiceItemController = Em.Controller.extend({
       's': 'stop'
       '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
    * Common method for ajax (start/stop service) responses
    * @param data
    * @param data
@@ -301,8 +310,7 @@ App.MainServiceItemController = Em.Controller.extend({
    */
    */
   refreshConfigs: function () {
   refreshConfigs: function () {
     var self = this;
     var self = this;
-
-    if (this.get('content.isClientsOnly')) {
+    if (this.get('isClientsOnlyService')) {
       return App.showConfirmationFeedBackPopup(function (query) {
       return App.showConfirmationFeedBackPopup(function (query) {
         batchUtils.getComponentsFromServer({
         batchUtils.getComponentsFromServer({
           services: [self.get('content.serviceName')]
           services: [self.get('content.serviceName')]

+ 1 - 1
ambari-web/app/controllers/main/service/reassign/step2_controller.js

@@ -55,7 +55,7 @@ App.ReassignMasterWizardStep2Controller = App.WizardStep5Controller.extend({
         selectedHost: master.hostName,
         selectedHost: master.hostName,
         isInstalled: true,
         isInstalled: true,
         serviceId: App.HostComponent.find().findProperty('componentName', master.component).get('serviceName'),
         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
         color: color
       });
       });
     }, this);
     }, this);

+ 25 - 8
ambari-web/app/controllers/main/service/reassign_controller.js

@@ -141,14 +141,31 @@ App.ReassignMasterController = App.WizardController.extend({
    * Load services data from server.
    * Load services data from server.
    */
    */
   loadServicesFromServer: function () {
   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());
   },
   },
 
 
   /**
   /**

+ 51 - 70
ambari-web/app/controllers/wizard.js

@@ -55,7 +55,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
   },
   },
 
 
   slaveComponents: function () {
   slaveComponents: function () {
-    return App.StackServiceComponent.find().filterProperty('isSlave',true);
+    return App.StackServiceComponent.find().filterProperty('isSlave', true);
   }.property('App.router.clusterController.isLoaded'),
   }.property('App.router.clusterController.isLoaded'),
 
 
   allHosts: function () {
   allHosts: function () {
@@ -510,11 +510,21 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
 
 
   loadedServiceComponents: null,
   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
    * Generate serviceComponents as pr the stack definition  and save it to localdata
    * called form stepController step4WizardController
    * called form stepController step4WizardController
    */
    */
   loadServiceComponents: function () {
   loadServiceComponents: function () {
+    this.clearStackModels();
     App.ajax.send({
     App.ajax.send({
       name: 'wizard.service_components',
       name: 'wizard.service_components',
       sender: this,
       sender: this,
@@ -526,14 +536,40 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
       success: 'loadServiceComponentsSuccessCallback',
       success: 'loadServiceComponentsSuccessCallback',
       error: 'loadServiceComponentsErrorCallback'
       error: 'loadServiceComponentsErrorCallback'
     });
     });
-    return this.get('loadedServiceComponents');
   },
   },
 
 
   loadServiceComponentsSuccessCallback: function (jsonData) {
   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) {
   loadServiceComponentsErrorCallback: function (request, ajaxOptions, error) {
@@ -542,64 +578,6 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
     console.log('Step8: Error message is: ' + request.responseText);
     console.log('Step8: Error message is: ' + request.responseText);
   },
   },
 
 
-  /**
-   *
-   * @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
    * Load config groups from local DB
    */
    */
@@ -800,10 +778,13 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
    */
    */
   loadAdvancedConfigs: function (dependentController) {
   loadAdvancedConfigs: function (dependentController) {
     var self = this;
     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 = [];
     var loadAdvancedConfigResult = [];
     dependentController.set('isAdvancedConfigLoaded', false);
     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) {
       App.config.loadAdvancedConfig(_serviceName, function (properties) {
         loadAdvancedConfigResult.pushObjects(properties);
         loadAdvancedConfigResult.pushObjects(properties);
         counter--;
         counter--;
@@ -857,18 +838,18 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
       // check for configs that need to update for installed services
       // check for configs that need to update for installed services
       if (stepController.get('installedServiceNames') && stepController.get('installedServiceNames').contains(_content.get('serviceName'))) {
       if (stepController.get('installedServiceNames') && stepController.get('installedServiceNames').contains(_content.get('serviceName'))) {
         // get only modified configs
         // 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'];
           var notAllowed = ['masterHost', 'masterHosts', 'slaveHosts', 'slaveHost'];
           return !notAllowed.contains(config.get('displayType'));
           return !notAllowed.contains(config.get('displayType'));
         });
         });
         // if modified configs detected push all service's configs for update
         // if modified configs detected push all service's configs for update
         if (configs.length)
         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
         // watch for properties that are not modified but have to be updated
         if (_content.get('configs').someProperty('forceUpdate')) {
         if (_content.get('configs').someProperty('forceUpdate')) {
           // check for already added modified properties
           // check for already added modified properties
           if (!updateServiceConfigProperties.findProperty('serviceName', _content.get('serviceName'))) {
           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 components = this.get('slaveComponents');
     var result = [];
     var result = [];
     var installedServices = App.Service.find().mapProperty('serviceName');
     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 installedComponentsMap = {};
     var uninstalledComponents = [];
     var uninstalledComponents = [];
 
 

+ 101 - 179
ambari-web/app/controllers/wizard/step4_controller.js

@@ -42,7 +42,7 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @type {bool}
    * @type {bool}
    */
    */
   isAll: function () {
   isAll: function () {
-    return this.filterProperty('canBeSelected', true).everyProperty('isSelected', true);
+    return this.everyProperty('isSelected', true);
   }.property('@each.isSelected'),
   }.property('@each.isSelected'),
 
 
   /**
   /**
@@ -50,96 +50,15 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @type {bool}
    * @type {bool}
    */
    */
   isMinimum: function () {
   isMinimum: function () {
-    return this.filterProperty('isDisabled', false).everyProperty('isSelected', false);
+    return this.everyProperty('isSelected', false);
   }.property('@each.isSelected'),
   }.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
    * Onclick handler for <code>select all</code> link
    * @method selectAll
    * @method selectAll
    */
    */
   selectAll: function () {
   selectAll: function () {
-    this.filterProperty('canBeSelected', true).setEach('isSelected', true);
+    this.setEach('isSelected', true);
   },
   },
 
 
   /**
   /**
@@ -147,76 +66,7 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method selectMinimum
    * @method selectMinimum
    */
    */
   selectMinimum: function () {
   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
    * @method noDFSs
    */
    */
   noDFSs: function () {
   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
    * @method multipleDFSs
    */
    */
   multipleDFSs: function () {
   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}
    * @return {bool}
    * @method gangliaOrNagiosNotSelected
    * @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
    * @method validateMonitoring
    */
    */
   validateMonitoring: function () {
   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 {
     } else {
       App.router.send('next');
       App.router.send('next');
     }
     }
@@ -265,22 +119,88 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @method submit
    * @method submit
    */
    */
   submit: function () {
   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
    * Select/deselect services
    * @param services array of objects
    * @param services array of objects
@@ -294,17 +214,19 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    *    ]
    *    ]
    *  </code>
    *  </code>
    * @param {string} i18nSuffix
    * @param {string} i18nSuffix
+   * @param {string} serviceName
    * @return {App.ModalPopup}
    * @return {App.ModalPopup}
    * @method needToAddServicePopup
    * @method needToAddServicePopup
    */
    */
-  needToAddServicePopup: function (services, i18nSuffix) {
+
+  needToAddServicePopup: function(services, i18nSuffix, serviceName) {
     if (!(services instanceof Array)) {
     if (!(services instanceof Array)) {
       services = [services];
       services = [services];
     }
     }
     var self = this;
     var self = this;
     return App.ModalPopup.show({
     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 () {
       onPrimary: function () {
         services.forEach(function (service) {
         services.forEach(function (service) {
           self.findProperty('serviceName', service.serviceName).set('isSelected', service.selected);
           self.findProperty('serviceName', service.serviceName).set('isSelected', service.selected);
@@ -320,10 +242,10 @@ App.WizardStep4Controller = Em.ArrayController.extend({
    * @return {App.ModalPopup}
    * @return {App.ModalPopup}
    * @method monitoringCheckPopup
    * @method monitoringCheckPopup
    */
    */
-  monitoringCheckPopup: function () {
+  monitoringCheckPopup: function (notSelectedServiceNames,monitoringServicesNames) {
     return App.ModalPopup.show({
     return App.ModalPopup.show({
       header: Em.I18n.t('installer.step4.monitoringCheck.popup.header'),
       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 () {
       onPrimary: function () {
         this.hide();
         this.hide();
         App.router.send('next');
         App.router.send('next');

+ 124 - 154
ambari-web/app/controllers/wizard/step5_controller.js

@@ -44,26 +44,28 @@ App.WizardStep5Controller = Em.Controller.extend({
   }.property('content.controllerName'),
   }.property('content.controllerName'),
 
 
   /**
   /**
-   * Is AddServiceWizard used
+   * Is isHighAvailabilityWizard used
    * @type {bool}
    * @type {bool}
    */
    */
-  isAddServiceWizard: function () {
-    return this.get('content.controllerName') == 'addServiceController';
+  isHighAvailabilityWizard: function () {
+    return this.get('content.controllerName') == 'highAvailabilityWizardController';
   }.property('content.controllerName'),
   }.property('content.controllerName'),
 
 
   /**
   /**
-   * Is Hive reassigning
+   * Is AddServiceWizard used
    * @type {bool}
    * @type {bool}
    */
    */
-  isReassignHive: function () {
-    return this.get('servicesMasters').objectAt(0) && this.get('servicesMasters').objectAt(0).component_name == 'HIVE_SERVER' && this.get('isReassignWizard');
-  }.property('isReassignWizard', 'servicesMasters'),
+  isAddServiceWizard: function () {
+    return this.get('content.controllerName') == 'addServiceController';
+  }.property('content.controllerName'),
 
 
   /**
   /**
    * Master components which could be assigned to multiple hosts
    * Master components which could be assigned to multiple hosts
    * @type {string[]}
    * @type {string[]}
    */
    */
-  multipleComponents: ['ZOOKEEPER_SERVER', 'HBASE_MASTER'],
+  multipleComponents: function () {
+    return App.get('components.addableMasterInstallerWizard');
+  }.property('App.components.addableMasterInstallerWizard'),
 
 
   /**
   /**
    * Define state for submit button
    * Define state for submit button
@@ -112,20 +114,13 @@ App.WizardStep5Controller = Em.Controller.extend({
    */
    */
   selectedServicesMasters: [],
   selectedServicesMasters: [],
 
 
+
   /**
   /**
    * Is data for current step loaded
    * Is data for current step loaded
    * @type {bool}
    * @type {bool}
    */
    */
   isLoaded: false,
   isLoaded: false,
 
 
-  /**
-   * Check if HIVE_SERVER component exist (also checks if this is not reassign)
-   * @type {bool}
-   */
-  hasHiveServer: function () {
-    return this.get('selectedServicesMasters').someProperty('component_name', 'HIVE_SERVER') && !this.get('isReassignWizard');
-  }.property('selectedServicesMasters'),
-
   /**
   /**
    * List of host with assigned masters
    * List of host with assigned masters
    * Format:
    * Format:
@@ -198,6 +193,10 @@ App.WizardStep5Controller = Em.Controller.extend({
     this.set('hosts', []);
     this.set('hosts', []);
     this.set('selectedServicesMasters', []);
     this.set('selectedServicesMasters', []);
     this.set('servicesMasters', []);
     this.set('servicesMasters', []);
+    App.StackServiceComponent.find().forEach(function (stackComponent) {
+      stackComponent.set('serviceComponentId', 1);
+    }, this);
+
   },
   },
 
 
   /**
   /**
@@ -209,12 +208,9 @@ App.WizardStep5Controller = Em.Controller.extend({
     this.clearStep();
     this.clearStep();
     this.renderHostInfo();
     this.renderHostInfo();
     this.renderComponents(this.loadComponents());
     this.renderComponents(this.loadComponents());
-
-    this.updateComponent('ZOOKEEPER_SERVER');
-    if (App.supports.multipleHBaseMasters) {
-      this.updateComponent('HBASE_MASTER');
-    }
-
+    this.get('multipleComponents').forEach(function (componentName) {
+      this.updateComponent(componentName);
+    }, this);
     if (!this.get("selectedServicesMasters").filterProperty('isInstalled', false).length) {
     if (!this.get("selectedServicesMasters").filterProperty('isInstalled', false).length) {
       console.log('no master components to add');
       console.log('no master components to add');
       App.router.send('next');
       App.router.send('next');
@@ -222,7 +218,7 @@ App.WizardStep5Controller = Em.Controller.extend({
   },
   },
 
 
   /**
   /**
-   * Used to set showAddControl flag for ZOOKEEPER_SERVER and HBASE_SERVER
+   * Used to set showAddControl flag for installer wizard
    * @method updateComponent
    * @method updateComponent
    */
    */
   updateComponent: function (componentName) {
   updateComponent: function (componentName) {
@@ -230,12 +226,12 @@ App.WizardStep5Controller = Em.Controller.extend({
     if (!component) {
     if (!component) {
       return;
       return;
     }
     }
-    var services = this.get('content.services').filterProperty('isInstalled', true).mapProperty('serviceName');
+    var services = App.StackService.find().filterProperty('isInstalled', true).mapProperty('serviceName');
     var currentService = componentName.split('_')[0];
     var currentService = componentName.split('_')[0];
     var showControl = !services.contains(currentService);
     var showControl = !services.contains(currentService);
 
 
     if (showControl) {
     if (showControl) {
-      if (this.get("selectedServicesMasters").filterProperty("component_name", componentName).length < this.get("hosts.length") && !this.get('isReassignWizard')) {
+      if (this.get("selectedServicesMasters").filterProperty("component_name", componentName).length < this.get("hosts.length") && !this.get('isReassignWizard') && !this.get('isHighAvailabilityWizard')) {
         component.set('showAddControl', true);
         component.set('showAddControl', true);
       } else {
       } else {
         component.set('showRemoveControl', false);
         component.set('showRemoveControl', false);
@@ -289,11 +285,18 @@ App.WizardStep5Controller = Em.Controller.extend({
    * @return {Object[]}
    * @return {Object[]}
    */
    */
   loadComponents: function () {
   loadComponents: function () {
-
-    var services = this.get('content.services').filterProperty('isSelected', true).mapProperty('serviceName'); //list of shown services
-    var selectedServices = this.get('content.services').filterProperty('isSelected').filterProperty('isInstalled', false).mapProperty('serviceName');
-
-    var masterComponents = App.StackServiceComponent.find().filterProperty('isShownOnInstallerAssignMasterPage', true); //get full list from mock data
+    var selectedServices = App.StackService.find().filterProperty('isSelected').mapProperty('serviceName');
+    var installedServices = App.StackService.find().filterProperty('isInstalled').mapProperty('serviceName');
+    var services = installedServices.concat(selectedServices).uniq();
+    var selectedNotInstalledServices = this.get('content.services').filterProperty('isSelected').filterProperty('isInstalled', false).mapProperty('serviceName');
+
+    var masterComponents = [];
+    //get full list from mock data
+    if (this.get('isAddServiceWizard')) {
+      masterComponents = App.StackServiceComponent.find().filterProperty('isShownOnAddServiceAssignMasterPage');
+    } else {
+      masterComponents = App.StackServiceComponent.find().filterProperty('isShownOnInstallerAssignMasterPage');
+    }
     var masterHosts = this.get('content.masterComponentHosts'); //saved to local storage info
     var masterHosts = this.get('content.masterComponentHosts'); //saved to local storage info
 
 
     var resultComponents = [];
     var resultComponents = [];
@@ -303,7 +306,7 @@ App.WizardStep5Controller = Em.Controller.extend({
       // If service is already installed and not being added as a new service then render on UI only those master components
       // If service is already installed and not being added as a new service then render on UI only those master components
       // that have already installed hostComponents.
       // that have already installed hostComponents.
       // NOTE: On upgrade there might be a prior installed service with non-installed newly introduced serviceComponent
       // NOTE: On upgrade there might be a prior installed service with non-installed newly introduced serviceComponent
-      var isNotSelectedService = !selectedServices.contains(services[index]);
+      var isNotSelectedService = !selectedNotInstalledServices.contains(services[index]);
       if (isNotSelectedService) {
       if (isNotSelectedService) {
         componentInfo = componentInfo.filter(function (_component) {
         componentInfo = componentInfo.filter(function (_component) {
           return App.HostComponent.find().someProperty('componentName',_component.get('componentName'));
           return App.HostComponent.find().someProperty('componentName',_component.get('componentName'));
@@ -311,29 +314,29 @@ App.WizardStep5Controller = Em.Controller.extend({
       }
       }
 
 
       componentInfo.forEach(function (_componentInfo) {
       componentInfo.forEach(function (_componentInfo) {
-        if (_componentInfo.get('componentName') == 'ZOOKEEPER_SERVER' || _componentInfo.get('componentName') == 'HBASE_MASTER') {
+        if (this.get('multipleComponents').contains(_componentInfo.get('componentName'))) {
           var savedComponents = masterHosts.filterProperty('component', _componentInfo.get('componentName'));
           var savedComponents = masterHosts.filterProperty('component', _componentInfo.get('componentName'));
           if (savedComponents.length) {
           if (savedComponents.length) {
             savedComponents.forEach(function (item) {
             savedComponents.forEach(function (item) {
               var multipleMasterHost = {};
               var multipleMasterHost = {};
-              multipleMasterHost.display_name = _componentInfo.get('displayName');
               multipleMasterHost.component_name = _componentInfo.get('componentName');
               multipleMasterHost.component_name = _componentInfo.get('componentName');
+              multipleMasterHost.display_name = _componentInfo.get('displayName');
               multipleMasterHost.selectedHost = item.hostName;
               multipleMasterHost.selectedHost = item.hostName;
               multipleMasterHost.serviceId = services[index];
               multipleMasterHost.serviceId = services[index];
               multipleMasterHost.isInstalled = item.isInstalled;
               multipleMasterHost.isInstalled = item.isInstalled;
-              multipleMasterHost.isHiveCoHost = false;
+              multipleMasterHost.isServiceCoHost = false;
               resultComponents.push(multipleMasterHost);
               resultComponents.push(multipleMasterHost);
             })
             })
           } else {
           } else {
-            var zooHosts = this.selectHost(_componentInfo.get('componentName'));
-            zooHosts.forEach(function (_host) {
+            var multipleMasterHosts = this.selectHost(_componentInfo.get('componentName'));
+            multipleMasterHosts.forEach(function (_host) {
               var multipleMasterHost = {};
               var multipleMasterHost = {};
-              multipleMasterHost.display_name = _componentInfo.get('displayName');
               multipleMasterHost.component_name = _componentInfo.get('componentName');
               multipleMasterHost.component_name = _componentInfo.get('componentName');
+              multipleMasterHost.display_name = _componentInfo.get('displayName');
               multipleMasterHost.selectedHost = _host;
               multipleMasterHost.selectedHost = _host;
               multipleMasterHost.serviceId = services[index];
               multipleMasterHost.serviceId = services[index];
               multipleMasterHost.isInstalled = false;
               multipleMasterHost.isInstalled = false;
-              multipleMasterHost.isHiveCoHost = false;
+              multipleMasterHost.isServiceCoHost = false;
               resultComponents.push(multipleMasterHost);
               resultComponents.push(multipleMasterHost);
             });
             });
 
 
@@ -346,7 +349,7 @@ App.WizardStep5Controller = Em.Controller.extend({
           componentObj.selectedHost = savedComponent ? savedComponent.hostName : this.selectHost(_componentInfo.get('componentName'));   // call the method that plays selectNode algorithm or fetches from server
           componentObj.selectedHost = savedComponent ? savedComponent.hostName : this.selectHost(_componentInfo.get('componentName'));   // call the method that plays selectNode algorithm or fetches from server
           componentObj.isInstalled = savedComponent ? savedComponent.isInstalled : false;
           componentObj.isInstalled = savedComponent ? savedComponent.isInstalled : false;
           componentObj.serviceId = services[index];
           componentObj.serviceId = services[index];
-          componentObj.isHiveCoHost = this._isHiveCoHost(_componentInfo.get('componentName'));
+          componentObj.isServiceCoHost = App.StackServiceComponent.find().findProperty('componentName', _componentInfo.get('componentName')).get('isCoHostedComponent') && !this.get('isReassignWizard');
           resultComponents.push(componentObj);
           resultComponents.push(componentObj);
         }
         }
       }, this);
       }, this);
@@ -356,6 +359,8 @@ App.WizardStep5Controller = Em.Controller.extend({
   },
   },
 
 
   /**
   /**
+<<<<<<< HEAD
+=======
    * @param {string} componentName
    * @param {string} componentName
    * @returns {bool}
    * @returns {bool}
    * @private
    * @private
@@ -366,73 +371,58 @@ App.WizardStep5Controller = Em.Controller.extend({
   },
   },
 
 
   /**
   /**
+>>>>>>> apache-ref/trunk
    * Put master components to <code>selectedServicesMasters</code>, which will be automatically rendered in template
    * Put master components to <code>selectedServicesMasters</code>, which will be automatically rendered in template
    * @param {Ember.Enumerable} masterComponents
    * @param {Ember.Enumerable} masterComponents
    * @method renderComponents
    * @method renderComponents
    */
    */
   renderComponents: function (masterComponents) {
   renderComponents: function (masterComponents) {
-    var services = this.get('content.services').filterProperty('isInstalled', true).mapProperty('serviceName'); //list of shown services
-    var showRemoveControlZk = !services.contains('ZOOKEEPER') && masterComponents.filterProperty('component_name', 'ZOOKEEPER_SERVER').length > 1;
-    var showRemoveControlHb = !services.contains('HBASE') && masterComponents.filterProperty('component_name', 'HBASE_MASTER').length > 1;
-    var zid = 1, hid = 1, nid = 1, result = [], self = this;
+    var installedServices = App.StackService.find().filterProperty('isSelected').filterProperty('isInstalled', false).mapProperty('serviceName'); //list of shown services
+    var result = [];
+    var serviceComponentId, previousComponentName;
 
 
     masterComponents.forEach(function (item) {
     masterComponents.forEach(function (item) {
-
-      if (item.component_name == 'SECONDARY_NAMENODE') {
-        if (self.get('isAddServiceWizard')) {
-          if (App.get('isHaEnabled')) {
-            return;
-          }
-        }
-      }
-
+      var serviceComponent = App.StackServiceComponent.find().findProperty('componentName', item.component_name);
+      var showRemoveControl = installedServices.contains(serviceComponent.get('stackService.serviceName')) &&
+        (masterComponents.filterProperty('component_name', item.component_name).length > 1);
       var componentObj = Em.Object.create(item);
       var componentObj = Em.Object.create(item);
       console.log("TRACE: render master component name is: " + item.component_name);
       console.log("TRACE: render master component name is: " + item.component_name);
-
-      if (item.component_name === "ZOOKEEPER_SERVER") {
-        componentObj.set('zId', zid++);
-        componentObj.set("showRemoveControl", showRemoveControlZk);
-      }
-      else {
-        if (App.get('supports.multipleHBaseMasters') && item.component_name === "HBASE_MASTER") {
-          componentObj.set('zId', hid++);
-          componentObj.set("showRemoveControl", showRemoveControlHb);
-        }
-        else {
-          if (item.component_name === "NAMENODE") {
-            componentObj.set('zId', nid++);
-          }
-        }
+      var masterComponent = App.StackServiceComponent.find().findProperty('componentName', item.component_name);
+      if (masterComponent.get('isMasterWithMultipleInstances')) {
+        if (item.component_name !== previousComponentName) serviceComponentId = 1;
+        previousComponentName = item.component_name;
+        componentObj.set('serviceComponentId', serviceComponentId++);
+        componentObj.set("showRemoveControl", showRemoveControl);
       }
       }
       componentObj.set('isHostNameValid', true);
       componentObj.set('isHostNameValid', true);
       result.push(componentObj);
       result.push(componentObj);
     }, this);
     }, this);
-
     this.set("selectedServicesMasters", result);
     this.set("selectedServicesMasters", result);
     if (this.get('isReassignWizard')) {
     if (this.get('isReassignWizard')) {
       var components = result.filterProperty('component_name', this.get('content.reassign.component_name'));
       var components = result.filterProperty('component_name', this.get('content.reassign.component_name'));
       components.setEach('isInstalled', false);
       components.setEach('isInstalled', false);
       this.set('servicesMasters', components);
       this.set('servicesMasters', components);
-    }
-    else {
+    } else {
       this.set('servicesMasters', result);
       this.set('servicesMasters', result);
     }
     }
   },
   },
 
 
   /**
   /**
-   * Update host for components HIVE_METASTORE and WEBHCAT_SERVER according to host with HIVE_SERVER
-   * @method updateHiveCoHosts
+   * Update dependent co-hosted components according to the change in the component host
+   * @method updateCoHosts
    */
    */
-  updateHiveCoHosts: function () {
-    var hiveServer = this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_SERVER'),
-      hiveMetastore = this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_METASTORE'),
-      webHCatServer = this.get('selectedServicesMasters').findProperty('component_name', 'WEBHCAT_SERVER');
-    if (hiveServer && hiveMetastore && webHCatServer) {
-      if (!this.get('isReassignHive') && this.get('servicesMasters').objectAt(0) && !(this.get('servicesMasters').objectAt(0).component_name == 'HIVE_METASTORE')) {
-        hiveMetastore.set('selectedHost', hiveServer.get('selectedHost'))
-      }
-      webHCatServer.set('selectedHost', hiveServer.get('selectedHost'));
-    }
+  updateCoHosts: function () {
+    var components = App.StackServiceComponent.find().filterProperty('isOtherComponentCoHosted');
+    var selectedServicesMasters = this.get('selectedServicesMasters');
+    components.forEach(function (component) {
+      var componentName = component.get('componentName');
+      var hostComponent = selectedServicesMasters.findProperty('component_name', componentName);
+      var dependentCoHosts = component.get('coHostedComponents');
+      dependentCoHosts.forEach(function (coHostedComponent) {
+        var dependentHostComponent = selectedServicesMasters.findProperty('component_name', coHostedComponent);
+        if (hostComponent && dependentHostComponent) dependentHostComponent.set('selectedHost', hostComponent.get('selectedHost'));
+      }, this);
+    }, this);
   }.observes('selectedServicesMasters.@each.selectedHost'),
   }.observes('selectedServicesMasters.@each.selectedHost'),
 
 
   /**
   /**
@@ -441,19 +431,25 @@ App.WizardStep5Controller = Em.Controller.extend({
    * if key more that number of hosts, then return value of that key.
    * if key more that number of hosts, then return value of that key.
    * Value is index of host in hosts array.
    * Value is index of host in hosts array.
    *
    *
-   * @param {number} noOfHosts
-   * @param {object} selectionScheme
+   * @param {object} componentName
+   * @param {object} hosts
    * @return {string}
    * @return {string}
    * @method getHostForComponent
    * @method getHostForComponent
    */
    */
-  getHostForComponent: function (noOfHosts, selectionScheme) {
-    var hosts = this.get('hosts');
+  getHostForComponent: function (componentName, hosts) {
+    var component = App.StackServiceComponent.find().findProperty('componentName', componentName);
+    if (component) {
+      var selectionScheme = App.StackServiceComponent.find().findProperty('componentName', componentName).get('selectionSchemeForMasterComponent');
+    } else {
+      return hosts[0];
+    }
+
     if (hosts.length === 1 || $.isEmptyObject(selectionScheme)) {
     if (hosts.length === 1 || $.isEmptyObject(selectionScheme)) {
       return hosts[0];
       return hosts[0];
     } else {
     } else {
       for (var i in selectionScheme) {
       for (var i in selectionScheme) {
         if (window.isFinite(i)) {
         if (window.isFinite(i)) {
-          if (noOfHosts < window.parseInt(i)) {
+          if (hosts.length < window.parseInt(i)) {
             return hosts[selectionScheme[i]];
             return hosts[selectionScheme[i]];
           }
           }
         }
         }
@@ -463,34 +459,22 @@ App.WizardStep5Controller = Em.Controller.extend({
   },
   },
 
 
   /**
   /**
-   * Get list of hostnames for ZK Server
-   * @param {number} noOfHosts
+   * Get list of host names for master component with multiple instances
+   * @param {Object} component
+   * @param {Object} hosts
    * @returns {string[]}
    * @returns {string[]}
-   * @method getZooKeeperServer
+   * @method getHostsForComponent
    */
    */
-  getZooKeeperServer: function (noOfHosts) {
-    var hosts = this.get('hosts');
-    if (noOfHosts < 3) {
-      return [hosts[0].host_name];
-    } else {
-      return [hosts[0].host_name, hosts[1].host_name, hosts[2].host_name];
+  getHostsForComponent: function (component, hosts) {
+    var defaultNoOfMasterHosts = component.get('defaultNoOfMasterHosts');
+    var masterHosts = [];
+    if (hosts.length < defaultNoOfMasterHosts) {
+      defaultNoOfMasterHosts = hosts.length;
     }
     }
-  },
-
-  /**
-   * Get hostname based on number of available hosts
-   * @param {number} noOfHosts
-   * @returns {string}
-   * @method getServerHost
-   */
-  getServerHost: function (noOfHosts) {
-    var hostNames = this.get('hosts').mapProperty('host_name');
-    var hostExcAmbari = hostNames.without(location.hostname);
-    if (noOfHosts > 1) {
-      return hostExcAmbari[0];
-    } else {
-      return hostNames[0];
+    for (var index = 0; index < defaultNoOfMasterHosts; index++) {
+      masterHosts.push(hosts[index]);
     }
     }
+    return masterHosts;
   },
   },
 
 
   /**
   /**
@@ -500,50 +484,36 @@ App.WizardStep5Controller = Em.Controller.extend({
    * @method selectHost
    * @method selectHost
    */
    */
   selectHost: function (componentName) {
   selectHost: function (componentName) {
-    var noOfHosts = this.get('hosts').length;
-
-    if (componentName === 'KERBEROS_SERVER')
-      return this.getHostForComponent(noOfHosts, {"3": 1, "6": 1, "31": 3, "else": 5}).host_name;
-
-    if (componentName === 'NAMENODE')
-      return this.getHostForComponent(noOfHosts, {"else": 0}).host_name;
-
-    if (componentName === 'SECONDARY_NAMENODE')
-      return this.getHostForComponent(noOfHosts, {"else": 1}).host_name;
-
-    if (componentName === 'HBASE_MASTER')
-      return [this.getHostForComponent(noOfHosts, {"3": 0, "6": 0, "31": 2, "else": 3}).host_name];
-
-    if (componentName === 'ZOOKEEPER_SERVER')
-      return this.getZooKeeperServer(noOfHosts);
-
-    if (['JOBTRACKER', 'HISTORYSERVER', 'RESOURCEMANAGER', 'APP_TIMELINE_SERVER'].contains(componentName))
-      return this.getHostForComponent(noOfHosts, {"3": 1, "6": 1, "31": 1, "else": 2}).host_name;
-
-    if (['OOZIE_SERVER', 'FALCON_SERVER'].contains(componentName))
-      return this.getHostForComponent(noOfHosts, {"3": 1, "6": 1, "31": 2, "else": 3}).host_name;
-
-    if (['HIVE_SERVER', 'HIVE_METASTORE', 'WEBHCAT_SERVER'].contains(componentName))
-      return this.getHostForComponent(noOfHosts, {"3": 1, "6": 1, "31": 2, "else": 4}).host_name;
-
-    if (['STORM_UI_SERVER', 'DRPC_SERVER', 'STORM_REST_API', 'NIMBUS', 'GANGLIA_SERVER', 'NAGIOS_SERVER', 'HUE_SERVER'].contains(componentName))
-      return this.getServerHost(noOfHosts);
-
-    return '';
+    var component = App.StackServiceComponent.find().findProperty('componentName', componentName);
+    var hostNames = this.get('hosts').mapProperty('host_name');
+    if (hostNames.length > 1 && App.StackServiceComponent.find().filterProperty('isNotPreferableOnAmbariServerHost').mapProperty('componentName').contains(componentName)) {
+      hostNames = this.get('hosts').mapProperty('host_name').filter(function (item) {
+        return item !== location.hostname;
+      }, this);
+    }
+    if (this.get('multipleComponents').contains(componentName)) {
+      if (component.get('defaultNoOfMasterHosts') > 1) {
+        return this.getHostsForComponent(component, hostNames);
+      } else {
+        return [this.getHostForComponent(componentName, hostNames)];
+      }
+    } else {
+      return this.getHostForComponent(componentName, hostNames);
+    }
   },
   },
 
 
   /**
   /**
    * On change callback for inputs
    * On change callback for inputs
    * @param {string} componentName
    * @param {string} componentName
    * @param {string} selectedHost
    * @param {string} selectedHost
-   * @param {number} zId
+   * @param {number} serviceComponentId
    * @method assignHostToMaster
    * @method assignHostToMaster
    */
    */
-  assignHostToMaster: function (componentName, selectedHost, zId) {
+  assignHostToMaster: function (componentName, selectedHost, serviceComponentId) {
     var flag = this.isHostNameValid(componentName, selectedHost);
     var flag = this.isHostNameValid(componentName, selectedHost);
-    this.updateIsHostNameValidFlag(componentName, zId, flag);
+    this.updateIsHostNameValidFlag(componentName, serviceComponentId, flag);
     if (zId) {
     if (zId) {
-      this.get('selectedServicesMasters').filterProperty('component_name', componentName).findProperty("zId", zId).set("selectedHost", selectedHost);
+      this.get('selectedServicesMasters').filterProperty('component_name', componentName).findProperty("serviceComponentId", serviceComponentId).set("selectedHost", selectedHost);
     }
     }
     else {
     else {
       this.get('selectedServicesMasters').findProperty("component_name", componentName).set("selectedHost", selectedHost);
       this.get('selectedServicesMasters').findProperty("component_name", componentName).set("selectedHost", selectedHost);
@@ -582,10 +552,10 @@ App.WizardStep5Controller = Em.Controller.extend({
    * @param {bool} flag
    * @param {bool} flag
    * @method updateIsHostNameValidFlag
    * @method updateIsHostNameValidFlag
    */
    */
-  updateIsHostNameValidFlag: function (componentName, zId, flag) {
+  updateIsHostNameValidFlag: function (componentName, serviceComponentId, flag) {
     if (componentName) {
     if (componentName) {
-      if (zId) {
-        this.get('selectedServicesMasters').filterProperty('component_name', componentName).findProperty("zId", zId).set("isHostNameValid", flag);
+      if (serviceComponentId) {
+        this.get('selectedServicesMasters').filterProperty('component_name', componentName).findProperty("serviceComponentId", serviceComponentId).set("isHostNameValid", flag);
       } else {
       } else {
         this.get('selectedServicesMasters').findProperty("component_name", componentName).set("isHostNameValid", flag);
         this.get('selectedServicesMasters').findProperty("component_name", componentName).set("isHostNameValid", flag);
       }
       }
@@ -633,7 +603,7 @@ App.WizardStep5Controller = Em.Controller.extend({
       currentMasters.set("lastObject.showAddControl", false);
       currentMasters.set("lastObject.showAddControl", false);
       currentMasters.set("lastObject.showRemoveControl", true);
       currentMasters.set("lastObject.showRemoveControl", true);
 
 
-      //create a new zookeeper based on an existing one
+      //create a new master component host based on an existing one
       newMaster = Em.Object.create({});
       newMaster = Em.Object.create({});
       lastMaster = currentMasters.get("lastObject");
       lastMaster = currentMasters.get("lastObject");
       newMaster.set("display_name", lastMaster.get("display_name"));
       newMaster.set("display_name", lastMaster.get("display_name"));
@@ -659,7 +629,7 @@ App.WizardStep5Controller = Em.Controller.extend({
       }
       }
 
 
       newMaster.set("selectedHost", suggestedHost);
       newMaster.set("selectedHost", suggestedHost);
-      newMaster.set("zId", (currentMasters.get("lastObject.zId") + 1));
+      newMaster.set("serviceComponentId", (currentMasters.get("lastObject.serviceComponentId") + 1));
 
 
       this.get("selectedServicesMasters").insertAt(this.get("selectedServicesMasters").indexOf(lastMaster) + 1, newMaster);
       this.get("selectedServicesMasters").insertAt(this.get("selectedServicesMasters").indexOf(lastMaster) + 1, newMaster);
 
 
@@ -674,19 +644,19 @@ App.WizardStep5Controller = Em.Controller.extend({
   /**
   /**
    * Remove component from ZooKeeper server or Hbase Master
    * Remove component from ZooKeeper server or Hbase Master
    * @param {string} componentName
    * @param {string} componentName
-   * @param {number} zId
+   * @param {number} serviceComponentId
    * @return {bool} true - removed, false - no
    * @return {bool} true - removed, false - no
    * @method removeComponent
    * @method removeComponent
    */
    */
-  removeComponent: function (componentName, zId) {
+  removeComponent: function (componentName, serviceComponentId) {
     var currentMasters = this.get("selectedServicesMasters").filterProperty("component_name", componentName);
     var currentMasters = this.get("selectedServicesMasters").filterProperty("component_name", componentName);
 
 
-    //work only if the Zookeeper service is selected in previous step
+    //work only if the multiple master service is selected in previous step
     if (currentMasters.length <= 1) {
     if (currentMasters.length <= 1) {
       return false;
       return false;
     }
     }
 
 
-    this.get("selectedServicesMasters").removeAt(this.get("selectedServicesMasters").indexOf(currentMasters.findProperty("zId", zId)));
+    this.get("selectedServicesMasters").removeAt(this.get("selectedServicesMasters").indexOf(currentMasters.findProperty("serviceComponentId", serviceComponentId)));
 
 
     currentMasters = this.get("selectedServicesMasters").filterProperty("component_name", componentName);
     currentMasters = this.get("selectedServicesMasters").filterProperty("component_name", componentName);
     if (currentMasters.get("length") < this.get("hosts.length")) {
     if (currentMasters.get("length") < this.get("hosts.length")) {

+ 48 - 116
ambari-web/app/controllers/wizard/step6_controller.js

@@ -51,13 +51,6 @@ App.WizardStep6Controller = Em.Controller.extend({
    */
    */
   headers: [],
   headers: [],
 
 
-  /**
-   * true - assign ZK, HB
-   * false - slaves and clients
-   * @type {bool}
-   */
-  isMasters: false,
-
   /**
   /**
    * @type {bool}
    * @type {bool}
    */
    */
@@ -80,7 +73,7 @@ App.WizardStep6Controller = Em.Controller.extend({
   }.property('content.controllerName'),
   }.property('content.controllerName'),
 
 
   /**
   /**
-   * Check if <code>addHerviceWizard</code> used
+   * Check if <code>addServiceWizard</code> used
    * @type {bool}
    * @type {bool}
    */
    */
   isAddServiceWizard: function () {
   isAddServiceWizard: function () {
@@ -118,21 +111,16 @@ App.WizardStep6Controller = Em.Controller.extend({
     }
     }
 
 
     if (this.get('isAddHostWizard')) {
     if (this.get('isAddHostWizard')) {
-      if (this.get('isMasters')) {
-        this.set('errorMessage', '');
-      }
-      else {
-        hosts.forEach(function (host) {
-          isError = false;
-          headers.forEach(function (header) {
-            isError |= host.get('checkboxes').findProperty('title', header.get('label')).checked;
-          });
-          isError = !isError;
-          if (!isError) {
-            self.set('errorMessage', '');
-          }
+      hosts.forEach(function (host) {
+        isError = false;
+        headers.forEach(function (header) {
+          isError |= host.get('checkboxes').findProperty('title', header.get('label')).checked;
         });
         });
-      }
+        isError = !isError;
+        if (!isError) {
+          self.set('errorMessage', '');
+        }
+      });
     }
     }
   },
   },
 
 
@@ -195,8 +183,11 @@ App.WizardStep6Controller = Em.Controller.extend({
    * @method isServiceSelected
    * @method isServiceSelected
    */
    */
   isServiceSelected: function (name) {
   isServiceSelected: function (name) {
-    return !!(this.get('content.services').findProperty('serviceName', name) &&
-      this.get('content.services').findProperty('serviceName', name).get('isSelected'));
+    var serviceName = this.get('content.services').findProperty('serviceName', name);
+    if (!serviceName) {
+      return !!serviceName;
+    }
+    return serviceName.get('isSelected') || serviceName.get('isInstalled');
   },
   },
 
 
   /**
   /**
@@ -225,16 +216,6 @@ App.WizardStep6Controller = Em.Controller.extend({
     this.clearError();
     this.clearError();
   },
   },
 
 
-  /**
-   * Get <code>displayName</code> for component by <code>componentName</code>
-   * @param componentName
-   * @returns {string}
-   * @method getComponentDisplayName
-   */
-  getComponentDisplayName: function (componentName) {
-    return App.StackServiceComponent.find().findProperty('componentName', componentName).get('displayName');
-  },
-
   /**
   /**
    * Init step6 data
    * Init step6 data
    * @method loadStep
    * @method loadStep
@@ -245,82 +226,39 @@ App.WizardStep6Controller = Em.Controller.extend({
 
 
     console.log("WizardStep6Controller: Loading step6: Assign Slaves");
     console.log("WizardStep6Controller: Loading step6: Assign Slaves");
     this.clearStep();
     this.clearStep();
+    var selectedServices = App.StackService.find().filterProperty('isSelected');
+    var installedServices = App.StackService.find().filterProperty('isInstalled');
+    var services;
+    if (this.get('isInstallerWizard')) services = selectedServices;
+    else if (this.get('isAddHostWizard')) services = installedServices;
+    else if (this.get('isAddServiceWizard')) services = installedServices.concat(selectedServices);
 
 
     var headers = Em.A([]);
     var headers = Em.A([]);
+    services.forEach(function (stackService) {
+      stackService.get('serviceComponents').forEach(function (serviceComponent) {
+        if (serviceComponent.get('isShownOnInstallerSlaveClientPage')) {
+          headers.pushObject(Em.Object.create({
+            name: serviceComponent.get('componentName'),
+            label: serviceComponent.get('displayName'),
+            allChecked: false,
+            noChecked: true
+          }));
+        }
+      }, this);
+    }, this);
 
 
-    if (this.get('isMasters')) {
-      if (this.isServiceSelected('HBASE') && App.supports.multipleHBaseMasters) {
-        headers.pushObject(Em.Object.create({
-          name: 'HBASE_MASTER',
-          label: self.getComponentDisplayName('HBASE_MASTER')
-        }));
-      }
-      if (this.isServiceSelected('ZOOKEEPER')) {
-        headers.pushObject(Em.Object.create({
-          name: 'ZOOKEEPER_SERVER',
-          label: self.getComponentDisplayName('ZOOKEEPER_SERVER')
-        }));
-      }
-    }
-    else {
-      if (this.isServiceSelected('HDFS')) {
-        headers.pushObject(Em.Object.create({
-          name: 'DATANODE',
-          label: self.getComponentDisplayName('DATANODE')
-        }));
-      }
-      if (this.isServiceSelected('MAPREDUCE')) {
-        headers.pushObject(Em.Object.create({
-          name: 'TASKTRACKER',
-          label: self.getComponentDisplayName('TASKTRACKER')
-        }));
-      }
-      if (this.isServiceSelected('YARN')) {
-        headers.pushObject(Em.Object.create({
-          name: 'NODEMANAGER',
-          label: self.getComponentDisplayName('NODEMANAGER')
-        }));
-      }
-      if (this.isServiceSelected('HBASE')) {
-        headers.pushObject(Em.Object.create({
-          name: 'HBASE_REGIONSERVER',
-          label: self.getComponentDisplayName('HBASE_REGIONSERVER')
-        }));
-      }
-      if (this.isServiceSelected('STORM')) {
-        headers.pushObject(Em.Object.create({
-          name: 'SUPERVISOR',
-          label: self.getComponentDisplayName('SUPERVISOR')
-        }));
-      }
-      if (this.isServiceSelected('FLUME')) {
-        headers.pushObject(Em.Object.create({
-          name: 'FLUME_HANDLER',
-          label: self.getComponentDisplayName('FLUME_HANDLER')
-        }));
-      }
-      headers.pushObject(Em.Object.create({
-        name: 'CLIENT',
-        label: App.format.role('CLIENT')
-      }));
-    }
-
-    headers.forEach(function (header) {
-      header.setProperties({ allChecked: false, noChecked: true });
-    });
+    headers.pushObject(Em.Object.create({
+      name: 'CLIENT',
+      label: App.format.role('CLIENT'),
+      allChecked: false,
+      noChecked: true
+    }));
 
 
     this.get('headers').pushObjects(headers);
     this.get('headers').pushObjects(headers);
 
 
     this.render();
     this.render();
-    if (this.get('isMasters')) {
-      if (this.get('content.skipMasterStep')) {
-        App.router.send('next');
-      }
-    }
-    else {
-      if (this.get('content.skipSlavesStep')) {
-        App.router.send('next');
-      }
+    if (this.get('content.skipSlavesStep')) {
+      App.router.send('next');
     }
     }
   },
   },
 
 
@@ -383,13 +321,7 @@ App.WizardStep6Controller = Em.Controller.extend({
     });
     });
     //hosts with master components should be in the beginning of list
     //hosts with master components should be in the beginning of list
     hostsObj.unshift.apply(hostsObj, masterHosts);
     hostsObj.unshift.apply(hostsObj, masterHosts);
-
-    if (this.get('isMasters')) {
-      hostsObj = this.selectMasterComponents(hostsObj);
-    } else {
-      hostsObj = this.renderSlaves(hostsObj);
-    }
-
+    hostsObj = this.renderSlaves(hostsObj);
     this.set('hosts', hostsObj);
     this.set('hosts', hostsObj);
     headers.forEach(function (header) {
     headers.forEach(function (header) {
       this.checkCallback(header.get('name'));
       this.checkCallback(header.get('name'));
@@ -404,7 +336,6 @@ App.WizardStep6Controller = Em.Controller.extend({
    * @method renderSlaves
    * @method renderSlaves
    */
    */
   renderSlaves: function (hostsObj) {
   renderSlaves: function (hostsObj) {
-    var self = this;
     var headers = this.get('headers');
     var headers = this.get('headers');
     var slaveComponents = this.get('content.slaveComponentHosts');
     var slaveComponents = this.get('content.slaveComponentHosts');
     if (!slaveComponents) { // we are at this page for the first time
     if (!slaveComponents) { // we are at this page for the first time
@@ -416,9 +347,11 @@ App.WizardStep6Controller = Em.Controller.extend({
         checkboxes.findProperty('title', headers.findProperty('name', 'CLIENT').get('label')).set('checked', false);
         checkboxes.findProperty('title', headers.findProperty('name', 'CLIENT').get('label')).set('checked', false);
         // First not Master should have Client (only first!)
         // First not Master should have Client (only first!)
         if (!client_is_set) {
         if (!client_is_set) {
-          if (self.isServiceSelected("HDFS")) {
-            var checkboxDatanode = checkboxes.findProperty('title', headers.findProperty('name', 'DATANODE').get('label'));
-            if (checkboxDatanode && checkboxDatanode.get('checked')) {
+          var dfs = App.StackService.find().findProperty('isPrimaryDFS');
+          if (dfs.get('isSelected') || dfs.get('isInstalled')) {
+            var checkboxServiceComponent = checkboxes.findProperty('title', headers.findProperty('name', dfs.get('serviceComponents').
+              findProperty('isShownOnInstallerSlaveClientPage').get('componentName')).get('label'));
+            if (checkboxServiceComponent && checkboxServiceComponent.get('checked')) {
               checkboxes.findProperty('title', headers.findProperty('name', 'CLIENT').get('label')).set('checked', true);
               checkboxes.findProperty('title', headers.findProperty('name', 'CLIENT').get('label')).set('checked', true);
               client_is_set = true;
               client_is_set = true;
             }
             }
@@ -430,8 +363,7 @@ App.WizardStep6Controller = Em.Controller.extend({
         var lastHost = hostsObj[hostsObj.length - 1];
         var lastHost = hostsObj[hostsObj.length - 1];
         lastHost.get('checkboxes').setEach('checked', true);
         lastHost.get('checkboxes').setEach('checked', true);
       }
       }
-    }
-    else {
+    } else {
       this.get('headers').forEach(function (header) {
       this.get('headers').forEach(function (header) {
         var nodes = slaveComponents.findProperty('componentName', header.get('name'));
         var nodes = slaveComponents.findProperty('componentName', header.get('name'));
         if (nodes) {
         if (nodes) {

+ 43 - 40
ambari-web/app/controllers/wizard/step7_controller.js

@@ -43,8 +43,6 @@ App.WizardStep7Controller = Em.Controller.extend({
 
 
   slaveHostToGroup: null,
   slaveHostToGroup: null,
 
 
-  secureConfigs: require('data/secure_mapping'),
-
   /**
   /**
    * If miscConfigChange Modal is shown
    * If miscConfigChange Modal is shown
    * @type {bool}
    * @type {bool}
@@ -131,7 +129,9 @@ App.WizardStep7Controller = Em.Controller.extend({
    * @type {string[]}
    * @type {string[]}
    */
    */
   allSelectedServiceNames: function () {
   allSelectedServiceNames: function () {
-    return this.get('content.services').filterProperty('isSelected').mapProperty('serviceName');
+    return this.get('content.services').filter(function (service) {
+      return service.get('isInstalled') || service.get('isSelected');
+    }).mapProperty('serviceName');
   }.property('content.services').cacheable(),
   }.property('content.services').cacheable(),
 
 
   /**
   /**
@@ -142,7 +142,9 @@ App.WizardStep7Controller = Em.Controller.extend({
   installedServiceNames: function () {
   installedServiceNames: function () {
     var serviceNames = this.get('content.services').filterProperty('isInstalled').mapProperty('serviceName');
     var serviceNames = this.get('content.services').filterProperty('isInstalled').mapProperty('serviceName');
     if (this.get('content.controllerName') !== 'installerController') {
     if (this.get('content.controllerName') !== 'installerController') {
-      return serviceNames.without('SQOOP').without('HCATALOG');
+      serviceNames = serviceNames.filter(function(_serviceName){
+        return !App.get('services.noConfigTypes').concat('HCATALOG').contains(_serviceName);
+      });
     }
     }
     return serviceNames;
     return serviceNames;
   }.property('content.services').cacheable(),
   }.property('content.services').cacheable(),
@@ -260,7 +262,7 @@ App.WizardStep7Controller = Em.Controller.extend({
     var serviceName = params.serviceName,
     var serviceName = params.serviceName,
       service = this.get('stepConfigs').findProperty('serviceName', serviceName),
       service = this.get('stepConfigs').findProperty('serviceName', serviceName),
       defaultConfigGroupHosts = this.get('wizardController.allHosts').mapProperty('hostName'),
       defaultConfigGroupHosts = this.get('wizardController.allHosts').mapProperty('hostName'),
-      siteToTagMap = this._createSiteToTagMap(data.Clusters.desired_configs, params.serviceConfigsDef.sites),
+      siteToTagMap = this._createSiteToTagMap(data.Clusters.desired_configs, params.serviceConfigsDef.get('configTypes')),
       selectedConfigGroup;
       selectedConfigGroup;
 
 
     this.set('loadedClusterSiteToTagMap', siteToTagMap);
     this.set('loadedClusterSiteToTagMap', siteToTagMap);
@@ -362,11 +364,11 @@ App.WizardStep7Controller = Em.Controller.extend({
    * @method _getRecommendedDefaultsForComponent
    * @method _getRecommendedDefaultsForComponent
    */
    */
   _getRecommendedDefaultsForComponent: function (serviceName) {
   _getRecommendedDefaultsForComponent: function (serviceName) {
-    var s = this.get('serviceConfigsData').findProperty('serviceName', serviceName),
+    var s = App.StackService.find(serviceName),
       recommendedDefaults = {},
       recommendedDefaults = {},
       localDB = this.getInfoForDefaults();
       localDB = this.getInfoForDefaults();
-    if (s.defaultsProviders) {
-      s.defaultsProviders.forEach(function (defaultsProvider) {
+    if (s.get('defaultsProvider')) {
+      s.get('defaultsProvider').forEach(function (defaultsProvider) {
         var d = defaultsProvider.getDefaults(localDB);
         var d = defaultsProvider.getDefaults(localDB);
         for (var name in d) {
         for (var name in d) {
           if (d.hasOwnProperty(name)) {
           if (d.hasOwnProperty(name)) {
@@ -384,7 +386,7 @@ App.WizardStep7Controller = Em.Controller.extend({
    * @slaveComponentHosts - contains slaves and clients as well
    * @slaveComponentHosts - contains slaves and clients as well
    * @returns {{masterComponentHosts: Array, slaveComponentHosts: Array, hosts: {}}}
    * @returns {{masterComponentHosts: Array, slaveComponentHosts: Array, hosts: {}}}
    */
    */
-  getInfoForDefaults: function() {
+  getInfoForDefaults: function () {
     var slaveComponentHosts = [];
     var slaveComponentHosts = [];
     var hosts = this.get('content.hosts');
     var hosts = this.get('content.hosts');
     var slaveHostMap = {};
     var slaveHostMap = {};
@@ -407,7 +409,7 @@ App.WizardStep7Controller = Em.Controller.extend({
 
 
     //push slaves and clients into @slaveComponentHosts
     //push slaves and clients into @slaveComponentHosts
     for (var componentName in slaveHostMap) {
     for (var componentName in slaveHostMap) {
-      if(slaveHostMap[componentName].length > 0) {
+      if (slaveHostMap[componentName].length > 0) {
         slaveComponentHosts.push({
         slaveComponentHosts.push({
           componentName: componentName,
           componentName: componentName,
           hosts: slaveHostMap[componentName]
           hosts: slaveHostMap[componentName]
@@ -415,7 +417,7 @@ App.WizardStep7Controller = Em.Controller.extend({
       }
       }
     }
     }
 
 
-    var masterComponentHosts = App.HostComponent.find().filterProperty('isMaster', true).map(function(item) {
+    var masterComponentHosts = App.HostComponent.find().filterProperty('isMaster', true).map(function (item) {
       return {
       return {
         component: item.get('componentName'),
         component: item.get('componentName'),
         serviceId: item.get('service.serviceName'),
         serviceId: item.get('service.serviceName'),
@@ -531,12 +533,12 @@ App.WizardStep7Controller = Em.Controller.extend({
    */
    */
   _updateValidatorsForConfig: function (serviceConfigProperty, component, serviceConfigsData) {
   _updateValidatorsForConfig: function (serviceConfigProperty, component, serviceConfigsData) {
     if (serviceConfigProperty.get('serviceName') === component.get('serviceName')) {
     if (serviceConfigProperty.get('serviceName') === component.get('serviceName')) {
-      if (serviceConfigsData.configsValidator) {
-        var validators = serviceConfigsData.configsValidator.get('configValidators');
+      if (serviceConfigsData.get('configsValidator')) {
+        var validators = serviceConfigsData.get('configsValidator').get('configValidators');
         for (var validatorName in validators) {
         for (var validatorName in validators) {
           if (validators.hasOwnProperty(validatorName)) {
           if (validators.hasOwnProperty(validatorName)) {
             if (serviceConfigProperty.get('name') == validatorName) {
             if (serviceConfigProperty.get('name') == validatorName) {
-              serviceConfigProperty.set('serviceValidator', serviceConfigsData.configsValidator);
+              serviceConfigProperty.set('serviceValidator', serviceConfigsData.get('configsValidator'));
             }
             }
           }
           }
         }
         }
@@ -556,12 +558,12 @@ App.WizardStep7Controller = Em.Controller.extend({
    * @method loadComponentConfigs
    * @method loadComponentConfigs
    */
    */
   loadComponentConfigs: function (configs, componentConfig, component) {
   loadComponentConfigs: function (configs, componentConfig, component) {
-    var s = this.get('serviceConfigsData').findProperty('serviceName', component.get('serviceName')),
+    var s = App.StackService.find(component.get('serviceName')),
       defaultGroupSelected = component.get('selectedConfigGroup.isDefault');
       defaultGroupSelected = component.get('selectedConfigGroup.isDefault');
 
 
-    if (s.configsValidator) {
+    if (s && s.get('configsValidator')) {
       var recommendedDefaults = this._getRecommendedDefaultsForComponent(component.get('serviceName'));
       var recommendedDefaults = this._getRecommendedDefaultsForComponent(component.get('serviceName'));
-      s.configsValidator.set('recommendedDefaults', recommendedDefaults);
+      s.get('configsValidator').set('recommendedDefaults', recommendedDefaults);
     }
     }
 
 
     configs.forEach(function (serviceConfigProperty) {
     configs.forEach(function (serviceConfigProperty) {
@@ -640,6 +642,9 @@ App.WizardStep7Controller = Em.Controller.extend({
       return;
       return;
     }
     }
     this.clearStep();
     this.clearStep();
+    App.config.setPreDefinedGlobalProperties();
+    App.config.setPreDefinedServiceConfigs();
+
     //STEP 1: Load advanced configs
     //STEP 1: Load advanced configs
     var advancedConfigs = this.get('content.advancedServiceConfig');
     var advancedConfigs = this.get('content.advancedServiceConfig');
     //STEP 2: Load on-site configs by service from local DB
     //STEP 2: Load on-site configs by service from local DB
@@ -718,7 +723,7 @@ App.WizardStep7Controller = Em.Controller.extend({
       // Remove SNameNode if HA is enabled
       // Remove SNameNode if HA is enabled
       if (App.get('isHaEnabled')) {
       if (App.get('isHaEnabled')) {
         var c = serviceConfigs.findProperty('serviceName', 'HDFS').configs;
         var c = serviceConfigs.findProperty('serviceName', 'HDFS').configs;
-        var removedConfigs = c.filterProperty('category', 'SNameNode');
+        var removedConfigs = c.filterProperty('category', 'SECONDARY_NAMENODE');
         removedConfigs.map(function (config) {
         removedConfigs.map(function (config) {
           c = c.without(config);
           c = c.without(config);
         });
         });
@@ -765,10 +770,8 @@ App.WizardStep7Controller = Em.Controller.extend({
    */
    */
   getConfigTagsSuccess: function (data) {
   getConfigTagsSuccess: function (data) {
     var installedServiceSites = [];
     var installedServiceSites = [];
-    this.get('serviceConfigsData').filter(function (service) {
-      if (this.get('installedServiceNames').contains(service.serviceName)) {
-        installedServiceSites = installedServiceSites.concat(service.sites);
-      }
+    App.StackService.find().filterProperty('isSelected').filter(function (service) {
+      installedServiceSites = installedServiceSites.concat(service.get('configTypes'));
     }, this);
     }, this);
     installedServiceSites = installedServiceSites.uniq();
     installedServiceSites = installedServiceSites.uniq();
     var serviceConfigTags = [];
     var serviceConfigTags = [];
@@ -1044,10 +1047,10 @@ App.WizardStep7Controller = Em.Controller.extend({
   },
   },
 
 
   /**
   /**
-    * Check whether hive New MySQL database is on the same host as Ambari server MySQL server
-    * @return {$.ajax|null}
-    * @method checkMySQLHost
-    */
+   * Check whether hive New MySQL database is on the same host as Ambari server MySQL server
+   * @return {$.ajax|null}
+   * @method checkMySQLHost
+   */
   checkMySQLHost: function () {
   checkMySQLHost: function () {
     // get ambari database type and hostname
     // get ambari database type and hostname
     return App.ajax.send({
     return App.ajax.send({
@@ -1081,7 +1084,7 @@ App.WizardStep7Controller = Em.Controller.extend({
    *
    *
    * @method resolveHiveMysqlDatabase
    * @method resolveHiveMysqlDatabase
    **/
    **/
-  resolveHiveMysqlDatabase: function() {
+  resolveHiveMysqlDatabase: function () {
     var hiveService = this.get('content.services').findProperty('serviceName', 'HIVE');
     var hiveService = this.get('content.services').findProperty('serviceName', 'HIVE');
     if (!hiveService || !hiveService.get('isSelected') || hiveService.get('isInstalled')) {
     if (!hiveService || !hiveService.get('isSelected') || hiveService.get('isInstalled')) {
       this.moveNext();
       this.moveNext();
@@ -1089,7 +1092,7 @@ App.WizardStep7Controller = Em.Controller.extend({
     }
     }
     var hiveDBType = this.get('stepConfigs').findProperty('serviceName', 'HIVE').configs.findProperty('name', 'hive_database').value;
     var hiveDBType = this.get('stepConfigs').findProperty('serviceName', 'HIVE').configs.findProperty('name', 'hive_database').value;
     if (hiveDBType == 'New MySQL Database') {
     if (hiveDBType == 'New MySQL Database') {
-      var self= this;
+      var self = this;
       this.checkMySQLHost().done(function () {
       this.checkMySQLHost().done(function () {
         if (self.get('mySQLServerConflict')) {
         if (self.get('mySQLServerConflict')) {
           // error popup before you can proceed
           // error popup before you can proceed
@@ -1100,14 +1103,14 @@ App.WizardStep7Controller = Em.Controller.extend({
             }),
             }),
             secondary: Em.I18n.t('installer.step7.popup.mySQLWarning.button.gotostep5'),
             secondary: Em.I18n.t('installer.step7.popup.mySQLWarning.button.gotostep5'),
             primary: Em.I18n.t('installer.step7.popup.mySQLWarning.button.dismiss'),
             primary: Em.I18n.t('installer.step7.popup.mySQLWarning.button.dismiss'),
-            onSecondary: function (){
+            onSecondary: function () {
               var parent = this;
               var parent = this;
               return App.ModalPopup.show({
               return App.ModalPopup.show({
                 header: Em.I18n.t('installer.step7.popup.mySQLWarning.confirmation.header'),
                 header: Em.I18n.t('installer.step7.popup.mySQLWarning.confirmation.header'),
                 bodyClass: Ember.View.extend({
                 bodyClass: Ember.View.extend({
-                  template: Ember.Handlebars.compile( Em.I18n.t('installer.step7.popup.mySQLWarning.confirmation.body'))
+                  template: Ember.Handlebars.compile(Em.I18n.t('installer.step7.popup.mySQLWarning.confirmation.body'))
                 }),
                 }),
-                onPrimary: function (){
+                onPrimary: function () {
                   this.hide();
                   this.hide();
                   parent.hide();
                   parent.hide();
                   // go back to step 5: assign masters and disable default navigation warning
                   // go back to step 5: assign masters and disable default navigation warning
@@ -1125,7 +1128,7 @@ App.WizardStep7Controller = Em.Controller.extend({
     }
     }
   },
   },
 
 
-  checkDatabaseConnectionTest: function() {
+  checkDatabaseConnectionTest: function () {
     var deferred = $.Deferred();
     var deferred = $.Deferred();
     if (!App.supports.databaseConnection) {
     if (!App.supports.databaseConnection) {
       deferred.resolve();
       deferred.resolve();
@@ -1141,7 +1144,7 @@ App.WizardStep7Controller = Em.Controller.extend({
         ignored: Em.I18n.t('installer.step7.hive.database.new')
         ignored: Em.I18n.t('installer.step7.hive.database.new')
       }
       }
     ];
     ];
-    configMap.forEach(function(config) {
+    configMap.forEach(function (config) {
       var isConnectionNotTested = false;
       var isConnectionNotTested = false;
       var service = this.get('content.services').findProperty('serviceName', config.serviceName);
       var service = this.get('content.services').findProperty('serviceName', config.serviceName);
       if (service && service.get('isSelected') && !service.get('isInstalled')) {
       if (service && service.get('isSelected') && !service.get('isInstalled')) {
@@ -1163,8 +1166,8 @@ App.WizardStep7Controller = Em.Controller.extend({
     }, this);
     }, this);
     var ignoredServices = configMap.filterProperty('isCheckIgnored', true);
     var ignoredServices = configMap.filterProperty('isCheckIgnored', true);
     if (ignoredServices.length) {
     if (ignoredServices.length) {
-      var displayedServiceNames = ignoredServices.mapProperty('serviceName').map(function(serviceName) {
-        return App.Service.DisplayNames[serviceName];
+      var displayedServiceNames = ignoredServices.mapProperty('serviceName').map(function (serviceName) {
+        return this.get('content.services').findProperty('serviceName', serviceName).get('displayName');
       }, this);
       }, this);
       this.showDatabaseConnectionWarningPopup(displayedServiceNames, deferred);
       this.showDatabaseConnectionWarningPopup(displayedServiceNames, deferred);
     }
     }
@@ -1174,17 +1177,17 @@ App.WizardStep7Controller = Em.Controller.extend({
     return deferred;
     return deferred;
   },
   },
 
 
-  showDatabaseConnectionWarningPopup: function(serviceNames, deferred) {
+  showDatabaseConnectionWarningPopup: function (serviceNames, deferred) {
     return App.ModalPopup.show({
     return App.ModalPopup.show({
       header: Em.I18n.t('installer.step7.popup.database.connection.header'),
       header: Em.I18n.t('installer.step7.popup.database.connection.header'),
       body: Em.I18n.t('installer.step7.popup.database.connection.body').format(serviceNames.join(', ')),
       body: Em.I18n.t('installer.step7.popup.database.connection.body').format(serviceNames.join(', ')),
       secondary: Em.I18n.t('common.cancel'),
       secondary: Em.I18n.t('common.cancel'),
       primary: Em.I18n.t('common.proceedAnyway'),
       primary: Em.I18n.t('common.proceedAnyway'),
-      onPrimary: function() {
+      onPrimary: function () {
         deferred.resolve();
         deferred.resolve();
         this._super();
         this._super();
       },
       },
-      onSecondary: function() {
+      onSecondary: function () {
         deferred.reject();
         deferred.reject();
         this._super();
         this._super();
       }
       }
@@ -1193,7 +1196,7 @@ App.WizardStep7Controller = Em.Controller.extend({
   /**
   /**
    * Proceed to the next step
    * Proceed to the next step
    **/
    **/
-  moveNext: function() {
+  moveNext: function () {
     App.router.send('next');
     App.router.send('next');
   },
   },
 
 
@@ -1204,7 +1207,7 @@ App.WizardStep7Controller = Em.Controller.extend({
   submit: function () {
   submit: function () {
     var _this = this;
     var _this = this;
     if (!this.get('isSubmitDisabled')) {
     if (!this.get('isSubmitDisabled')) {
-      this.checkDatabaseConnectionTest().done(function() {
+      this.checkDatabaseConnectionTest().done(function () {
         _this.resolveHiveMysqlDatabase();
         _this.resolveHiveMysqlDatabase();
       });
       });
     }
     }

+ 103 - 51
ambari-web/app/controllers/wizard/step8_controller.js

@@ -27,7 +27,28 @@ App.WizardStep8Controller = Em.Controller.extend({
    * List of raw data about cluster that should be displayed
    * List of raw data about cluster that should be displayed
    * @type {Array}
    * @type {Array}
    */
    */
-  rawContent: require('data/review_configs'),
+  rawContent: [
+    {
+      config_name: 'Admin',
+      display_name: 'Admin Name',
+      config_value: ''
+    },
+    {
+      config_name: 'cluster',
+      display_name: 'Cluster Name',
+      config_value: ''
+    },
+    {
+      config_name: 'hosts',
+      display_name: 'Total Hosts',
+      config_value: ''
+    },
+    {
+      config_name: 'Repo',
+      display_name: 'Local Repository',
+      config_value: ''
+    }
+  ],
 
 
   /**
   /**
    * List of data about cluster (based on formatted <code>rawContent</code>)
    * List of data about cluster (based on formatted <code>rawContent</code>)
@@ -644,19 +665,43 @@ App.WizardStep8Controller = Em.Controller.extend({
    * @method loadServices
    * @method loadServices
    */
    */
   loadServices: function () {
   loadServices: function () {
-    var reviewService = this.get('rawContent').findProperty('config_name', 'services');
-    if (Em.isNone(reviewService)) return;
-
-    var config_value = Em.get(reviewService, 'config_value');
-    if (Em.isNone(config_value)) return;
-
-    this.get('selectedServices').forEach(function (_service) {
-      var serviceObj = config_value.findProperty('service_name', _service.serviceName);
-      if (Em.isNone(serviceObj)) return;
-      serviceObj.get('service_components').forEach(function (_component) {
-        this.assignComponentHosts(_component);
-        console.log(' ---INFO: step8: service component: ' + _service.serviceName);
+    this.get('selectedServices').filterProperty('isHiddenOnSelectServicePage', false).forEach(function (service) {
+      console.log('INFO: step8: Name of the service from getService function: ' + service.get('serviceName'));
+      var serviceObj = Em.Object.create({
+        service_name: service.get('serviceName'),
+        display_name: service.get('displayNameOnSelectServicePage'),
+        service_components: Em.A([])
+      });
+      service.get('serviceComponents').forEach(function(component) {
+        // show clients for services that have only clients components
+        if ((component.get('isClient') || component.get('isClientBehavior')) && !service.get('isClientOnlyService')) return;
+        // skip components that was hide on assign master page
+        if (component.get('isMaster') && !component.get('isShownOnInstallerAssignMasterPage')) return;
+        // no HA component
+        if (App.get('isHaEnabled') && component.get('isHAComponentOnly')) return;
+        var displayName;
+        if (component.get('isClient')) {
+          displayName = Em.I18n.t('common.clients')
+        } else {
+          // remove service name from component display name
+          displayName = component.get('displayName').replace(new RegExp('^' + service.get('serviceName') + '\\s','i'), '');
+        }
+        serviceObj.get('service_components').pushObject(Em.Object.create({
+          component_name: component.get('isClient') ? Em.I18n.t('common.client').toUpperCase() : component.get('componentName'),
+          display_name: displayName,
+          component_value: this.assignComponentHosts(component)
+        }));
       }, this);
       }, this);
+      if (service.get('customReviewHandler')) {
+        for (var displayName in service.get('customReviewHandler')) {
+          serviceObj.get('service_components').pushObject(Em.Object.create({
+            display_name: displayName,
+            component_value: this.assignComponentHosts(Em.Object.create({
+              customHandler: service.get('customReviewHandler.' + displayName)
+            }))
+          }));
+        }
+      }
       this.get('services').pushObject(serviceObj);
       this.get('services').pushObject(serviceObj);
     }, this);
     }, this);
   },
   },
@@ -664,31 +709,35 @@ App.WizardStep8Controller = Em.Controller.extend({
   /**
   /**
    * Set <code>component_value</code> property to <code>component</code>
    * Set <code>component_value</code> property to <code>component</code>
    * @param {Em.Object} component
    * @param {Em.Object} component
+   * @return {String}
    * @method assignComponentHosts
    * @method assignComponentHosts
    */
    */
   assignComponentHosts: function (component) {
   assignComponentHosts: function (component) {
     var componentValue;
     var componentValue;
     if (component.get('customHandler')) {
     if (component.get('customHandler')) {
-      this[component.get('customHandler')].call(this, component);
-      console.log(' --- ---INFO: step8: in customHandler');
+      componentValue = this[component.get('customHandler')].call(this, component);
     }
     }
     else {
     else {
-      console.log(' --- ---INFO: step8: NOT in customHandler');
-      if (component.get('isMaster')) {
-        console.log(' --- ---INFO: step8: component isMaster');
-        componentValue = this.get('content.masterComponentHosts')
-          .findProperty('component', component.component_name).hostName;
+      if (component.get('isMaster') || component.get('isMasterBehavior')) {
+        componentValue = this.getMasterComponentValue(component.get('componentName'));
       }
       }
       else {
       else {
         console.log(' --- ---INFO: step8: NOT component isMaster');
         console.log(' --- ---INFO: step8: NOT component isMaster');
         var hostsLength = this.get('content.slaveComponentHosts')
         var hostsLength = this.get('content.slaveComponentHosts')
-          .findProperty('componentName', component.component_name)
+          .findProperty('componentName', component.get('isClient') ? Em.I18n.t('common.client').toUpperCase() : component.get('componentName'))
           .hosts.length;
           .hosts.length;
         componentValue = hostsLength + Em.I18n.t('installer.step8.host' + ((hostsLength > 1) ? 's' : ''));
         componentValue = hostsLength + Em.I18n.t('installer.step8.host' + ((hostsLength > 1) ? 's' : ''));
       }
       }
-      console.log(' --- --- --- INFO: step8: componentValue: ' + componentValue);
-      component.set('component_value', componentValue);
     }
     }
+    return componentValue;
+  },
+
+  getMasterComponentValue: function(componentName) {
+    var masterComponents = this.get('content.masterComponentHosts');
+    var hostsCount = masterComponents.filterProperty('component', componentName).length;
+    return stringUtils.pluralize(hostsCount,
+      masterComponents.findProperty('component', componentName).hostName,
+      hostsCount + ' ' + Em.I18n.t('installer.step8.hosts'));
   },
   },
 
 
   /**
   /**
@@ -696,26 +745,26 @@ App.WizardStep8Controller = Em.Controller.extend({
    * @param {Ember.Object} dbComponent
    * @param {Ember.Object} dbComponent
    * @method loadHiveDbValue
    * @method loadHiveDbValue
    */
    */
-  loadHiveDbValue: function (dbComponent) {
+  loadHiveDbValue: function () {
     var db,
     var db,
       serviceConfigPreoprties = this.get('wizardController').getDBProperty('serviceConfigProperties'),
       serviceConfigPreoprties = this.get('wizardController').getDBProperty('serviceConfigProperties'),
       hiveDb = serviceConfigPreoprties.findProperty('name', 'hive_database');
       hiveDb = serviceConfigPreoprties.findProperty('name', 'hive_database');
     if (hiveDb.value === 'New MySQL Database') {
     if (hiveDb.value === 'New MySQL Database') {
-      dbComponent.set('component_value', 'MySQL (New Database)');
+      return 'MySQL (New Database)';
     }
     }
     else {
     else {
       if (hiveDb.value === 'Existing MySQL Database') {
       if (hiveDb.value === 'Existing MySQL Database') {
-        db = serviceConfigPreoprties.findProperty('name', 'hive_existing_mysql_database');
-        dbComponent.set('component_value', db.value + ' (' + hiveDb.value + ')');
+        db = serviceConfigPreoprties .findProperty('name', 'hive_existing_mysql_database');
+        return db.value + ' (' + hiveDb.value + ')';
       }
       }
       else {
       else {
         if (hiveDb.value === Em.I18n.t('services.service.config.hive.oozie.postgresql')) {
         if (hiveDb.value === Em.I18n.t('services.service.config.hive.oozie.postgresql')) {
-          db = serviceConfigPreoprties.findProperty('name', 'hive_existing_postgresql_database');
-          dbComponent.set('component_value', db.value + ' (' + hiveDb.value + ')');
+          db = serviceConfigPreoprties .findProperty('name', 'hive_existing_postgresql_database');
+          return db.value + ' (' + hiveDb.value + ')';
         }
         }
         else { // existing oracle database
         else { // existing oracle database
-          db = serviceConfigPreoprties.findProperty('name', 'hive_existing_oracle_database');
-          dbComponent.set('component_value', db.value + ' (' + hiveDb.value + ')');
+          db = serviceConfigPreoprties .findProperty('name', 'hive_existing_oracle_database');
+          return db.value + ' (' + hiveDb.value + ')';
         }
         }
       }
       }
     }
     }
@@ -756,25 +805,25 @@ App.WizardStep8Controller = Em.Controller.extend({
    * @param {Object} dbComponent
    * @param {Object} dbComponent
    * @method loadOozieDbValue
    * @method loadOozieDbValue
    */
    */
-  loadOozieDbValue: function (dbComponent) {
+  loadOozieDbValue: function () {
     var db, oozieDb = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_database');
     var db, oozieDb = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_database');
     if (oozieDb.value === 'New Derby Database') {
     if (oozieDb.value === 'New Derby Database') {
       db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_derby_database');
       db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_derby_database');
-      dbComponent.set('component_value', db.value + ' (' + oozieDb.value + ')');
+      return db.value + ' (' + oozieDb.value + ')';
     }
     }
     else {
     else {
       if (oozieDb.value === 'Existing MySQL Database') {
       if (oozieDb.value === 'Existing MySQL Database') {
         db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_existing_mysql_database');
         db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_existing_mysql_database');
-        dbComponent.set('component_value', db.value + ' (' + oozieDb.value + ')');
+        return db.value + ' (' + oozieDb.value + ')';
       }
       }
       else {
       else {
         if (oozieDb.value === Em.I18n.t('services.service.config.hive.oozie.postgresql')) {
         if (oozieDb.value === Em.I18n.t('services.service.config.hive.oozie.postgresql')) {
           db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_existing_postgresql_database');
           db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_existing_postgresql_database');
-          dbComponent.set('component_value', db.value + ' (' + oozieDb.value + ')');
+          return db.value + ' (' + oozieDb.value + ')';
         }
         }
         else { // existing oracle database
         else { // existing oracle database
           db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_existing_oracle_database');
           db = this.get('wizardController').getDBProperty('serviceConfigProperties').findProperty('name', 'oozie_existing_oracle_database');
-          dbComponent.set('component_value', db.value + ' (' + oozieDb.value + ')');
+          return db.value + ' (' + oozieDb.value + ')';
         }
         }
       }
       }
     }
     }
@@ -785,11 +834,11 @@ App.WizardStep8Controller = Em.Controller.extend({
    * @param {Object} nagiosAdmin
    * @param {Object} nagiosAdmin
    * @method loadNagiosAdminValue
    * @method loadNagiosAdminValue
    */
    */
-  loadNagiosAdminValue: function (nagiosAdmin) {
+  loadNagiosAdminValue: function () {
     var config = this.get('content.serviceConfigProperties');
     var config = this.get('content.serviceConfigProperties');
     var adminLoginName = config.findProperty('name', 'nagios_web_login');
     var adminLoginName = config.findProperty('name', 'nagios_web_login');
     var adminEmail = config.findProperty('name', 'nagios_contact');
     var adminEmail = config.findProperty('name', 'nagios_contact');
-    nagiosAdmin.set('component_value', adminLoginName.value + ' / (' + adminEmail.value + ')');
+    return adminLoginName.value + ' / (' + adminEmail.value + ')';
   },
   },
 
 
   /**
   /**
@@ -1161,6 +1210,19 @@ App.WizardStep8Controller = Em.Controller.extend({
     }, this);
     }, this);
   },
   },
 
 
+  getClientsToMasterMap: function () {
+    var clientNames = App.StackServiceComponent.find().filterProperty('isClient').mapProperty('componentName'),
+        clientsMap = {},
+        dependedComponents = App.StackServiceComponent.find().filterProperty('isMaster');
+    clientNames.forEach(function(clientName) {
+      clientsMap[clientName] = Em.A([]);
+      dependedComponents.forEach(function(component) {
+        if (component.get('dependencies').contains(clientName)) clientsMap[clientName].push(component.get('componentName'));
+      });
+      if (!clientsMap[clientName].length) delete clientsMap[clientName];
+    });
+    return clientsMap;
+  },
   /**
   /**
    * Register slave components and clients
    * Register slave components and clients
    * @uses registerHostsToComponent
    * @uses registerHostsToComponent
@@ -1183,16 +1245,7 @@ App.WizardStep8Controller = Em.Controller.extend({
      *  }
      *  }
      * </code>
      * </code>
      */
      */
-    var clientsToMasterMap = {
-      HDFS_CLIENT: Em.A(['HBASE_MASTER', 'HBASE_REGIONSERVER', 'WEBHCAT_SERVER', 'HISTORYSERVER', 'OOZIE_SERVER']),
-      MAPREDUCE_CLIENT: Em.A(['HIVE_SERVER', 'OOZIE_SERVER', 'NAGIOS_SERVER', 'WEBHCAT_SERVER']),
-      OOZIE_CLIENT: Em.A(['NAGIOS_SERVER']),
-      ZOOKEEPER_CLIENT: Em.A(['WEBHCAT_SERVER']),
-      HIVE_CLIENT: Em.A(['WEBHCAT_SERVER', 'HIVE_SERVER']),
-      HCAT: Em.A(['NAGIOS_SERVER']),
-      YARN_CLIENT: Em.A(['NAGIOS_SERVER', 'HIVE_SERVER', 'OOZIE_SERVER', 'WEBHCAT_SERVER']),
-      TEZ_CLIENT: Em.A(['NAGIOS_SERVER', 'HIVE_SERVER'])
-    };
+    var clientsToMasterMap = this.getClientsToMasterMap();
 
 
     slaveHosts.forEach(function (_slave) {
     slaveHosts.forEach(function (_slave) {
       if (_slave.componentName !== 'CLIENT') {
       if (_slave.componentName !== 'CLIENT') {
@@ -1267,9 +1320,9 @@ App.WizardStep8Controller = Em.Controller.extend({
    */
    */
   createAdditionalHostComponents: function () {
   createAdditionalHostComponents: function () {
     var masterHosts = this.get('content.masterComponentHosts');
     var masterHosts = this.get('content.masterComponentHosts');
-
+    // add MySQL Server if Hive is selected
     // add Ganglia Monitor (Slave) to all hosts if Ganglia service is selected
     // add Ganglia Monitor (Slave) to all hosts if Ganglia service is selected
-    var gangliaService = this.get('content.services').filterProperty('isSelected', true).findProperty('serviceName', 'GANGLIA');
+    var gangliaService = this.get('content.services').filterProperty('isSelected').findProperty('serviceName', 'GANGLIA');
     if (gangliaService) {
     if (gangliaService) {
       var hosts = this.getRegisteredHosts();
       var hosts = this.getRegisteredHosts();
       if (gangliaService.get('isInstalled')) {
       if (gangliaService.get('isInstalled')) {
@@ -1279,7 +1332,6 @@ App.WizardStep8Controller = Em.Controller.extend({
         this.registerHostsToComponent(hosts.mapProperty('hostName'), 'GANGLIA_MONITOR');
         this.registerHostsToComponent(hosts.mapProperty('hostName'), 'GANGLIA_MONITOR');
       }
       }
     }
     }
-    // add MySQL Server if Hive is selected
     var hiveService = this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false).findProperty('serviceName', 'HIVE');
     var hiveService = this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false).findProperty('serviceName', 'HIVE');
     if (hiveService) {
     if (hiveService) {
       var hiveDb = this.get('content.serviceConfigProperties').findProperty('name', 'hive_database');
       var hiveDb = this.get('content.serviceConfigProperties').findProperty('name', 'hive_database');

+ 5 - 31
ambari-web/app/controllers/wizard/step9_controller.js

@@ -16,6 +16,7 @@
  * limitations under the License.
  * limitations under the License.
  */
  */
 var App = require('app');
 var App = require('app');
+var stringUtils = require('utils/string_utils');
 
 
 App.WizardStep9Controller = Em.Controller.extend({
 App.WizardStep9Controller = Em.Controller.extend({
 
 
@@ -474,11 +475,11 @@ App.WizardStep9Controller = Em.Controller.extend({
         data = {
         data = {
           "context": Em.I18n.t("requestInfo.startHostComponents"),
           "context": Em.I18n.t("requestInfo.startHostComponents"),
           "query": "HostRoles/component_name.in(" + App.get('components.slaves').join(',') + ")&HostRoles/state=INSTALLED&HostRoles/host_name.in(" + hostnames.join(',') + ")",
           "query": "HostRoles/component_name.in(" + App.get('components.slaves').join(',') + ")&HostRoles/state=INSTALLED&HostRoles/host_name.in(" + hostnames.join(',') + ")",
-          "HostRoles": { "state": "STARTED" }
+          "HostRoles": { "state": "STARTED"}
         };
         };
         break;
         break;
       case 'addServiceController':
       case 'addServiceController':
-        var servicesList = this.get('content.services').filterProperty('isSelected', true).filterProperty('isDisabled', false).mapProperty('serviceName').join(",");
+        var servicesList = this.get('content.services').filterProperty('isSelected').filterProperty('isInstalled', false).mapProperty('serviceName').join(",");
         name = 'common.services.update';
         name = 'common.services.update';
         data = {
         data = {
           "context": Em.I18n.t("requestInfo.startAddedServices"),
           "context": Em.I18n.t("requestInfo.startAddedServices"),
@@ -1104,7 +1105,7 @@ App.WizardStep9Controller = Em.Controller.extend({
         var componentName = App.format.role(_hostComponent.HostRoles.component_name);
         var componentName = App.format.role(_hostComponent.HostRoles.component_name);
         componentArr.pushObject(componentName);
         componentArr.pushObject(componentName);
       }, this);
       }, this);
-      hostComponentObj.componentNames = this.getComponentMessage(componentArr);
+      hostComponentObj.componentNames = stringUtils.getFormattedStringFromArray(componentArr);
       hostsWithHeartbeatLost.pushObject(hostComponentObj);
       hostsWithHeartbeatLost.pushObject(hostComponentObj);
     }, this);
     }, this);
     this.set('hostsWithHeartbeatLost', hostsWithHeartbeatLost);
     this.set('hostsWithHeartbeatLost', hostsWithHeartbeatLost);
@@ -1145,33 +1146,6 @@ App.WizardStep9Controller = Em.Controller.extend({
     this.saveClusterStatus(clusterStatus);
     this.saveClusterStatus(clusterStatus);
   },
   },
 
 
-  /**
-   * Get formatted string of components to display on the UI
-   * @param componentArr {Array}  Array of components
-   * @returns {String}
-   * @method getComponentMessage
-   */
-  getComponentMessage: function (componentArr) {
-    var label = '';
-    componentArr.forEach(function (_component) {
-      if (componentArr.length === 1) {
-        label = _component;
-      }
-      else {
-        if (_component !== componentArr[componentArr.length - 1]) {           // [clients.length - 1]
-          label = label + ' ' + _component;
-          if (_component !== componentArr[componentArr.length - 2]) {
-            label = label + ',';
-          }
-        }
-        else {
-          label = label + ' ' + Em.I18n.t('and') + ' ' + _component;
-        }
-      }
-    }, this);
-    return label.trim();
-  },
-
   /**
   /**
    * save cluster status in the parentController and localdb
    * save cluster status in the parentController and localdb
    * @param {object} clusterStatus
    * @param {object} clusterStatus
@@ -1197,4 +1171,4 @@ App.WizardStep9Controller = Em.Controller.extend({
     }
     }
   }
   }
 
 
-});
+});

+ 58 - 60
ambari-web/app/data/HDP2/global_properties.js

@@ -92,7 +92,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -106,7 +106,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 2
       "index": 2
     },
     },
     {
     {
@@ -120,7 +120,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -134,7 +134,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 4
       "index": 4
     },
     },
     {
     {
@@ -149,7 +149,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "SNameNode",
+      "category": "SECONDARY_NAMENODE",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -166,7 +166,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "domain": "datanode-global",
       "domain": "datanode-global",
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "DataNode",
+      "category": "DATANODE",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -180,7 +180,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "domain": "datanode-global",
       "domain": "datanode-global",
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "DataNode",
+      "category": "DATANODE",
       "index": 2
       "index": 2
     },
     },
     {
     {
@@ -247,7 +247,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "MAPREDUCE2",
       "serviceName": "MAPREDUCE2",
-      "category": "HistoryServer",
+      "category": "HISTORYSERVER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -261,7 +261,7 @@ module.exports =
       "displayType": "int",
       "displayType": "int",
       "isVisible": true,
       "isVisible": true,
       "serviceName": "MAPREDUCE2",
       "serviceName": "MAPREDUCE2",
-      "category": "HistoryServer",
+      "category": "HISTORYSERVER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -316,7 +316,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "ResourceManager",
+      "category": "RESOURCEMANAGER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -330,7 +330,7 @@ module.exports =
       "unit": "MB",
       "unit": "MB",
       "isVisible": true,
       "isVisible": true,
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "ResourceManager",
+      "category": "RESOURCEMANAGER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -344,7 +344,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "NodeManager",
+      "category": "NODEMANAGER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -358,7 +358,7 @@ module.exports =
       "unit": "MB",
       "unit": "MB",
       "isVisible": true,
       "isVisible": true,
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "NodeManager",
+      "category": "NODEMANAGER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -398,7 +398,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -412,7 +412,7 @@ module.exports =
       "unit": "MB",
       "unit": "MB",
       "isVisible": true,
       "isVisible": true,
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "index": 1
       "index": 1
     },
     },
   /**********************************************HBASE***************************************/
   /**********************************************HBASE***************************************/
@@ -428,7 +428,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HBASE",
       "serviceName": "HBASE",
-      "category": "HBase Master",
+      "category": "HBASE_MASTER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -442,7 +442,7 @@ module.exports =
       "isOverridable": true,
       "isOverridable": true,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HBASE",
       "serviceName": "HBASE",
-      "category": "HBase Master",
+      "category": "HBASE_MASTER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -457,9 +457,8 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "isRequired": false,
       "isRequired": false,
-      "domain": "regionserver-global",
       "serviceName": "HBASE",
       "serviceName": "HBASE",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -471,9 +470,8 @@ module.exports =
       "displayType": "int",
       "displayType": "int",
       "unit": "MB",
       "unit": "MB",
       "isVisible": true,
       "isVisible": true,
-      "domain": "regionserver-global",
       "serviceName": "HBASE",
       "serviceName": "HBASE",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -631,7 +629,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 0
       "index": 0
     },
     },
     // for existing MySQL
     // for existing MySQL
@@ -647,7 +645,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isReconfigurable": false,
       "isReconfigurable": false,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
       "index": 1
     },
     },
     // for existing PostgreSQL
     // for existing PostgreSQL
@@ -663,7 +661,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isReconfigurable": false,
       "isReconfigurable": false,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
       "index": 1
     },
     },
     // for existing Oracle
     // for existing Oracle
@@ -679,7 +677,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isReconfigurable": false,
       "isReconfigurable": false,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
       "index": 1
     },
     },
     // for new MySQL
     // for new MySQL
@@ -694,7 +692,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": false,
       "isVisible": false,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -729,7 +727,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 2
       "index": 2
     },
     },
     {
     {
@@ -744,7 +742,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -760,7 +758,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -776,7 +774,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -792,7 +790,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -808,7 +806,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": false,
       "isVisible": false,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -889,7 +887,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "serviceName": "WEBHCAT",
       "serviceName": "WEBHCAT",
-      "category": "WebHCat Server"
+      "category": "WEBHCAT_SERVER"
     },
     },
     {
     {
       "id": "puppet var",
       "id": "puppet var",
@@ -930,7 +928,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 0
       "index": 0
     },
     },
     // for existing Oracle
     // for existing Oracle
@@ -947,7 +945,7 @@ module.exports =
       "isReconfigurable": false,
       "isReconfigurable": false,
       "isOverridable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
       "index": 1
     },
     },
     // for existing PostgreSQL
     // for existing PostgreSQL
@@ -963,7 +961,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isReconfigurable": false,
       "isReconfigurable": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
       "index": 1
     },
     },
     // for new MySQL
     // for new MySQL
@@ -978,7 +976,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isOverridable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
       "index": 1
     },
     },
     // for current derby
     // for current derby
@@ -994,7 +992,7 @@ module.exports =
       "isReconfigurable": false,
       "isReconfigurable": false,
       "isOverridable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
       "index": 1
     },
     },
     // for existing MySQL oozie
     // for existing MySQL oozie
@@ -1010,7 +1008,7 @@ module.exports =
       "isReconfigurable": false,
       "isReconfigurable": false,
       "isOverridable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -1052,7 +1050,7 @@ module.exports =
       "radioName": "oozie-database",
       "radioName": "oozie-database",
       "isVisible": true,
       "isVisible": true,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 2
       "index": 2
     },
     },
     {
     {
@@ -1068,7 +1066,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isRequired": false,
       "isRequired": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 9
       "index": 9
     },
     },
     {
     {
@@ -1082,7 +1080,7 @@ module.exports =
       "displayType": "host",
       "displayType": "host",
       "isVisible": false,
       "isVisible": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -1097,7 +1095,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -1112,7 +1110,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -1127,7 +1125,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -1143,7 +1141,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server"
+      "category": "OOZIE_SERVER"
     },
     },
     {
     {
       "id": "puppet var",
       "id": "puppet var",
@@ -1235,7 +1233,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isRequired": false,
       "isRequired": false,
       "serviceName": "ZOOKEEPER",
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -1249,7 +1247,7 @@ module.exports =
       "displayType": "directory",
       "displayType": "directory",
       "isVisible": true,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -1263,7 +1261,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 2
       "index": 2
     },
     },
     {
     {
@@ -1276,7 +1274,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -1289,7 +1287,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 4
       "index": 4
     },
     },
     {
     {
@@ -1302,7 +1300,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 5
       "index": 5
     },
     },
     {
     {
@@ -1401,7 +1399,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "serviceName": "FALCON",
       "serviceName": "FALCON",
-      "category": "Falcon"
+      "category": "FALCON_SERVER"
     },
     },
     {
     {
       "id": "puppet var",
       "id": "puppet var",
@@ -1414,7 +1412,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isRequiredByAgent": true,
       "isRequiredByAgent": true,
       "serviceName": "FALCON",
       "serviceName": "FALCON",
-      "category": "Falcon"
+      "category": "FALCON_SERVER"
     },
     },
     {
     {
       "id": "puppet var",
       "id": "puppet var",
@@ -1427,7 +1425,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isRequiredByAgent": true,
       "isRequiredByAgent": true,
       "serviceName": "FALCON",
       "serviceName": "FALCON",
-      "category": "Falcon"
+      "category": "FALCON_SERVER"
     },
     },
     {
     {
       "id": "puppet var",
       "id": "puppet var",
@@ -1440,7 +1438,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isRequiredByAgent": true,
       "isRequiredByAgent": true,
       "serviceName": "FALCON",
       "serviceName": "FALCON",
-      "category": "Falcon"
+      "category": "FALCON_SERVER"
     },
     },
     {
     {
       "id": "puppet var",
       "id": "puppet var",
@@ -1550,7 +1548,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "StormUIServer",
+      "category": "STORM_UI_SERVER",
       "filename": "global.xml"
       "filename": "global.xml"
     },
     },
     {
     {
@@ -1564,7 +1562,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "filename": "global.xml"
       "filename": "global.xml"
     },
     },
     {
     {
@@ -1579,7 +1577,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "serviceName": "STORM",
       "serviceName": "STORM",
       "isOverridable": false,
       "isOverridable": false,
-      "category": "Supervisor",
+      "category": "SUPERVISOR",
       "filename": "global.xml"
       "filename": "global.xml"
     },
     },
     {
     {
@@ -1594,7 +1592,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "serviceName": "STORM",
       "serviceName": "STORM",
       "isOverridable": false,
       "isOverridable": false,
-      "category": "StormRestApi",
+      "category": "STORM_REST_API",
       "filename": "global.xml"
       "filename": "global.xml"
     },
     },
   /**********************************************MISC***************************************/
   /**********************************************MISC***************************************/

+ 69 - 69
ambari-web/app/data/HDP2/site_properties.js

@@ -31,7 +31,7 @@ module.exports =
       "displayType": "directory",
       "displayType": "directory",
       "isOverridable": false,
       "isOverridable": false,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "SNameNode",
+      "category": "SECONDARY_NAMENODE",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -52,7 +52,7 @@ module.exports =
       "displayType": "directories",
       "displayType": "directories",
       "isOverridable": false,
       "isOverridable": false,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -70,7 +70,7 @@ module.exports =
       "name": "dfs.datanode.failed.volumes.tolerated",
       "name": "dfs.datanode.failed.volumes.tolerated",
       "displayName": "DataNode volumes failure toleration",
       "displayName": "DataNode volumes failure toleration",
       "displayType": "int",
       "displayType": "int",
-      "category": "DataNode",
+      "category": "DATANODE",
       "serviceName": "HDFS",
       "serviceName": "HDFS",
       "index": 3
       "index": 3
     },
     },
@@ -80,7 +80,7 @@ module.exports =
       "displayName": "DataNode directories",
       "displayName": "DataNode directories",
       "defaultDirectory": "/hadoop/hdfs/data",
       "defaultDirectory": "/hadoop/hdfs/data",
       "displayType": "directories",
       "displayType": "directories",
-      "category": "DataNode",
+      "category": "DATANODE",
       "serviceName": "HDFS",
       "serviceName": "HDFS",
       "index": 1
       "index": 1
     },
     },
@@ -89,7 +89,7 @@ module.exports =
       "name": "dfs.datanode.data.dir.perm",
       "name": "dfs.datanode.data.dir.perm",
       "displayName": "DataNode directories permission",
       "displayName": "DataNode directories permission",
       "displayType": "int",
       "displayType": "int",
-      "category": "DataNode",
+      "category": "DATANODE",
       "serviceName": "HDFS"
       "serviceName": "HDFS"
     },
     },
     {
     {
@@ -148,7 +148,7 @@ module.exports =
       "displayName": "yarn.acl.enable",
       "displayName": "yarn.acl.enable",
       "displayType": "checkbox",
       "displayType": "checkbox",
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "ResourceManager"
+      "category": "RESOURCEMANAGER"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
@@ -156,7 +156,7 @@ module.exports =
       "displayName": "yarn.admin.acl",
       "displayName": "yarn.admin.acl",
       "isRequired": false,
       "isRequired": false,
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "ResourceManager"
+      "category": "RESOURCEMANAGER"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
@@ -164,7 +164,7 @@ module.exports =
       "displayName": "yarn.log-aggregation-enable",
       "displayName": "yarn.log-aggregation-enable",
       "displayType": "checkbox",
       "displayType": "checkbox",
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "ResourceManager"
+      "category": "RESOURCEMANAGER"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
@@ -195,21 +195,21 @@ module.exports =
       "displayName": "yarn.nodemanager.resource.memory-mb",
       "displayName": "yarn.nodemanager.resource.memory-mb",
       "displayType": "int",
       "displayType": "int",
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
       "name": "yarn.nodemanager.vmem-pmem-ratio",
       "name": "yarn.nodemanager.vmem-pmem-ratio",
       "displayName": "yarn.nodemanager.vmem-pmem-ratio",
       "displayName": "yarn.nodemanager.vmem-pmem-ratio",
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
       "name": "yarn.nodemanager.linux-container-executor.group",
       "name": "yarn.nodemanager.linux-container-executor.group",
       "displayName": "yarn.nodemanager.linux-container-executor.group",
       "displayName": "yarn.nodemanager.linux-container-executor.group",
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
@@ -218,7 +218,7 @@ module.exports =
       "defaultDirectory": "/hadoop/yarn/log",
       "defaultDirectory": "/hadoop/yarn/log",
       "displayType": "directories",
       "displayType": "directories",
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
@@ -227,7 +227,7 @@ module.exports =
       "defaultDirectory": "/hadoop/yarn/local",
       "defaultDirectory": "/hadoop/yarn/local",
       "displayType": "directories",
       "displayType": "directories",
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
@@ -235,28 +235,28 @@ module.exports =
       "displayName": "yarn.nodemanager.remote-app-log-dir",
       "displayName": "yarn.nodemanager.remote-app-log-dir",
       "displayType": "directory",
       "displayType": "directory",
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
       "name": "yarn.nodemanager.remote-app-log-dir-suffix",
       "name": "yarn.nodemanager.remote-app-log-dir-suffix",
       "displayName": "yarn.nodemanager.remote-app-log-dir-suffix",
       "displayName": "yarn.nodemanager.remote-app-log-dir-suffix",
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
       "name": "yarn.nodemanager.aux-services",
       "name": "yarn.nodemanager.aux-services",
       "displayName": "yarn.nodemanager.aux-services",
       "displayName": "yarn.nodemanager.aux-services",
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
       "name": "yarn.nodemanager.log.retain-second",
       "name": "yarn.nodemanager.log.retain-second",
       "displayName": "yarn.nodemanager.log.retain-second",
       "displayName": "yarn.nodemanager.log.retain-second",
       "serviceName": "YARN",
       "serviceName": "YARN",
-      "category": "NodeManager"
+      "category": "NODEMANAGER"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
@@ -269,7 +269,7 @@ module.exports =
       "id": "site property",
       "id": "site property",
       "name": "yarn.timeline-service.enabled",
       "name": "yarn.timeline-service.enabled",
       "displayName": "yarn.timeline-service.enabled",
       "displayName": "yarn.timeline-service.enabled",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "displayType": "checkbox",
       "displayType": "checkbox",
       "serviceName": "YARN"
       "serviceName": "YARN"
     },
     },
@@ -278,7 +278,7 @@ module.exports =
       "name": "yarn.timeline-service.leveldb-timeline-store.path",
       "name": "yarn.timeline-service.leveldb-timeline-store.path",
       "displayName": "yarn.timeline-service.leveldb-timeline-store.path",
       "displayName": "yarn.timeline-service.leveldb-timeline-store.path",
       "defaultDirectory": "/hadoop/yarn/timeline",
       "defaultDirectory": "/hadoop/yarn/timeline",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "displayType": "directory",
       "displayType": "directory",
       "serviceName": "YARN"
       "serviceName": "YARN"
     },
     },
@@ -287,14 +287,14 @@ module.exports =
       "name": "yarn.timeline-service.leveldb-timeline-store.ttl-interval-ms",
       "name": "yarn.timeline-service.leveldb-timeline-store.ttl-interval-ms",
       "displayName": "yarn.timeline-service.leveldb-timeline-store.ttl-interval-ms",
       "displayName": "yarn.timeline-service.leveldb-timeline-store.ttl-interval-ms",
       "displayType": "int",
       "displayType": "int",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
       "serviceName": "YARN"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
       "name": "yarn.timeline-service.store-class",
       "name": "yarn.timeline-service.store-class",
       "displayName": "yarn.timeline-service.store-class",
       "displayName": "yarn.timeline-service.store-class",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
       "serviceName": "YARN"
     },
     },
     {
     {
@@ -302,7 +302,7 @@ module.exports =
       "name": "yarn.timeline-service.ttl-enable",
       "name": "yarn.timeline-service.ttl-enable",
       "displayName": "yarn.timeline-service.ttl-enable",
       "displayName": "yarn.timeline-service.ttl-enable",
       "displayType": "checkbox",
       "displayType": "checkbox",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
       "serviceName": "YARN"
     },
     },
     {
     {
@@ -310,14 +310,14 @@ module.exports =
       "name": "yarn.timeline-service.ttl-ms",
       "name": "yarn.timeline-service.ttl-ms",
       "displayName": "yarn.timeline-service.ttl-ms",
       "displayName": "yarn.timeline-service.ttl-ms",
       "displayType": "int",
       "displayType": "int",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
       "serviceName": "YARN"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
       "name": "yarn.timeline-service.generic-application-history.store-class",
       "name": "yarn.timeline-service.generic-application-history.store-class",
       "displayName": "yarn.timeline-service.generic-application-history.store-class",
       "displayName": "yarn.timeline-service.generic-application-history.store-class",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
       "serviceName": "YARN"
     },
     },
     {
     {
@@ -325,7 +325,7 @@ module.exports =
       "name": "yarn.timeline-service.webapp.address",
       "name": "yarn.timeline-service.webapp.address",
       "displayName": "yarn.timeline-service.webapp.address",
       "displayName": "yarn.timeline-service.webapp.address",
       "displayType": "string",
       "displayType": "string",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
       "serviceName": "YARN"
     },
     },
     {
     {
@@ -333,7 +333,7 @@ module.exports =
       "name": "yarn.timeline-service.webapp.https.address",
       "name": "yarn.timeline-service.webapp.https.address",
       "displayName": "yarn.timeline-service.webapp.https.address",
       "displayName": "yarn.timeline-service.webapp.https.address",
       "displayType": "string",
       "displayType": "string",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
       "serviceName": "YARN"
     },
     },
     {
     {
@@ -341,7 +341,7 @@ module.exports =
       "name": "yarn.timeline-service.address",
       "name": "yarn.timeline-service.address",
       "displayName": "yarn.timeline-service.address",
       "displayName": "yarn.timeline-service.address",
       "displayType": "string",
       "displayType": "string",
-      "category": "AppTimelineServer",
+      "category": "APP_TIMELINE_SERVER",
       "serviceName": "YARN"
       "serviceName": "YARN"
     },
     },
   /**********************************************MAPREDUCE2***************************************/
   /**********************************************MAPREDUCE2***************************************/
@@ -397,7 +397,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "displayType": "host",
       "displayType": "host",
       "isObserved": true,
       "isObserved": true,
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
       "index": 4
       "index": 4
     },
     },
@@ -407,7 +407,7 @@ module.exports =
       "displayName": "Database Username",
       "displayName": "Database Username",
       "isOverridable": false,
       "isOverridable": false,
       "displayType": "host",
       "displayType": "host",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
       "index": 5
       "index": 5
     },
     },
@@ -417,7 +417,7 @@ module.exports =
       "displayName": "Database Password",
       "displayName": "Database Password",
       "isOverridable": false,
       "isOverridable": false,
       "displayType": "password",
       "displayType": "password",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
       "filename": "oozie-site.xml",
       "filename": "oozie-site.xml",
       "index": 6
       "index": 6
@@ -427,7 +427,7 @@ module.exports =
       "name": "oozie.service.JPAService.jdbc.driver", // the default value of this property is overriden in code
       "name": "oozie.service.JPAService.jdbc.driver", // the default value of this property is overriden in code
       "displayName": "JDBC Driver Class",
       "displayName": "JDBC Driver Class",
       "isOverridable": false,
       "isOverridable": false,
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
       "index": 7
       "index": 7
     },
     },
@@ -437,7 +437,7 @@ module.exports =
       "displayName": "Database URL",
       "displayName": "Database URL",
       "isOverridable": false,
       "isOverridable": false,
       "displayType": "advanced",
       "displayType": "advanced",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
       "index": 8
       "index": 8
     },
     },
@@ -448,7 +448,7 @@ module.exports =
       "name": "javax.jdo.option.ConnectionDriverName",  // the default value is overwritten in code
       "name": "javax.jdo.option.ConnectionDriverName",  // the default value is overwritten in code
       "displayName": "JDBC Driver Class",
       "displayName": "JDBC Driver Class",
       "isOverridable": false,
       "isOverridable": false,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "serviceName": "HIVE",
       "index": 7
       "index": 7
     },
     },
@@ -469,7 +469,7 @@ module.exports =
       "displayName": "Database Username",
       "displayName": "Database Username",
       "displayType": "host",
       "displayType": "host",
       "isOverridable": false,
       "isOverridable": false,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "serviceName": "HIVE",
       "index": 5
       "index": 5
     },
     },
@@ -479,7 +479,7 @@ module.exports =
       "displayName": "Database Password",
       "displayName": "Database Password",
       "displayType": "password",
       "displayType": "password",
       "isOverridable": false,
       "isOverridable": false,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "serviceName": "HIVE",
       "index": 6
       "index": 6
     },
     },
@@ -489,7 +489,7 @@ module.exports =
       "displayName": "Database URL",
       "displayName": "Database URL",
       "displayType": "advanced",
       "displayType": "advanced",
       "isOverridable": false,
       "isOverridable": false,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "serviceName": "HIVE",
       "index": 8
       "index": 8
     },
     },
@@ -501,7 +501,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 4
       "index": 4
     },
     },
     {
     {
@@ -685,7 +685,7 @@ module.exports =
       "name": "hbase.regionserver.handler.count",
       "name": "hbase.regionserver.handler.count",
       "displayName": "RegionServer Handler",
       "displayName": "RegionServer Handler",
       "displayType": "int",
       "displayType": "int",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "serviceName": "HBASE",
       "index": 2
       "index": 2
     },
     },
@@ -695,7 +695,7 @@ module.exports =
       "displayName": "HBase Region Major Compaction",
       "displayName": "HBase Region Major Compaction",
       "displayType": "int",
       "displayType": "int",
       "unit": "ms",
       "unit": "ms",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "serviceName": "HBASE",
       "index": 3
       "index": 3
     },
     },
@@ -704,7 +704,7 @@ module.exports =
       "name": "hbase.hregion.memstore.block.multiplier",
       "name": "hbase.hregion.memstore.block.multiplier",
       "displayName": "HBase Region Block Multiplier",
       "displayName": "HBase Region Block Multiplier",
       "displayType": "int",
       "displayType": "int",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "serviceName": "HBASE",
       "index": 4
       "index": 4
     },
     },
@@ -722,7 +722,7 @@ module.exports =
       "displayName": "HBase Region Memstore Flush Size",
       "displayName": "HBase Region Memstore Flush Size",
       "displayType": "int",
       "displayType": "int",
       "unit": "bytes",
       "unit": "bytes",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "serviceName": "HBASE",
       "index": 5
       "index": 5
     },
     },
@@ -946,7 +946,7 @@ module.exports =
       "displayType": "masterHost",
       "displayType": "masterHost",
       "isOverridable": false,
       "isOverridable": false,
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus"
+      "category": "NIMBUS"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
@@ -954,7 +954,7 @@ module.exports =
       "displayName": "nimbus.thrift.port",
       "displayName": "nimbus.thrift.port",
       "displayType": "int",
       "displayType": "int",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus"
+      "category": "NIMBUS"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
@@ -962,7 +962,7 @@ module.exports =
       "displayName": "nimbus.thrift.max_buffer_size",
       "displayName": "nimbus.thrift.max_buffer_size",
       "displayType": "int",
       "displayType": "int",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "bytes"
       "unit": "bytes"
     },
     },
     {
     {
@@ -972,7 +972,7 @@ module.exports =
       "displayType": "multiLine",
       "displayType": "multiLine",
       "isOverridable": false,
       "isOverridable": false,
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "filename": "storm-site.xml"
       "filename": "storm-site.xml"
     },
     },
     {
     {
@@ -981,7 +981,7 @@ module.exports =
       "displayName": "nimbus.task.timeout.secs",
       "displayName": "nimbus.task.timeout.secs",
       "displayType": "int",
       "displayType": "int",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
       "unit": "seconds"
     },
     },
     {
     {
@@ -990,7 +990,7 @@ module.exports =
       "displayName": "nimbus.supervisor.timeout.secs",
       "displayName": "nimbus.supervisor.timeout.secs",
       "displayType": "int",
       "displayType": "int",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
       "unit": "seconds"
     },
     },
     {
     {
@@ -999,7 +999,7 @@ module.exports =
       "displayName": "nimbus.monitor.freq.secs",
       "displayName": "nimbus.monitor.freq.secs",
       "displayType": "int",
       "displayType": "int",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
       "unit": "seconds"
     },
     },
     {
     {
@@ -1008,7 +1008,7 @@ module.exports =
       "displayName": "nimbus.cleanup.inbox.freq.secs",
       "displayName": "nimbus.cleanup.inbox.freq.secs",
       "displayType": "int",
       "displayType": "int",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
       "unit": "seconds"
     },
     },
     {
     {
@@ -1017,7 +1017,7 @@ module.exports =
       "displayName": "nimbus.inbox.jar.expiration.secs",
       "displayName": "nimbus.inbox.jar.expiration.secs",
       "displayType": "int",
       "displayType": "int",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
       "unit": "seconds"
     },
     },
     {
     {
@@ -1026,7 +1026,7 @@ module.exports =
       "displayName": "nimbus.task.launch.secs",
       "displayName": "nimbus.task.launch.secs",
       "displayType": "int",
       "displayType": "int",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
       "unit": "seconds"
     },
     },
     {
     {
@@ -1036,7 +1036,7 @@ module.exports =
       "displayType": "checkbox",
       "displayType": "checkbox",
       "isReconfigurable": true,
       "isReconfigurable": true,
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus"
+      "category": "NIMBUS"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
@@ -1044,7 +1044,7 @@ module.exports =
       "displayName": "nimbus.file.copy.expiration.secs",
       "displayName": "nimbus.file.copy.expiration.secs",
       "displayType": "int",
       "displayType": "int",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus",
+      "category": "NIMBUS",
       "unit": "seconds"
       "unit": "seconds"
     },
     },
     {
     {
@@ -1052,7 +1052,7 @@ module.exports =
       "name": "nimbus.topology.validator",
       "name": "nimbus.topology.validator",
       "displayName": "nimbus.topology.validator",
       "displayName": "nimbus.topology.validator",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Nimbus"
+      "category": "NIMBUS"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
@@ -1060,13 +1060,13 @@ module.exports =
       "displayName": "supervisor.slots.ports",
       "displayName": "supervisor.slots.ports",
       "displayType": "string",
       "displayType": "string",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Supervisor"
+      "category": "SUPERVISOR"
     },
     },
     {
     {
       "id": "site property",
       "id": "site property",
       "isOverrideable": false,
       "isOverrideable": false,
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Supervisor",
+      "category": "SUPERVISOR",
       "displayName": "supervisor.childopts",
       "displayName": "supervisor.childopts",
       "name": "supervisor.childopts",
       "name": "supervisor.childopts",
       "displayType": "multiLine",
       "displayType": "multiLine",
@@ -1075,7 +1075,7 @@ module.exports =
     {
     {
       "id": "site property",
       "id": "site property",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Supervisor",
+      "category": "SUPERVISOR",
       "displayName": "supervisor.worker.start.timeout.secs",
       "displayName": "supervisor.worker.start.timeout.secs",
       "name": "supervisor.worker.start.timeout.secs",
       "name": "supervisor.worker.start.timeout.secs",
       "displayType": "int",
       "displayType": "int",
@@ -1084,7 +1084,7 @@ module.exports =
     {
     {
       "id": "site property",
       "id": "site property",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Supervisor",
+      "category": "SUPERVISOR",
       "displayName": "supervisor.worker.timeout.secs",
       "displayName": "supervisor.worker.timeout.secs",
       "name": "supervisor.worker.timeout.secs",
       "name": "supervisor.worker.timeout.secs",
       "displayType": "int",
       "displayType": "int",
@@ -1093,7 +1093,7 @@ module.exports =
     {
     {
       "id": "site property",
       "id": "site property",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Supervisor",
+      "category": "SUPERVISOR",
       "displayName": "supervisor.monitor.frequency.secs",
       "displayName": "supervisor.monitor.frequency.secs",
       "name": "supervisor.monitor.frequency.secs",
       "name": "supervisor.monitor.frequency.secs",
       "displayType": "int",
       "displayType": "int",
@@ -1102,7 +1102,7 @@ module.exports =
     {
     {
       "id": "site property",
       "id": "site property",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "Supervisor",
+      "category": "SUPERVISOR",
       "displayName": "supervisor.heartbeat.frequency.secs",
       "displayName": "supervisor.heartbeat.frequency.secs",
       "name": "supervisor.heartbeat.frequency.secs",
       "name": "supervisor.heartbeat.frequency.secs",
       "displayType": "int",
       "displayType": "int",
@@ -1111,7 +1111,7 @@ module.exports =
     {
     {
       "id": "site property",
       "id": "site property",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "displayName": "drpc.port",
       "displayName": "drpc.port",
       "name": "drpc.port",
       "name": "drpc.port",
       "displayType": "int"
       "displayType": "int"
@@ -1119,7 +1119,7 @@ module.exports =
     {
     {
       "id": "site property",
       "id": "site property",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "displayName": "drpc.worker.threads",
       "displayName": "drpc.worker.threads",
       "name": "drpc.worker.threads",
       "name": "drpc.worker.threads",
       "displayType": "int"
       "displayType": "int"
@@ -1127,7 +1127,7 @@ module.exports =
     {
     {
       "id": "site property",
       "id": "site property",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "displayName": "drpc.queue.size",
       "displayName": "drpc.queue.size",
       "name": "drpc.queue.size",
       "name": "drpc.queue.size",
       "displayType": "int"
       "displayType": "int"
@@ -1135,7 +1135,7 @@ module.exports =
     {
     {
       "id": "site property",
       "id": "site property",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "displayName": "drpc.invocations.port",
       "displayName": "drpc.invocations.port",
       "name": "drpc.invocations.port",
       "name": "drpc.invocations.port",
       "displayType": "int"
       "displayType": "int"
@@ -1143,7 +1143,7 @@ module.exports =
     {
     {
       "id": "site property",
       "id": "site property",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "displayName": "drpc.request.timeout.secs",
       "displayName": "drpc.request.timeout.secs",
       "name": "drpc.request.timeout.secs",
       "name": "drpc.request.timeout.secs",
       "displayType": "int",
       "displayType": "int",
@@ -1152,7 +1152,7 @@ module.exports =
     {
     {
       "id": "site property",
       "id": "site property",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "DRPCServer",
+      "category": "DRPC_SERVER",
       "displayName": "drpc.childopts",
       "displayName": "drpc.childopts",
       "name": "drpc.childopts",
       "name": "drpc.childopts",
       "displayType": "string"
       "displayType": "string"
@@ -1160,7 +1160,7 @@ module.exports =
     {
     {
       "id": "site property",
       "id": "site property",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "StormUIServer",
+      "category": "STORM_UI_SERVER",
       "displayName": "ui.port",
       "displayName": "ui.port",
       "name": "ui.port",
       "name": "ui.port",
       "displayType": "int"
       "displayType": "int"
@@ -1168,7 +1168,7 @@ module.exports =
     {
     {
       "id": "site property",
       "id": "site property",
       "serviceName": "STORM",
       "serviceName": "STORM",
-      "category": "StormUIServer",
+      "category": "STORM_UI_SERVER",
       "displayName": "ui.childopts",
       "displayName": "ui.childopts",
       "name": "ui.childopts",
       "name": "ui.childopts",
       "displayType": "string"
       "displayType": "string"
@@ -1763,7 +1763,7 @@ module.exports =
       "isRequired": false,
       "isRequired": false,
       "displayType": "content",
       "displayType": "content",
       "serviceName": "FLUME",
       "serviceName": "FLUME",
-      "category": "FlumeAgent",
+      "category": "FLUME_HANDLER",
       "filename": "flume-conf.xml"
       "filename": "flume-conf.xml"
     }
     }
   ]
   ]

+ 49 - 50
ambari-web/app/data/global_properties.js

@@ -92,7 +92,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -106,7 +106,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 2
       "index": 2
     },
     },
     {
     {
@@ -120,7 +120,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -135,7 +135,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "SNameNode",
+      "category": "SECONDARY_NAMENODE",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -152,7 +152,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "domain": "datanode-global",
       "domain": "datanode-global",
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "DataNode",
+      "category": "DATANODE",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -166,7 +166,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "domain": "datanode-global",
       "domain": "datanode-global",
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "DataNode",
+      "category": "DATANODE",
       "index": 2
       "index": 2
     },
     },
     {
     {
@@ -218,7 +218,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "NameNode"
+      "category": "NAMENODE"
     },
     },
     {
     {
       "id": "puppet var",
       "id": "puppet var",
@@ -244,7 +244,7 @@ module.exports =
       "displayType": "directory",
       "displayType": "directory",
       "isVisible": false,
       "isVisible": false,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "NameNode"
+      "category": "NAMENODE"
     },
     },
 
 
   /**********************************************GLUSTERFS***************************************/
   /**********************************************GLUSTERFS***************************************/
@@ -386,7 +386,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "MAPREDUCE",
       "serviceName": "MAPREDUCE",
-      "category": "HistoryServer",
+      "category": "HISTORYSERVER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -401,7 +401,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "MAPREDUCE",
       "serviceName": "MAPREDUCE",
-      "category": "JobTracker",
+      "category": "JOBTRACKER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -415,7 +415,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "MAPREDUCE",
       "serviceName": "MAPREDUCE",
-      "category": "JobTracker",
+      "category": "JOBTRACKER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -429,7 +429,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "MAPREDUCE",
       "serviceName": "MAPREDUCE",
-      "category": "JobTracker",
+      "category": "JOBTRACKER",
       "index": 2
       "index": 2
     },
     },
     {
     {
@@ -443,7 +443,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "MAPREDUCE",
       "serviceName": "MAPREDUCE",
-      "category": "JobTracker",
+      "category": "JOBTRACKER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -458,9 +458,8 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isRequired": false,
       "isRequired": false,
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
-      "domain": "tasktracker-global",
       "serviceName": "MAPREDUCE",
       "serviceName": "MAPREDUCE",
-      "category": "TaskTracker",
+      "category": "TASKTRACKER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -472,7 +471,7 @@ module.exports =
       "displayType": "int",
       "displayType": "int",
       "unit": "MB",
       "unit": "MB",
       "serviceName": "MAPREDUCE",
       "serviceName": "MAPREDUCE",
-      "category": "TaskTracker",
+      "category": "TASKTRACKER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -526,7 +525,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HBASE",
       "serviceName": "HBASE",
-      "category": "HBase Master",
+      "category": "HBASE_MASTER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -540,7 +539,7 @@ module.exports =
       "isOverridable": true,
       "isOverridable": true,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HBASE",
       "serviceName": "HBASE",
-      "category": "HBase Master",
+      "category": "HBASE_MASTER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -557,7 +556,7 @@ module.exports =
       "isRequired": false,
       "isRequired": false,
       "domain": "regionserver-global",
       "domain": "regionserver-global",
       "serviceName": "HBASE",
       "serviceName": "HBASE",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -571,7 +570,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "domain": "regionserver-global",
       "domain": "regionserver-global",
       "serviceName": "HBASE",
       "serviceName": "HBASE",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -613,7 +612,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 0
       "index": 0
     },
     },
     // for existing MySQL
     // for existing MySQL
@@ -629,7 +628,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isReconfigurable": false,
       "isReconfigurable": false,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
       "index": 1
     },
     },
     // for existing PostgreSQL
     // for existing PostgreSQL
@@ -645,7 +644,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isReconfigurable": false,
       "isReconfigurable": false,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
       "index": 1
     },
     },
     // for existing Oracle
     // for existing Oracle
@@ -661,7 +660,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isReconfigurable": false,
       "isReconfigurable": false,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
       "index": 1
     },
     },
     // for new MySQL
     // for new MySQL
@@ -676,7 +675,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": false,
       "isVisible": false,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -711,7 +710,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 2
       "index": 2
     },
     },
     {
     {
@@ -726,7 +725,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -742,7 +741,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -758,7 +757,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -774,7 +773,7 @@ module.exports =
         "isVisible": false,
         "isVisible": false,
         "isObserved": true,
         "isObserved": true,
         "serviceName": "HIVE",
         "serviceName": "HIVE",
-        "category": "Hive Metastore",
+        "category": "HIVE_METASTORE",
         "index": 3
         "index": 3
       },
       },
     {
     {
@@ -790,7 +789,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": false,
       "isVisible": false,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -857,7 +856,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "WEBHCAT",
       "serviceName": "WEBHCAT",
-      "category": "WebHCat Server"
+      "category": "WEBHCAT_SERVER"
     },
     },
     {
     {
       "id": "puppet var",
       "id": "puppet var",
@@ -898,7 +897,7 @@ module.exports =
       "isRequiredByAgent": false,
       "isRequiredByAgent": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 0
       "index": 0
     },
     },
     // for existing PostgreSQL
     // for existing PostgreSQL
@@ -914,7 +913,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isReconfigurable": false,
       "isReconfigurable": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
       "index": 1
     },
     },
     // for existing Oracle
     // for existing Oracle
@@ -931,7 +930,7 @@ module.exports =
       "isReconfigurable": false,
       "isReconfigurable": false,
       "isOverridable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
       "index": 1
     },
     },
     // for current derby
     // for current derby
@@ -947,7 +946,7 @@ module.exports =
       "isReconfigurable": false,
       "isReconfigurable": false,
       "isOverridable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
       "index": 1
     },
     },
     // for existing MySQL oozie
     // for existing MySQL oozie
@@ -963,7 +962,7 @@ module.exports =
       "isReconfigurable": false,
       "isReconfigurable": false,
       "isOverridable": false,
       "isOverridable": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -999,7 +998,7 @@ module.exports =
       "radioName": "oozie-database",
       "radioName": "oozie-database",
       "isVisible": true,
       "isVisible": true,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 2
       "index": 2
     },
     },
     {
     {
@@ -1013,7 +1012,7 @@ module.exports =
       "displayType": "host",
       "displayType": "host",
       "isVisible": false,
       "isVisible": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -1029,7 +1028,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -1045,7 +1044,7 @@ module.exports =
       "isVisible": false,   // This is dynamically set to true if database selected by the user is existing postgresql
       "isVisible": false,   // This is dynamically set to true if database selected by the user is existing postgresql
       "isObserved": true,
       "isObserved": true,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -1061,7 +1060,7 @@ module.exports =
       "isVisible": false,
       "isVisible": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -1077,7 +1076,7 @@ module.exports =
       "displayType": "masterHost",
       "displayType": "masterHost",
       "isVisible": false,
       "isVisible": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -1093,7 +1092,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isRequired": false,
       "isRequired": false,
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "index": 8
       "index": 8
     },
     },
 
 
@@ -1187,7 +1186,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isRequired": false,
       "isRequired": false,
       "serviceName": "ZOOKEEPER",
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 0
       "index": 0
     },
     },
     {
     {
@@ -1201,7 +1200,7 @@ module.exports =
       "displayType": "directory",
       "displayType": "directory",
       "isVisible": true,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -1215,7 +1214,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 2
       "index": 2
     },
     },
     {
     {
@@ -1228,7 +1227,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -1241,7 +1240,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 4
       "index": 4
     },
     },
     {
     {
@@ -1254,7 +1253,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "ZOOKEEPER",
       "serviceName": "ZOOKEEPER",
-      "category": "ZooKeeper Server",
+      "category": "ZOOKEEPER_SERVER",
       "index": 5
       "index": 5
     },
     },
     {
     {

+ 0 - 368
ambari-web/app/data/review_configs.js

@@ -1,368 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-module.exports = [
-
-  {
-    config_name: 'Admin',
-    display_name: 'Admin Name',
-    config_value: ''
-  },
-  {
-    config_name: 'cluster',
-    display_name: 'Cluster Name',
-    config_value: ''
-  },
-  {
-    config_name: 'hosts',
-    display_name: 'Total Hosts',
-    config_value: ''
-  },
-  {
-    config_name: 'Repo',
-    display_name: 'Local Repository',
-    config_value: ''
-  },
-  {
-    config_name: 'services',
-    display_name: 'Services',
-    config_value: [
-      Ember.Object.create({
-        service_name: 'HDFS',
-        display_name: 'HDFS',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'NameNode',
-            component_name: 'NAMENODE',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'SecondaryNameNode',
-            component_name: 'SECONDARY_NAMENODE',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'DataNodes',
-            component_name: 'DATANODE',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'GLUSTERFS',
-        display_name: 'GLUSTERFS',
-        service_components: []
-      }),  
-      Ember.Object.create({
-        service_name: 'MAPREDUCE',
-        display_name: 'MapReduce',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'JobTracker',
-            component_name: 'JOBTRACKER',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'TaskTrackers',
-            component_name: 'TASKTRACKER',
-            component_value: '',
-            isMaster: false
-          }),
-          Ember.Object.create({
-            display_name: 'History Server',
-            component_name: 'HISTORYSERVER',
-            component_value: '',
-            isMaster: true
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'YARN',
-        display_name: 'YARN + MapReduce2',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'NodeManager',
-            component_name: 'NODEMANAGER',
-            component_value: '',
-            isMaster: false
-          }),
-          Ember.Object.create({
-            display_name: 'ResourceManager',
-            component_name: 'RESOURCEMANAGER',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'History Server',
-            component_name: 'HISTORYSERVER',
-            component_value: '',
-            isMaster: true
-          })
-          // @todo uncomment after Application Timeline Server API implementation
-//          Ember.Object.create({
-//            display_name: 'App Timeline Server',
-//            component_name: 'APP_TIMELINE_SERVER',
-//            component_value: '',
-//            isMaster: true
-//          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'HIVE',
-        display_name: 'Hive + HCatalog',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Hive Metastore',
-            component_name: 'HIVE_METASTORE',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'Database',
-            component_value: '',
-            customHandler: 'loadHiveDbValue'
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'HBASE',
-        display_name: 'HBase',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Master',
-            component_name: 'HBASE_MASTER',
-            component_value: '',
-            customHandler: 'loadHbaseMasterValue'
-          }),
-          Ember.Object.create({
-            display_name: 'RegionServers',
-            component_name: 'HBASE_REGIONSERVER',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'ZOOKEEPER',
-        display_name: 'ZooKeeper',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Servers',
-            component_name: 'ZOOKEEPER_SERVER',
-            component_value: '',
-            customHandler: 'loadZkServerValue'
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'OOZIE',
-        display_name: 'Oozie',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Server',
-            component_name: 'OOZIE_SERVER',
-            component_value: '',
-            isMaster: true
-          }),
-          // TODO: uncomment when ready to integrate with database other than Derby
-          Ember.Object.create({
-            display_name: 'Database',
-            component_value: '',
-            customHandler: 'loadOozieDbValue'
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'NAGIOS',
-        display_name: 'Nagios',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Server',
-            component_name: 'NAGIOS_SERVER',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'Administrator',
-            component_value: '',
-            customHandler: 'loadNagiosAdminValue'
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'GANGLIA',
-        display_name: 'Ganglia',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Server',
-            component_name: 'GANGLIA_SERVER',
-            component_value: '',
-            isMaster: true
-          })
-        ]
-      }),
-     /* Ember.Object.create({
-        service_name: 'TEZ',
-        display_name: 'TEZ',
-        service_components: []
-      }),
-      Ember.Object.create({
-        service_name: 'PIG',
-        display_name: 'Pig',
-        service_components: []
-      }),
-      Ember.Object.create({
-        service_name: 'SQOOP',
-        display_name: 'Sqoop',
-        service_components: []
-      }),
-      Ember.Object.create({
-        service_name: 'HCATALOG',
-        display_name: 'HCatalog',
-        service_components: []
-      }),*/
-      Ember.Object.create({
-        service_name: 'HUE',
-        display_name: 'Hue',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Server',
-            component_name: 'HUE_SERVER',
-            component_value: '',
-            isMaster: true
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'FALCON',
-        display_name: 'Falcon',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Server',
-            component_name: 'FALCON_SERVER',
-            component_value: '',
-            isMaster: true
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'STORM',
-        display_name: 'Storm',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Nimbus',
-            component_name: 'NIMBUS',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'Storm REST API Server',
-            component_name: 'STORM_REST_API',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'Storm UI Server',
-            component_name: 'STORM_UI_SERVER',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'DRPC Server',
-            component_name: 'DRPC_SERVER',
-            component_value: '',
-            isMaster: true
-          }),
-          Ember.Object.create({
-            display_name: 'Supervisor',
-            component_name: 'SUPERVISOR',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'PIG',
-        display_name: 'Pig',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Clients',
-            component_name: 'CLIENT',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'SQOOP',
-        display_name: 'Sqoop',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Clients',
-            component_name: 'CLIENT',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'TEZ',
-        display_name: 'Tez',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Clients',
-            component_name: 'CLIENT',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      }),
-      Ember.Object.create({
-        service_name: 'FLUME',
-        display_name: 'Flume',
-        service_components: [
-          Ember.Object.create({
-            display_name: 'Flume Agent',
-            component_name: 'FLUME_HANDLER',
-            component_value: '',
-            isMaster: false
-          })
-        ]
-      })
-    ]
-  }
-];
-
-// @todo remove after Application Timeline Server API implementation
-if (App.supports.appTimelineServer) {
-  var yarnServiceComponents = module.exports.findProperty('config_name', 'services').config_value.findProperty('service_name','YARN').get('service_components');
-  yarnServiceComponents.push(
-    Ember.Object.create({
-      display_name: 'App Timeline Server',
-      component_name: "APP_TIMELINE_SERVER",
-      component_value: '',
-      isMaster: true
-    })
-  )
-}

+ 7 - 272
ambari-web/app/data/service_configs.js

@@ -18,279 +18,15 @@
 
 
 var App = require('app');
 var App = require('app');
 require('models/service_config');
 require('models/service_config');
-require('utils/configs/defaults_providers/yarn_defaults_provider');
-require('utils/configs/defaults_providers/tez_defaults_provider');
-require('utils/configs/defaults_providers/hive_defaults_provider');
-require('utils/configs/defaults_providers/storm_defaults_provider');
-require('utils/configs/defaults_providers/oozie_defaults_provider');
 require('utils/configs/defaults_providers/user_defaults_provider');
 require('utils/configs/defaults_providers/user_defaults_provider');
-require('utils/configs/validators/yarn_configs_validator');
-require('utils/configs/validators/hive_configs_validator');
-require('utils/configs/validators/tez_configs_validator');
-require('utils/configs/validators/mapreduce2_configs_validator');
-require('utils/configs/validators/storm_configs_validator');
 require('utils/configs/validators/user_configs_validator');
 require('utils/configs/validators/user_configs_validator');
 
 
+/**
+ * This
+ * @type {Array} Array of non-service tabs that will appears on  Customizes services page
+ */
 module.exports = [
 module.exports = [
-  {
-    serviceName: 'HDFS',
-    displayName: 'HDFS',
-    filename: 'hdfs-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'NameNode', displayName : 'NameNode', hostComponentNames : ['NAMENODE']}),
-      App.ServiceConfigCategory.create({ name: 'SNameNode', displayName : 'Secondary NameNode', hostComponentNames : ['SECONDARY_NAMENODE']}),
-      App.ServiceConfigCategory.create({ name: 'DataNode', displayName : 'DataNode', hostComponentNames : ['DATANODE']}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedCoreSite', displayName : 'Custom core-site.xml', siteFileName: 'core-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHDFSSite', displayName : 'Custom hdfs-site.xml', siteFileName: 'hdfs-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHDFSLog4j', displayName : 'Custom log4j.properties', siteFileName: 'hdfs-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'core-site', 'hdfs-site', 'hdfs-log4j'],
-    configs: []
-  },
-  {
-    serviceName: 'GLUSTERFS',
-    displayName: 'GLUSTERFS',
-    filename: 'core-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),     
-      App.ServiceConfigCategory.create({ name: 'AdvancedGlusterFSSite', displayName : 'Custom core-site.xml', siteFileName: 'core-site.xml', canAddProperty: true})
-    ],
-    sites: ['core-site'],
-    configs: []
-  },
-
-  {
-    serviceName: 'MAPREDUCE',
-    displayName: 'MapReduce',
-    filename: 'mapred-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'HistoryServer', displayName : 'History Server', hostComponentNames : ['HISTORYSERVER']}),
-      App.ServiceConfigCategory.create({ name: 'JobTracker', displayName : 'JobTracker', hostComponentNames : ['JOBTRACKER']}),
-      App.ServiceConfigCategory.create({ name: 'TaskTracker', displayName : 'TaskTracker', hostComponentNames : ['TASKTRACKER']}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedMapredSite', displayName : 'Custom mapred-site.xml', siteFileName: 'mapred-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedMapredLog4j', displayName : 'Custom log4j.properties', siteFileName: 'mapreduce-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'mapred-site', 'mapred-queue-acls', 'mapreduce-log4j'],
-    configs: []
-  },
-
-  {
-    serviceName: 'YARN',
-    displayName: 'YARN',
-    configsValidator: App.YARNConfigsValidator,
-    defaultsProviders: [App.YARNDefaultsProvider.create()],
-    filename: 'yarn-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'ResourceManager', displayName : 'Resource Manager', hostComponentNames : ['RESOURCEMANAGER']}),
-      App.ServiceConfigCategory.create({ name: 'NodeManager', displayName : 'Node Manager', hostComponentNames : ['NODEMANAGER']}),
-      App.ServiceConfigCategory.create({ name: 'AppTimelineServer', displayName : 'Application Timeline Server', hostComponentNames : ['APP_TIMELINE_SERVER']}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'CapacityScheduler', displayName : 'Scheduler', isCapacityScheduler : true, isCustomView: true, siteFileName: 'capacity-scheduler.xml', siteFileNames: ['capacity-scheduler.xml', 'mapred-queue-acls.xml'], canAddProperty: App.supports.capacitySchedulerUi}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedYARNSite', displayName : 'Custom yarn-site.xml', siteFileName: 'yarn-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedYARNLog4j', displayName : 'Custom log4j.properties', siteFileName: 'yarn-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'yarn-site', 'capacity-scheduler', 'yarn-log4j'],
-    configs: []
-  },
-
-  {
-    serviceName: 'MAPREDUCE2',
-    displayName: 'MapReduce 2',
-    filename: 'mapred-site',
-    configsValidator: App.MapReduce2ConfigsValidator,
-    defaultsProviders: [App.YARNDefaultsProvider.create()],
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'HistoryServer', displayName : 'History Server', hostComponentNames : ['HISTORYSERVER']}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedMapredSite', displayName : 'Custom mapred-site.xml', siteFileName: 'mapred-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedMapredLog4j', displayName : 'Custom log4j.properties', siteFileName: 'mapreduce2-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'mapred-site', 'mapred-queue-acls', 'mapreduce2-log4j'],
-    configs: []
-  },
-
-  {
-    serviceName: 'HIVE',
-    displayName: 'Hive',
-    filename: 'hive-site',
-    configsValidator: App.HiveConfigsValidator,
-    defaultsProviders: [App.HiveDefaultsProvider.create()],
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'Hive Metastore', displayName : 'Hive Metastore'}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHiveSite', displayName : 'Custom hive-site.xml', siteFileName: 'hive-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHiveLog4j', displayName : 'Custom log4j.properties', siteFileName: 'hive-log4j.xml', canAddProperty: false}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHiveExecLog4j', displayName : 'Custom hive-exec-log4j', siteFileName: 'hive-exec-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'hive-site', 'hive-log4j', 'hive-exec-log4j'],
-    configs: []
-  },
-
-  {
-    serviceName: 'WEBHCAT',
-    displayName: 'WebHCat',
-    filename: 'webhcat-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'WebHCat Server', displayName : 'WebHCat Server'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedWebHCatSite', displayName : 'Custom webhcat-site.xml', siteFileName: 'webhcat-site.xml', canAddProperty: true})
-    ],
-    sites: ['global', 'webhcat-site'],
-    configs: []
-  },
-
-  {
-    serviceName: 'HBASE',
-    displayName: 'HBase',
-    filename: 'hbase-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'HBase Master', displayName : 'HBase Master'}),
-      App.ServiceConfigCategory.create({ name: 'RegionServer', displayName : 'RegionServer'}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHbaseSite', displayName : 'Custom hbase-site.xml', siteFileName: 'hbase-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedHbaseLog4j', displayName : 'Custom log4j.properties', siteFileName: 'hbase-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'hbase-site', 'hbase-log4j'],
-    configs: []
-  },
-
-  {
-    serviceName: 'ZOOKEEPER',
-    displayName: 'ZooKeeper',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'ZooKeeper Server', displayName : 'ZooKeeper Server'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedZooLog4j', displayName : 'Custom log4j.properties', siteFileName: 'zookeeper-log4j.xml', canAddProperty: false}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedZooCfg', displayName : 'Custom zoo.cfg', siteFileName: 'zoo.cfg', canAddProperty: true})
-    ],
-    sites: ['global', 'zookeeper-log4j', 'zoo.cfg'],
-    configs: []
-  },
-
-  {
-    serviceName: 'OOZIE',
-    displayName: 'Oozie',
-    defaultsProviders: [App.OOZIEDefaultsProvider.create()],
-    filename: 'oozie-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'Oozie Server', displayName : 'Oozie Server'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedOozieSite', displayName : 'Custom oozie-site.xml', siteFileName: 'oozie-site.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedOozieLog4j', displayName : 'Custom log4j.properties', siteFileName: 'oozie-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['global', 'oozie-site', 'oozie-log4j'],
-    configs: []
-  },
-
-  {
-    serviceName: 'NAGIOS',
-    displayName: 'Nagios',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'})
-    ],
-    sites: ['global'],
-    configs: []
-  },
-
-  {
-    serviceName: 'GANGLIA',
-    displayName: 'Ganglia',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'})
-    ],
-    sites: ['global'],
-    configs: []
-  },
-
-  {
-    serviceName: 'HUE',
-    displayName: 'Hue',
-    filename: 'hue-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'Hue Server', displayName : 'Hue Server'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'})
-    ],
-    sites: ['hue-site'],
-    configs: []
-  },
-
-  {
-    serviceName: 'PIG',
-    displayName: 'Pig',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Custom pig.properties', siteFileName: 'pig-properties.xml', canAddProperty: false}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedPigLog4j', displayName : 'Custom log4j.properties', siteFileName: 'pig-log4j.xml', canAddProperty: false})
-    ],
-    sites: ['pig-properties','pig-log4j'],
-    configs: []
-  },
-  {
-    serviceName: 'FALCON',
-    displayName: 'Falcon',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'Falcon', displayName : 'Falcon Server'}),
-      App.ServiceConfigCategory.create({ name: 'Falcon - Oozie integration', displayName : 'Falcon - Oozie integration'}),
-      App.ServiceConfigCategory.create({ name: 'FalconStartupSite', displayName : 'Falcon startup.properties'}),
-      App.ServiceConfigCategory.create({ name: 'FalconRuntimeSite', displayName : 'Falcon runtime.properties'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedFalconStartupSite', displayName : 'Custom startup.properties', siteFileName: 'falcon-startup.properties.xml', canAddProperty: true}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedFalconRuntimeSite', displayName : 'Custom runtime.properties', siteFileName: 'falcon-runtime.properties.xml', canAddProperty: true})
-    ],
-    sites: ['global', 'oozie-site','falcon-startup.properties', 'falcon-runtime.properties'],
-    configs: []
-  },
-
-  {
-    serviceName: 'STORM',
-    displayName: 'Storm',
-    configsValidator: App.STORMConfigsValidator,
-    defaultsProviders: [App.STORMDefaultsProvider.create()],
-    filename: 'storm-site',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'Nimbus', displayName : 'Nimbus'}),
-      App.ServiceConfigCategory.create({ name: 'Supervisor', displayName : 'Supervisor'}),
-      App.ServiceConfigCategory.create({ name: 'StormUIServer', displayName : 'Storm UI Server'}),
-      App.ServiceConfigCategory.create({ name: 'StormRestApi', displayName : 'Storm REST API Server'}),
-      App.ServiceConfigCategory.create({ name: 'DRPCServer', displayName : 'DRPC Server'}),
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedStormSite', displayName : 'Custom storm.yaml', siteFileName: 'storm-site.xml', canAddProperty: true})
-    ],
-    sites: ['global', 'storm-site'],
-    configs: []
-  },
-  {
-    serviceName: 'TEZ',
-    displayName: 'Tez',
-    filename: 'tez-site',
-    configsValidator: App.TezConfigsValidator,
-    defaultsProviders: [App.TezDefaultsProvider.create()],
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
-      App.ServiceConfigCategory.create({ name: 'Advanced', displayName : 'Advanced'}),
-      App.ServiceConfigCategory.create({ name: 'AdvancedTezSite', displayName : 'Custom tez-site.xml', siteFileName: 'tez-site.xml', canAddProperty: true})
-    ],
-    sites: ['global', 'tez-site'],
-    configs: []
-  },
-  {
-    serviceName: 'FLUME',
-    displayName: 'Flume',
-    configCategories: [
-      App.ServiceConfigCategory.create({ name: 'FlumeAgent', displayName : 'flume.conf', siteFileName: 'flume-conf', canAddProperty: false})
-    ],
-    sites: ['flume-conf'],
-    configs: []
-  },
-  {
+  Em.Object.create({
     serviceName: 'MISC',
     serviceName: 'MISC',
     displayName: 'Misc',
     displayName: 'Misc',
     configsValidator: App.userConfigsValidator,
     configsValidator: App.userConfigsValidator,
@@ -299,8 +35,7 @@ module.exports = [
       App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
       App.ServiceConfigCategory.create({ name: 'General', displayName : 'General'}),
       App.ServiceConfigCategory.create({ name: 'Users and Groups', displayName : 'Users and Groups'})
       App.ServiceConfigCategory.create({ name: 'Users and Groups', displayName : 'Users and Groups'})
     ],
     ],
-    sites: ['global'],
+    configTypes: ['global'],
     configs: []
     configs: []
-  }
-
+  })
 ];
 ];

+ 0 - 189
ambari-web/app/data/services.js

@@ -1,189 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-var App = require('app');
-
-module.exports = [
-  {
-    serviceName: 'HDFS',
-    displayName: 'HDFS',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.hdfs.description')
-  },
-  {
-    serviceName: 'GLUSTERFS',
-    displayName: 'GLUSTERFS',
-    isDisabled: false,
-    isSelected: false,
-    canBeSelected: true,
-    description: Em.I18n.t('services.glusterfs.description')
-  },
-  {
-    serviceName: 'MAPREDUCE',
-    displayName: 'MapReduce',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.mapreduce.description')
-  },
-  {
-    serviceName: 'MAPREDUCE2',
-    displayName: 'MapReduce 2',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    isHidden: true,
-    description: Em.I18n.t('services.mapreduce2.description')
-  },
-  {
-    serviceName: 'YARN',
-    displayName: 'YARN + MapReduce2',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.yarn.description')
-  },
-  {
-    serviceName: 'TEZ',
-    displayName: 'Tez',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.tez.description')
-  },
-  {
-    serviceName: 'NAGIOS',
-    displayName: 'Nagios',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.nagios.description')
-  },
-  {
-    serviceName: 'GANGLIA',
-    displayName: 'Ganglia',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.ganglia.description')
-  },
-  {
-    serviceName: 'HIVE',
-    displayName: 'Hive + HCat',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.hive.description')
-  },
-  {
-    serviceName: 'HCATALOG',
-    displayName: 'HCatalog',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    isHidden: true
-  },
-  {
-    serviceName: 'WEBHCAT',
-    displayName: 'WebHCat',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    isHidden: true
-  },
-  {
-    serviceName: 'HBASE',
-    displayName: 'HBase',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.hbase.description')
-  },
-  {
-    serviceName: 'PIG',
-    displayName: 'Pig',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.pig.description')
-  },
-  {
-    serviceName: 'SQOOP',
-    displayName: 'Sqoop',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.sqoop.description')
-  },
-  {
-    serviceName: 'OOZIE',
-    displayName: 'Oozie',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.oozie.description')
-  },
-  {
-    serviceName: 'ZOOKEEPER',
-	  displayName: 'ZooKeeper',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    description: Em.I18n.t('services.zookeeper.description')
-  },
-  {
-    serviceName: 'HUE',
-    displayName: 'Hue',
-    isDisabled: false,
-    isSelected: App.supports.hue,
-    canBeSelected: App.supports.hue,
-    isHidden: !App.supports.hue
-  },
-  {
-    serviceName: 'FALCON',
-    displayName: 'Falcon',
-    isDisabled: false,
-    isSelected: App.supports.falcon,
-    canBeSelected: App.supports.falcon,
-    isHidden: !App.supports.falcon,
-    description: Em.I18n.t('services.falcon.description')
-  },
-  {
-    serviceName: 'STORM',
-    displayName: 'Storm',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    isHidden: false,
-    description: Em.I18n.t('services.storm.description')
-  }
-];
-
-if (App.supports.flume) {
-  var flume = {
-    serviceName: 'FLUME',
-    displayName: 'Flume',
-    isDisabled: false,
-    isSelected: true,
-    canBeSelected: true,
-    isHidden: false
-  };
-  module.exports.push(flume);
-}

+ 23 - 23
ambari-web/app/data/site_properties.js

@@ -30,7 +30,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "SNameNode",
+      "category": "SECONDARY_NAMENODE",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -70,7 +70,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
       "serviceName": "HDFS",
       "serviceName": "HDFS",
-      "category": "NameNode",
+      "category": "NAMENODE",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -93,7 +93,7 @@ module.exports =
       "defaultValue": "",
       "defaultValue": "",
       "displayType": "int",
       "displayType": "int",
       "isVisible": true,
       "isVisible": true,
-      "category": "DataNode",
+      "category": "DATANODE",
       "serviceName": "HDFS",
       "serviceName": "HDFS",
       "index": 3
       "index": 3
     },
     },
@@ -106,7 +106,7 @@ module.exports =
       "defaultDirectory": "/hadoop/hdfs/data",
       "defaultDirectory": "/hadoop/hdfs/data",
       "displayType": "directories",
       "displayType": "directories",
       "isVisible": true,
       "isVisible": true,
-      "category": "DataNode",
+      "category": "DATANODE",
       "serviceName": "HDFS",
       "serviceName": "HDFS",
       "index": 1
       "index": 1
     },
     },
@@ -118,7 +118,7 @@ module.exports =
       "defaultValue": "",
       "defaultValue": "",
       "displayType": "int",
       "displayType": "int",
       "isVisible": true,
       "isVisible": true,
-      "category": "DataNode",
+      "category": "DATANODE",
       "serviceName": "HDFS"
       "serviceName": "HDFS"
     },
     },
     {
     {
@@ -156,7 +156,7 @@ module.exports =
       "defaultDirectory": "/hadoop/mapred",
       "defaultDirectory": "/hadoop/mapred",
       "displayType": "directories",
       "displayType": "directories",
       "serviceName": "MAPREDUCE",
       "serviceName": "MAPREDUCE",
-      "category": "TaskTracker",
+      "category": "TASKTRACKER",
       "index": 1
       "index": 1
     },
     },
     {
     {
@@ -178,7 +178,7 @@ module.exports =
       "defaultValue": "",
       "defaultValue": "",
       "displayType": "int",
       "displayType": "int",
       "serviceName": "MAPREDUCE",
       "serviceName": "MAPREDUCE",
-      "category": "TaskTracker",
+      "category": "TASKTRACKER",
       "index": 2
       "index": 2
     },
     },
     {
     {
@@ -189,7 +189,7 @@ module.exports =
       "defaultValue": "",
       "defaultValue": "",
       "displayType": "int",
       "displayType": "int",
       "serviceName": "MAPREDUCE",
       "serviceName": "MAPREDUCE",
-      "category": "TaskTracker",
+      "category": "TASKTRACKER",
       "index": 3
       "index": 3
     },
     },
     {
     {
@@ -341,7 +341,7 @@ module.exports =
       "description": "Java options for the TaskTracker child processes.",
       "description": "Java options for the TaskTracker child processes.",
       "defaultValue": "",
       "defaultValue": "",
       "displayType": "advanced",
       "displayType": "advanced",
-      "category": "TaskTracker",
+      "category": "TASKTRACKER",
       "serviceName": "MAPREDUCE",
       "serviceName": "MAPREDUCE",
       "index": 4
       "index": 4
     },
     },
@@ -357,7 +357,7 @@ module.exports =
       "displayType": "host",
       "displayType": "host",
       "isVisible": true,
       "isVisible": true,
       "isObserved": true,
       "isObserved": true,
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
       "index": 3
       "index": 3
     },
     },
@@ -369,7 +369,7 @@ module.exports =
       "defaultValue": "",
       "defaultValue": "",
       "isOverridable": false,
       "isOverridable": false,
       "displayType": "host",
       "displayType": "host",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
       "index": 4
       "index": 4
     },
     },
@@ -382,7 +382,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "displayType": "password",
       "displayType": "password",
       "isVisible": true,
       "isVisible": true,
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
       "filename": "oozie-site.xml",
       "filename": "oozie-site.xml",
       "index": 5
       "index": 5
@@ -396,7 +396,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isOverridable": false,
       "isOverridable": false,
       "description": "Database name used for the Oozie",
       "description": "Database name used for the Oozie",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
       "index": 6
       "index": 6
     },
     },
@@ -408,7 +408,7 @@ module.exports =
       "defaultValue": "",
       "defaultValue": "",
       "isOverridable": false,
       "isOverridable": false,
       "displayType": "advanced",
       "displayType": "advanced",
-      "category": "Oozie Server",
+      "category": "OOZIE_SERVER",
       "serviceName": "OOZIE",
       "serviceName": "OOZIE",
       "index": 7
       "index": 7
     },
     },
@@ -423,7 +423,7 @@ module.exports =
       "isVisible": true,
       "isVisible": true,
       "isOverridable": false,
       "isOverridable": false,
       "description": "Driver class name for a JDBC metastore",
       "description": "Driver class name for a JDBC metastore",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "serviceName": "HIVE",
       "index": 7
       "index": 7
     },
     },
@@ -448,7 +448,7 @@ module.exports =
       "defaultValue": "hive",
       "defaultValue": "hive",
       "displayType": "host",
       "displayType": "host",
       "isOverridable": false,
       "isOverridable": false,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "serviceName": "HIVE",
       "index": 5
       "index": 5
     },
     },
@@ -461,7 +461,7 @@ module.exports =
       "displayType": "password",
       "displayType": "password",
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "serviceName": "HIVE",
       "index": 6
       "index": 6
     },
     },
@@ -475,7 +475,7 @@ module.exports =
       "displayType": "advanced",
       "displayType": "advanced",
       "isOverridable": false,
       "isOverridable": false,
       "isVisible": true,
       "isVisible": true,
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "serviceName": "HIVE",
       "serviceName": "HIVE",
       "index": 8
       "index": 8
     },
     },
@@ -490,7 +490,7 @@ module.exports =
       "isOverridable": false,
       "isOverridable": false,
       "isObserved": true,
       "isObserved": true,
       "serviceName": "HIVE",
       "serviceName": "HIVE",
-      "category": "Hive Metastore",
+      "category": "HIVE_METASTORE",
       "index": 4
       "index": 4
     },
     },
     {
     {
@@ -610,7 +610,7 @@ module.exports =
       "description": "Count of RPC Listener instances spun up on RegionServers",
       "description": "Count of RPC Listener instances spun up on RegionServers",
       "defaultValue": "60",
       "defaultValue": "60",
       "displayType": "int",
       "displayType": "int",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "serviceName": "HBASE",
       "index": 2
       "index": 2
     },
     },
@@ -623,7 +623,7 @@ module.exports =
       "displayType": "int",
       "displayType": "int",
       "unit": "ms",
       "unit": "ms",
       "isVisible": true,
       "isVisible": true,
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "serviceName": "HBASE",
       "index": 3
       "index": 3
     },
     },
@@ -634,7 +634,7 @@ module.exports =
       "description": "Block updates if memstore has \"Multiplier * HBase Region Memstore Flush Size\" bytes. Useful preventing runaway memstore during spikes in update traffic",
       "description": "Block updates if memstore has \"Multiplier * HBase Region Memstore Flush Size\" bytes. Useful preventing runaway memstore during spikes in update traffic",
       "defaultValue": "",
       "defaultValue": "",
       "displayType": "int",
       "displayType": "int",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "serviceName": "HBASE",
       "index": 4
       "index": 4
     },
     },
@@ -659,7 +659,7 @@ module.exports =
       "defaultValue": "",
       "defaultValue": "",
       "displayType": "int",
       "displayType": "int",
       "unit": "bytes",
       "unit": "bytes",
-      "category": "RegionServer",
+      "category": "HBASE_REGIONSERVER",
       "serviceName": "HBASE",
       "serviceName": "HBASE",
       "index": 5
       "index": 5
     },
     },

+ 1 - 1
ambari-web/app/mappers.js

@@ -18,7 +18,7 @@
 
 
 //load all mappers
 //load all mappers
 require('mappers/server_data_mapper');
 require('mappers/server_data_mapper');
-require('mappers/stack_service_component_mapper');
+require('mappers/stack_service_mapper');
 require('mappers/hosts_mapper');
 require('mappers/hosts_mapper');
 require('mappers/cluster_mapper');
 require('mappers/cluster_mapper');
 require('mappers/jobs_mapper');
 require('mappers/jobs_mapper');

+ 3 - 2
ambari-web/app/mappers/service_metrics_mapper.js

@@ -273,7 +273,8 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
         }
         }
       }, this);
       }, this);
 
 
-      result = misc.sortByOrder(App.Service.servicesSortOrder, result);
+      var stackServices = App.StackService.find().mapProperty('serviceName');
+      result = misc.sortByOrder(stackServices, result);
 
 
       //load services to model
       //load services to model
       App.store.loadMany(this.get('model'), result);
       App.store.loadMany(this.get('model'), result);
@@ -308,7 +309,7 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
     var isSecondaryNamenode = hostComponents.findProperty('component_name', 'SECONDARY_NAMENODE');
     var isSecondaryNamenode = hostComponents.findProperty('component_name', 'SECONDARY_NAMENODE');
     services.setEach('tool_tip_content', '');
     services.setEach('tool_tip_content', '');
     // set tooltip for client-only services
     // set tooltip for client-only services
-    var clientOnlyServiceNames = Em.A(['TEZ', 'SQOOP', 'PIG']);
+    var clientOnlyServiceNames = App.get('services.clientOnly');
     clientOnlyServiceNames.forEach(function(serviceName) {
     clientOnlyServiceNames.forEach(function(serviceName) {
       var service = services.findProperty('ServiceInfo.service_name', serviceName);
       var service = services.findProperty('ServiceInfo.service_name', serviceName);
       if (service) {
       if (service) {

+ 90 - 0
ambari-web/app/mappers/stack_service_mapper.js

@@ -0,0 +1,90 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var App = require('app');
+
+App.stackServiceMapper = App.QuickDataMapper.create({
+  model: App.StackService,
+  component_model: App.StackServiceComponent,
+
+  config: {
+    id: 'service_name',
+    service_name: 'service_name',
+    config_types: 'config_types',
+    comments: 'comments',
+    service_version: 'service_version',
+    stack_name: 'stack_name',
+    stack_version: 'stack_version',
+    is_selected: 'is_selected',
+    is_installed: 'is_installed',
+    service_components_key: 'service_components',
+    service_components_type: 'array',
+    service_components: {
+      item: 'id'
+    }
+  },
+
+  component_config: {
+    id: 'component_name',
+    component_name: 'component_name',
+    service_name: 'service_name',
+    component_category: 'component_category',
+    is_master: 'is_master',
+    is_client: 'is_client',
+    stack_name: 'stack_name',
+    stack_version: 'stack_version',
+    stack_service_id: 'service_name',
+    dependencies_key: 'dependencies',
+    dependencies_type: 'array',
+    dependencies: {
+      item: 'Dependencies.component_name'
+    }
+  },
+
+  map: function (json) {
+    var model = this.get('model');
+    var result = [];
+    var stackServiceComponents = [];
+    this.rearrangeServicesForDisplayOrder(json.items, App.StackService.displayOrder);
+    json.items.forEach(function (item) {
+      //@TODO: Remove the condition when Flume becomes supported service in any stack
+      if (item.StackServices.service_name !== 'FLUME' || App.supports.flume) {
+        var stackService = item.StackServices;
+        var serviceComponents = [];
+        item.serviceComponents.forEach(function (serviceComponent) {
+          serviceComponent.StackServiceComponents.id = serviceComponent.StackServiceComponents.component_name;
+          serviceComponent.StackServiceComponents.dependencies = serviceComponent.dependencies;
+          serviceComponents.push(serviceComponent.StackServiceComponents);
+          stackServiceComponents.push(this.parseIt(serviceComponent.StackServiceComponents, this.get('component_config')));
+        }, this);
+        stackService.service_components = serviceComponents;
+        result.push(this.parseIt(stackService, this.get('config')));
+      }
+    }, this);
+    App.store.loadMany(this.get('component_model'), stackServiceComponents);
+    App.store.loadMany(model, result);
+  },
+
+  rearrangeServicesForDisplayOrder: function (array, displayOrderArray) {
+    return array.sort(function (a, b) {
+      var aValue = displayOrderArray.indexOf(a.StackServices.service_name) != -1 ? displayOrderArray.indexOf(a.StackServices.service_name) : array.length;
+      var bValue = displayOrderArray.indexOf(b.StackServices.service_name) != -1 ? displayOrderArray.indexOf(b.StackServices.service_name) : array.length;
+      return aValue - bValue;
+    });
+  }
+});
+

+ 7 - 15
ambari-web/app/messages.js

@@ -580,28 +580,20 @@ Em.I18n.translations = {
 
 
   'installer.step4.header':'Choose Services',
   'installer.step4.header':'Choose Services',
   'installer.step4.body':'Choose which services you want to install on your cluster.',
   'installer.step4.body':'Choose which services you want to install on your cluster.',
-  'installer.step4.hdfsCheck.popup.header':'File System Required',
-  'installer.step4.hdfsCheck.popup.body':'You did not select a File System but one is required. We will automatically add HDFS. Is this OK?',
+  'installer.step4.fsCheck.popup.header':'File System Required',
+  'installer.step4.fsCheck.popup.body':'You did not select a File System but one is required. We will automatically add {0}. Is this OK?',
   'installer.step4.multipleDFS.popup.header':'Multiple File Systems Selected',
   'installer.step4.multipleDFS.popup.header':'Multiple File Systems Selected',
-  'installer.step4.multipleDFS.popup.body':'You selected more than one file system. We will automatically select only HDFS. Is this OK?',
-  'installer.step4.mapreduceCheck.popup.header':'MapReduce Needed',
-  'installer.step4.mapreduceCheck.popup.body':'You did not select MapReduce, but it is needed by other services you selected. We will automatically add MapReduce. Is this OK?',
-  'installer.step4.yarnCheck.popup.header':'YARN+MapReduce2 Needed',
-  'installer.step4.yarnCheck.popup.body':'You did not select YARN+MapReduce2, but it is needed by other services you selected. We will automatically add YARN+MapReduce2. Is this OK?',
-  'installer.step4.zooKeeperCheck.popup.header':'ZooKeeper Needed',
-  'installer.step4.zooKeeperCheck.popup.body':'You did not select ZooKeeper, but it is needed by other services you selected. We will automatically add ZooKeeper. Is this OK?',
-  'installer.step4.oozieCheck.popup.header':'Oozie Needed',
-  'installer.step4.oozieCheck.popup.body':'You did not select Oozie, but it is needed by other services you selected. We will automatically add Oozie. Is this OK?',
-  'installer.step4.tezCheck.popup.header':'Tez Needed',
-  'installer.step4.tezCheck.popup.body':'You did not select Tez, but it is needed by other services you selected. We will automatically add Tez. Is this OK?',
+  'installer.step4.multipleDFS.popup.body':'You selected more than one file system. We will automatically select only {0}. Is this OK?',
+  'installer.step4.serviceCheck.popup.header':'{0} Needed',
+  'installer.step4.serviceCheck.popup.body':'You did not select {0}, but it is needed by other services you selected. We will automatically add {0}. Is this OK?',
   'installer.step4.monitoringCheck.popup.header':'Limited Functionality Warning',
   'installer.step4.monitoringCheck.popup.header':'Limited Functionality Warning',
-  'installer.step4.monitoringCheck.popup.body':'You did not select Nagios and/or Ganglia. If both are not selected, monitoring and alerts will not function properly. Is this OK?',
+  'installer.step4.monitoringCheck.popup.body':'You did not select {0}. If {1} is not selected, monitoring and alerts will not function properly. Is this OK?',
 
 
   'installer.step5.header':'Assign Masters',
   'installer.step5.header':'Assign Masters',
   'installer.step5.reassign.header':'Select Target Host',
   'installer.step5.reassign.header':'Select Target Host',
   'installer.step5.attention':' hosts not running master services',
   'installer.step5.attention':' hosts not running master services',
   'installer.step5.body':'Assign master components to hosts you want to run them on.',
   'installer.step5.body':'Assign master components to hosts you want to run them on.',
-  'installer.step5.body.hive':'<i class="icon-asterisks">&#10037;</i> HiveServer2, Hive Metastore, and WebHCat Server will be hosted on the same server.',
+  'installer.step5.body.coHostedComponents':'<i class="icon-asterisks">&#10037;</i> {0} will be hosted on the same host.',
   'installer.step5.hostInfo':'%@ (%@, %@ cores)',
   'installer.step5.hostInfo':'%@ (%@, %@ cores)',
   'installer.step5.hiveGroup':'HiveServer2, WebHCat Server, MySQL Server',
   'installer.step5.hiveGroup':'HiveServer2, WebHCat Server, MySQL Server',
 
 

+ 2 - 1
ambari-web/app/mixins.js

@@ -21,6 +21,7 @@
 
 
 require('mixins/common/localStorage');
 require('mixins/common/localStorage');
 require('mixins/common/userPref');
 require('mixins/common/userPref');
+require('mixins/models/service_mixin');
 require('mixins/common/tableServerProvider');
 require('mixins/common/tableServerProvider');
 require('mixins/main/host/details/host_components/decommissionable');
 require('mixins/main/host/details/host_components/decommissionable');
-require('mixins/wizard/selectHost');
+require('mixins/wizard/selectHost');

+ 10 - 24
ambari-web/app/mappers/stack_service_component_mapper.js → ambari-web/app/mixins/models/service_mixin.js

@@ -18,27 +18,13 @@
 
 
 var App = require('app');
 var App = require('app');
 
 
-App.stackServiceComponentMapper = App.QuickDataMapper.create({
-  model: App.StackServiceComponent,
-  config: {
-    id: 'component_name',
-    component_name: 'component_name',
-    service_name: 'service_name',
-    component_category: 'component_category',
-    is_master: 'is_master',
-    is_client: 'is_client',
-    stack_name: 'stack_name',
-    stack_version: 'stack_version'
-  },
-
-  map: function (json) {
-    var model = this.get('model');
-    if (json.items) {
-      var result = [];
-      json.items.forEach(function (item) {
-        result.push(this.parseIt(item, this.get('config')));
-      }, this);
-      App.store.loadMany(model, result);
-    }
-  }
-});
+/**
+ * Service Mixin that used for App.StackService and App.Service models.
+ *
+ **/
+App.ServiceModelMixin = Em.Mixin.create({
+  serviceName: DS.attr('string'),
+  displayName: function() {
+    return App.format.role(this.get('serviceName'));
+  }.property('serviceName')
+});

+ 1 - 0
ambari-web/app/models.js

@@ -24,6 +24,7 @@ require('models/authentication');
 require('models/cluster');
 require('models/cluster');
 require('models/cluster_states');
 require('models/cluster_states');
 require('models/hosts');
 require('models/hosts');
+require('models/stack_service');
 require('models/stack_service_component');
 require('models/stack_service_component');
 require('models/quick_links');
 require('models/quick_links');
 require('models/service');
 require('models/service');

+ 1 - 5
ambari-web/app/models/host_component.js

@@ -33,11 +33,7 @@ App.HostComponent = DS.Model.extend({
    * @returns {bool}
    * @returns {bool}
    */
    */
   isClient:function () {
   isClient:function () {
-    if(['PIG', 'SQOOP', 'HCAT', 'MAPREDUCE2_CLIENT'].contains(this.get('componentName'))){
-      return true;
-    }
-
-    return Boolean(this.get('componentName').match(/_client/gi));
+    return App.get('components.clients').contains(this.get('componentName'));
   }.property('componentName'),
   }.property('componentName'),
   /**
   /**
    * Determine if component is running now
    * Determine if component is running now

+ 2 - 55
ambari-web/app/models/service.js

@@ -19,10 +19,9 @@
 
 
 var App = require('app');
 var App = require('app');
 require('utils/config');
 require('utils/config');
+require('mixins/models/service_mixin');
 
 
-App.Service = DS.Model.extend({
-
-  serviceName: DS.attr('string'),
+App.Service = DS.Model.extend(App.ServiceModelMixin, {
   passiveState: DS.attr('string'),
   passiveState: DS.attr('string'),
   workStatus: DS.attr('string'),
   workStatus: DS.attr('string'),
   rand: DS.attr('string'),
   rand: DS.attr('string'),
@@ -72,35 +71,6 @@ App.Service = DS.Model.extend({
     return this.get('workStatus') === 'STARTED';
     return this.get('workStatus') === 'STARTED';
   }.property('workStatus'),
   }.property('workStatus'),
 
 
-  isClientsOnly: function() {
-    var clientsOnly = ['GLUSTERFS','SQOOP','PIG','TEZ','HCATALOG'];
-    return clientsOnly.contains(this.get('serviceName'));
-  }.property('serviceName'),
-
-  isConfigurable: function () {
-    var configurableServices = [
-      "HDFS",
-      "GLUSTERFS",
-      "YARN",
-      "MAPREDUCE",
-      "MAPREDUCE2",
-      "HBASE",
-      "OOZIE",
-      "HIVE",
-      "WEBHCAT",
-      "ZOOKEEPER",
-      "PIG",
-      "NAGIOS",
-      "GANGLIA",
-      "HUE",
-      "TEZ",
-      "STORM",
-      "FALCON",
-      "FLUME"
-    ];
-    return configurableServices.contains(this.get('serviceName'));
-  }.property('serviceName'),
-
   /**
   /**
    * Service Tagging by their type.
    * Service Tagging by their type.
    * @type {String[]}
    * @type {String[]}
@@ -230,29 +200,6 @@ App.Service.DisplayNames = {
   'STORM': 'Storm'
   'STORM': 'Storm'
 };
 };
 
 
-App.Service.servicesSortOrder = [
-  'HDFS',
-  'GLUSTERFS',
-  'YARN',
-  'MAPREDUCE',
-  'MAPREDUCE2',
-  'TEZ',
-  'HBASE',
-  'HIVE',
-  'HCATALOG',
-  'WEBHCAT',
-  'FLUME',
-  'FALCON',
-  'STORM',
-  'OOZIE',
-  'GANGLIA',
-  'NAGIOS',
-  'ZOOKEEPER',
-  'PIG',
-  'SQOOP',
-  'HUE'
-];
-
 /**
 /**
  * association between service and extended model name
  * association between service and extended model name
  * @type {Object}
  * @type {Object}

+ 382 - 0
ambari-web/app/models/stack_service.js

@@ -0,0 +1,382 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+require('utils/helper');
+require('mixins/models/service_mixin');
+require('models/service_config');
+require('utils/configs/defaults_providers/yarn_defaults_provider');
+require('utils/configs/defaults_providers/tez_defaults_provider');
+require('utils/configs/defaults_providers/hive_defaults_provider');
+require('utils/configs/defaults_providers/storm_defaults_provider');
+require('utils/configs/defaults_providers/oozie_defaults_provider');
+require('utils/configs/validators/yarn_configs_validator');
+require('utils/configs/validators/hive_configs_validator');
+require('utils/configs/validators/tez_configs_validator');
+require('utils/configs/validators/mapreduce2_configs_validator');
+require('utils/configs/validators/storm_configs_validator');
+
+/**
+ * This model loads all services supported by the stack
+ * The model maps to the  http://hostname:8080/api/v1/stacks2/HDP/versions/${versionNumber}/stackServices?fields=StackServices/*,serviceComponents/*
+ * @type {*}
+ */
+App.StackService = DS.Model.extend(App.ServiceModelMixin, {
+  comments: DS.attr('string'),
+  configTypes: DS.attr('array'),
+  serviceVersion: DS.attr('string'),
+  stackName: DS.attr('string'),
+  stackVersion: DS.attr('string'),
+  isSelected: DS.attr('boolean', {defaultValue: true}),
+  isInstalled: DS.attr('boolean', {defaultValue: false}),
+  serviceComponents: DS.hasMany('App.StackServiceComponent'),
+  configs: DS.attr('array'),
+
+  // Is the service a distributed filesystem
+  isDFS: function () {
+    var dfsServices = ['HDFS', 'GLUSTERFS'];
+    return dfsServices.contains(this.get('serviceName'));
+  }.property('serviceName'),
+
+  // Primary DFS. used if there is more than one DFS in a stack.
+  // Only one service in the stack should be tagged as primary DFS.
+  isPrimaryDFS: function () {
+    return this.get('serviceName') === 'HDFS';
+  }.property('serviceName'),
+
+  displayNameOnSelectServicePage: function () {
+    var displayName = this.get('displayName');
+    var services = this.get('coSelectedServices').slice();
+    var serviceDisplayNames = services.map(function (item) {
+      return App.format.role(item);
+    }, this);
+    if (!!serviceDisplayNames.length) {
+      serviceDisplayNames.unshift(displayName);
+      displayName = serviceDisplayNames.join(" + ");
+    }
+    return displayName;
+  }.property('coSelectedServices', 'serviceName'),
+
+  isHiddenOnSelectServicePage: function () {
+    var hiddenServices = ['MAPREDUCE2', 'HCATALOG', 'WEBHCAT'];
+    return hiddenServices.contains(this.get('serviceName'));
+  }.property('serviceName'),
+
+  dependentServices: function () {
+    var serviceName = this.get('serviceName');
+    var dependentServices = [];
+    if (App.get('isHadoop2Stack')) {
+      dependentServices = App.StackService.dependency['HDP-2'][serviceName];
+    } else {
+      dependentServices = App.StackService.dependency['HDP-1'][serviceName];
+    }
+    return dependentServices;
+  }.property('serviceName'),
+
+  /**
+   * other services on which the service is dependent
+   */
+  serviceDependency: function () {
+    var serviceName = this.get('serviceName');
+    var serviceDependencyMap, key, serviceDependencies = [];
+    if (App.get('isHadoop2Stack')) {
+      serviceDependencyMap = App.StackService.dependency['HDP-2'];
+    } else {
+      serviceDependencyMap = App.StackService.dependency['HDP-1'];
+    }
+    for (key in serviceDependencyMap) {
+      if (serviceDependencyMap[key].contains(serviceName)) serviceDependencies.pushObject(key);
+    }
+    return  serviceDependencies;
+  }.property('serviceName'),
+
+  // Is the service required for monitoring of other hadoop ecosystem services
+  isMonitoringService: function () {
+    var services = ['NAGIOS', 'GANGLIA'];
+    return services.contains(this.get('serviceName'));
+  }.property('serviceName'),
+
+  coSelectedServices: function () {
+    var coSelectedServices = App.StackService.coSelected[this.get('serviceName')];
+    if (!!coSelectedServices) {
+      return coSelectedServices;
+    } else {
+      return [];
+    }
+  }.property('serviceName'),
+
+  hasClient: function () {
+    var serviceComponents = this.get('serviceComponents');
+    return serviceComponents.someProperty('isClient');
+  }.property('serviceName'),
+
+  isClientOnlyService: function () {
+    var serviceComponents = this.get('serviceComponents');
+    return serviceComponents.everyProperty('isClient');
+  }.property('serviceName'),
+
+  isNoConfigTypes: function () {
+   return !(this.get('configTypes') && this.get('configTypes').length);
+  }.property('configTypes'),
+
+  customReviewHandler: function () {
+    return App.StackService.reviewPageHandlers[this.get('serviceName')];
+  }.property('serviceName'),
+
+  defaultsProviders: function () {
+    var defaultConfigsHandler = App.StackService.defaultConfigsHandler[this.get('serviceName')];
+    return defaultConfigsHandler && defaultConfigsHandler.defaultsProviders;
+  }.property('serviceName'),
+
+  configsValidator: function () {
+    var defaultConfigsHandler = App.StackService.defaultConfigsHandler[this.get('serviceName')];
+    return defaultConfigsHandler && defaultConfigsHandler.configsValidator;
+  }.property('serviceName'),
+
+  /**
+   * configCategories are fetched from  App.StackService.configCategories.
+   * Also configCategories that does not match any serviceComponent of a service and not included in the permissible default pattern are omitted
+   */
+  configCategories: function () {
+    var configCategories = [];
+    var serviceName = this.get('serviceName');
+    var configTypes = this.get('configTypes');
+    var serviceComponents = this.get('serviceComponents');
+    if (configTypes.length) {
+      var pattern = ["General", "CapacityScheduler", "^Advanced", "^Custom", "Falcon - Oozie integration", "FalconStartupSite", "FalconRuntimeSite"];
+      configCategories = App.StackService.configCategories(serviceName).filter(function (_configCategory) {
+        var serviceComponentName = _configCategory.get('name');
+        var isServiceComponent = serviceComponents.someProperty('componentName', serviceComponentName);
+        if (isServiceComponent) return  isServiceComponent;
+        var result = false;
+        pattern.forEach(function (_pattern) {
+          var regex = new RegExp(_pattern);
+          if (regex.test(serviceComponentName)) result = true;
+        });
+        return result;
+      });
+    }
+    return configCategories;
+  }.property('serviceName', 'configTypes', 'serviceComponents'),
+
+  serviceConfigs: function () {
+    var configCategories = [];
+    var serviceName = this.get('serviceName');
+    var serviceComponents = this.get('serviceComponents');
+    configCategories = App.StackService.configCategories(serviceName).filter(function (_configCategory) {
+      var serviceComponentName = _configCategory.get('name');
+      return serviceComponents.someProperty('componentName', serviceComponentName);
+    });
+    return configCategories;
+  }.observes('serviceName', 'serviceComponents')
+
+});
+
+App.StackService.FIXTURES = [];
+
+App.StackService.displayOrder = [
+  'HDFS',
+  'MAPREDUCE',
+  'MAPREDUCE2',
+  'YARN',
+  'TEZ',
+  'NAGIOS',
+  'GANGLIA',
+  'HIVE',
+  'HCATALOG',
+  'WEBHCAT',
+  'HBASE',
+  'PIG',
+  'SQOOP',
+  'OOZIE',
+  'ZOOKEEPER',
+  'HUE',
+  'FALCON',
+  'STORM',
+  'FLUME'
+];
+
+App.StackService.dependency = {
+  'HDP-1': {
+    'MAPREDUCE': ['PIG', 'OOZIE', 'HIVE'],
+    'ZOOKEEPER': ['HBASE', 'HIVE', 'WEBHCAT']
+  },
+  'HDP-2': {
+    'YARN': ['PIG', 'OOZIE', 'HIVE', 'TEZ'],
+    'TEZ': ['YARN'],
+    'OOZIE': ['FALCON'],
+    'ZOOKEEPER': ['HDFS', 'HBASE', 'HIVE', 'WEBHCAT', 'STORM']
+  }
+};
+
+//@TODO: Write unit test for no two keys in the object should have any intersecting elements in their values
+App.StackService.coSelected = {
+  'YARN': ['MAPREDUCE2'],
+  'HIVE': ['HCATALOG', 'WEBHCAT']
+};
+
+
+App.StackService.reviewPageHandlers = {
+  'HIVE': {
+    'Database': 'loadHiveDbValue'
+  },
+  'NAGIOS': {
+    'Administrator': 'loadNagiosAdminValue'
+  },
+  'OOZIE': {
+    'Database': 'loadOozieDbValue'
+  }
+};
+
+App.StackService.defaultConfigsHandler = {
+  YARN: {defaultsProviders: [App.YARNDefaultsProvider.create()], configsValidator: App.YARNConfigsValidator},
+  MAPREDUCE2: {defaultsProviders: [App.YARNDefaultsProvider.create()], configsValidator: App.MapReduce2ConfigsValidator},
+  HIVE: {defaultsProviders: [App.HiveDefaultsProvider.create()], configsValidator: App.HiveConfigsValidator},
+  STORM: {defaultsProviders: [App.STORMDefaultsProvider.create()], configsValidator: App.STORMConfigsValidator},
+  TEZ: {defaultsProviders: [App.TezDefaultsProvider.create()], configsValidator: App.TezConfigsValidator}
+};
+
+App.StackService.configCategories = function (serviceName) {
+  switch (serviceName) {
+    case 'HDFS':
+      return [
+        App.ServiceConfigCategory.create({ name: 'NAMENODE', displayName: 'NameNode'}),
+        App.ServiceConfigCategory.create({ name: 'SECONDARY_NAMENODE', displayName: 'Secondary NameNode'}),
+        App.ServiceConfigCategory.create({ name: 'DATANODE', displayName: 'DataNode'}),
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedCoreSite', displayName: 'Custom core-site.xml', siteFileName: 'core-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHDFSSite', displayName: 'Custom hdfs-site.xml', siteFileName: 'hdfs-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHDFSLog4j', displayName: 'Custom log4j.properties', siteFileName: 'hdfs-log4j.xml', canAddProperty: false})
+      ];
+    case 'GLUSTERFS':
+      return [
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedGlusterFSSite', displayName : 'Custom core-site.xml', siteFileName: 'core-site.xml', canAddProperty: true})
+      ];
+    case 'MAPREDUCE':
+      return [
+        App.ServiceConfigCategory.create({ name: 'HISTORYSERVER', displayName: 'History Server'}),
+        App.ServiceConfigCategory.create({ name: 'JOBTRACKER', displayName: 'JobTracker'}),
+        App.ServiceConfigCategory.create({ name: 'TASKTRACKER', displayName: 'TaskTracker'}),
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedMapredSite', displayName: 'Custom mapred-site.xml', siteFileName: 'mapred-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedMapredLog4j', displayName: 'Custom log4j.properties', siteFileName: 'mapreduce-log4j.xml', canAddProperty: false})
+      ];
+    case 'YARN':
+      return [
+        App.ServiceConfigCategory.create({ name: 'RESOURCEMANAGER', displayName: 'Resource Manager'}),
+        App.ServiceConfigCategory.create({ name: 'NODEMANAGER', displayName: 'Node Manager'}),
+        App.ServiceConfigCategory.create({ name: 'APP_TIMELINE_SERVER', displayName: 'Application Timeline Server'}),
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'CapacityScheduler', displayName: 'Scheduler', isCapacityScheduler: true, isCustomView: true, siteFileName: 'capacity-scheduler.xml', siteFileNames: ['capacity-scheduler.xml', 'mapred-queue-acls.xml'], canAddProperty: App.supports.capacitySchedulerUi}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedYARNSite', displayName: 'Custom yarn-site.xml', siteFileName: 'yarn-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedYARNLog4j', displayName: 'Custom log4j.properties', siteFileName: 'yarn-log4j.xml', canAddProperty: false})
+      ];
+    case 'MAPREDUCE2':
+      return [
+        App.ServiceConfigCategory.create({ name: 'HISTORYSERVER', displayName: 'History Server'}),
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedMapredSite', displayName: 'Custom mapred-site.xml', siteFileName: 'mapred-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedMapredLog4j', displayName: 'Custom log4j.properties', siteFileName: 'mapreduce2-log4j.xml', canAddProperty: false})
+      ];
+    case 'HIVE':
+      return [
+        App.ServiceConfigCategory.create({ name: 'HIVE_METASTORE', displayName: 'Hive Metastore'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHiveSite', displayName: 'Custom hive-site.xml', siteFileName: 'hive-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHiveLog4j', displayName: 'Custom log4j.properties', siteFileName: 'hive-log4j.xml', canAddProperty: false}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHiveExecLog4j', displayName: 'Custom hive-exec-log4j', siteFileName: 'hive-exec-log4j.xml', canAddProperty: false})
+      ];
+    case 'WEBHCAT':
+      return [
+        App.ServiceConfigCategory.create({ name: 'WEBHCAT_SERVER', displayName: 'WebHCat Server'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedWebHCatSite', displayName: 'Custom webhcat-site.xml', siteFileName: 'webhcat-site.xml', canAddProperty: true})
+      ];
+    case 'HBASE':
+      return [
+        App.ServiceConfigCategory.create({ name: 'HBASE_MASTER', displayName: 'HBase Master'}),
+        App.ServiceConfigCategory.create({ name: 'HBASE_REGIONSERVER', displayName: 'RegionServer'}),
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHbaseSite', displayName: 'Custom hbase-site.xml', siteFileName: 'hbase-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedHbaseLog4j', displayName: 'Custom log4j.properties', siteFileName: 'hbase-log4j.xml', canAddProperty: false})
+      ];
+    case 'ZOOKEEPER':
+      return [
+        App.ServiceConfigCategory.create({ name: 'ZOOKEEPER_SERVER', displayName: 'ZooKeeper Server'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedZooLog4j', displayName: 'Custom log4j.properties', siteFileName: 'zookeeper-log4j.xml', canAddProperty: false}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedZooCfg', displayName: 'Custom zoo.cfg', siteFileName: 'zoo.cfg', canAddProperty: true})
+      ];
+    case 'OOZIE':
+      return [
+        App.ServiceConfigCategory.create({ name: 'OOZIE_SERVER', displayName: 'Oozie Server'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedOozieSite', displayName: 'Custom oozie-site.xml', siteFileName: 'oozie-site.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedOozieLog4j', displayName: 'Custom log4j.properties', siteFileName: 'oozie-log4j.xml', canAddProperty: false})
+      ];
+    case 'PIG':
+    return [
+      App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Custom pig.properties', siteFileName: 'pig-properties.xml', canAddProperty: false}),
+      App.ServiceConfigCategory.create({ name: 'AdvancedPigLog4j', displayName: 'Custom log4j.properties', siteFileName: 'pig-log4j.xml', canAddProperty: false})
+    ];
+    case 'FALCON':
+      return [
+        App.ServiceConfigCategory.create({ name: 'FALCON_SERVER', displayName: 'Falcon Server'}),
+        App.ServiceConfigCategory.create({ name: 'Falcon - Oozie integration', displayName: 'Falcon - Oozie integration'}),
+        App.ServiceConfigCategory.create({ name: 'FalconStartupSite', displayName: 'Falcon startup.properties'}),
+        App.ServiceConfigCategory.create({ name: 'FalconRuntimeSite', displayName: 'Falcon runtime.properties'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedFalconStartupSite', displayName: 'Custom startup.properties', siteFileName: 'falcon-startup.properties.xml', canAddProperty: true}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedFalconRuntimeSite', displayName: 'Custom runtime.properties', siteFileName: 'falcon-runtime.properties.xml', canAddProperty: true})
+      ];
+    case 'STORM':
+      return [
+        App.ServiceConfigCategory.create({ name: 'NIMBUS', displayName: 'Nimbus'}),
+        App.ServiceConfigCategory.create({ name: 'SUPERVISOR', displayName: 'Supervisor'}),
+        App.ServiceConfigCategory.create({ name: 'STORM_UI_SERVER', displayName: 'Storm UI Server'}),
+        App.ServiceConfigCategory.create({ name: 'STORM_REST_API', displayName: 'Storm REST API Server'}),
+        App.ServiceConfigCategory.create({ name: 'DRPC_SERVER', displayName: 'DRPC Server'}),
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedStormSite', displayName: 'Custom storm.yaml', siteFileName: 'storm-site.xml', canAddProperty: true})
+      ];
+    case 'TEZ':
+      return [
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General'}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced'}),
+        App.ServiceConfigCategory.create({ name: 'AdvancedTezSite', displayName: 'Custom tez-site.xml', siteFileName: 'tez-site.xml', canAddProperty: true})
+      ];
+    case 'FLUME':
+      return [
+        App.ServiceConfigCategory.create({ name: 'FLUME_HANDLER', displayName: 'flume.conf', siteFileName: 'flume-conf', canAddProperty: false})
+      ];
+    case 'HCATALOG':
+      return [];
+    default:
+      return [
+        App.ServiceConfigCategory.create({ name: 'General', displayName: 'General', canAddProperty: false}),
+        App.ServiceConfigCategory.create({ name: 'Advanced', displayName: 'Advanced', canAddProperty: false})
+      ];
+  }
+};

+ 142 - 4
ambari-web/app/models/stack_service_component.js

@@ -23,15 +23,22 @@ var App = require('app');
  */
  */
 App.StackServiceComponent = DS.Model.extend({
 App.StackServiceComponent = DS.Model.extend({
   componentName: DS.attr('string'),
   componentName: DS.attr('string'),
+  dependencies: DS.attr('array'),
   serviceName: DS.attr('string'),
   serviceName: DS.attr('string'),
   componentCategory: DS.attr('string'),
   componentCategory: DS.attr('string'),
   isMaster: DS.attr('boolean'),
   isMaster: DS.attr('boolean'),
   isClient: DS.attr('boolean'),
   isClient: DS.attr('boolean'),
   stackName: DS.attr('string'),
   stackName: DS.attr('string'),
   stackVersion: DS.attr('string'),
   stackVersion: DS.attr('string'),
+  stackService: DS.belongsTo('App.StackService'),
+  serviceComponentId: DS.attr('number', {defaultValue: 1}), // this is used on Assign Master page for multiple masters
 
 
   displayName: function() {
   displayName: function() {
-    return App.format.components[this.get('componentName')];
+    if (App.format.role(this.get('componentName'))) {
+      return App.format.role(this.get('componentName'));
+    } else {
+      return this.get('componentName');
+    }
   }.property('componentName'),
   }.property('componentName'),
 
 
   isSlave: function() {
   isSlave: function() {
@@ -68,9 +75,140 @@ App.StackServiceComponent = DS.Model.extend({
 
 
   isShownOnInstallerAssignMasterPage: function() {
   isShownOnInstallerAssignMasterPage: function() {
     var component = this.get('componentName');
     var component = this.get('componentName');
-    var mastersNotShown = ['MYSQL_SERVER','JOURNALNODE'];
+    var mastersNotShown = ['MYSQL_SERVER'];
     return ((this.get('isMaster') && !mastersNotShown.contains(component)) || component === 'APP_TIMELINE_SERVER');
     return ((this.get('isMaster') && !mastersNotShown.contains(component)) || component === 'APP_TIMELINE_SERVER');
-  }.property('isMaster','componentName')
+  }.property('isMaster','componentName'),
+
+  isShownOnInstallerSlaveClientPage: function() {
+    var component = this.get('componentName');
+    var slavesNotShown = ['JOURNALNODE','ZKFC','APP_TIMELINE_SERVER','GANGLIA_MONITOR'];
+    return this.get('isSlave') && !slavesNotShown.contains(component);
+  }.property('isSlave','componentName'),
+
+  isShownOnAddServiceAssignMasterPage: function() {
+    var isVisible = this.get('isShownOnInstallerAssignMasterPage');
+    if (App.get('isHaEnabled')) {
+      isVisible =  isVisible && this.get('componentName') !== 'SECONDARY_NAMENODE';
+    }
+    return isVisible;
+  }.property('isShownOnInstallerAssignMasterPage','App.isHaEnabled'),
+
+  isMasterWithMultipleInstances: function() {
+    var masters = ['ZOOKEEPER_SERVER', 'HBASE_MASTER'];
+    return masters.contains(this.get('componentName'));
+  }.property('componentName'),
+
+  /** Some non master components can be assigned as master **/
+  isMasterBehavior: function() {
+    var componentsName = ['APP_TIMELINE_SERVER'];
+    return componentsName.contains(this.get('componentName'));
+  }.property('componentName'),
+
+  /** Some non client components can be assigned as clients **/
+  isClientBehavior: function() {
+    var componentName = ['GANGLIA_MONITOR'];
+    return componentName.contains(this.get('componentName'));
+  }.property('componentName'),
+
+  /** Components that can be installed only if HA enabled **/
+  isHAComponentOnly: function() {
+    var HAComponentNames = ['ZKFC','JOURNALNODE'];
+    return HAComponentNames.contains(this.get('componentName'));
+  }.property('componentName'),
+
+  // Is It require to install the components on all hosts. used in step-6 wizard controller
+  isRequiredOnAllHosts: function() {
+    var service = this.get('stackService');
+    return service.get('isMonitoringService') && this.get('isSlave') ;
+  }.property('stackService','isSlave'),
+
+  // components that are not to be installed with ambari server
+  isNotPreferableOnAmbariServerHost: function() {
+    var service = ['STORM_UI_SERVER', 'DRPC_SERVER', 'STORM_REST_API', 'NIMBUS', 'GANGLIA_SERVER', 'NAGIOS_SERVER', 'HUE_SERVER'];
+    return service.contains(this.get('componentName'));
+  }.property('componentName'),
+
+  // default number of master hosts on Assign Master page:
+  defaultNoOfMasterHosts: function() {
+    var componentName = this.get('componentName');
+     if (this.get('isMasterWithMultipleInstances')) {
+       return App.StackServiceComponent.cardinality(componentName).min;
+     }
+  }.property('componentName'),
+
+  selectionSchemeForMasterComponent: function() {
+    return App.StackServiceComponent.selectionScheme(this.get('componentName'));
+  }.property('componentName'),
+
+  isMasterWithMultipleInstancesHaWizard: function() {
+    var masters = ['NAMENODE', 'JOURNALNODE'];
+    return masters.contains(this.get('componentName'));
+  }.property('componentName'),
+
+  // components that are co-hosted with this component
+  coHostedComponents: function() {
+    var componentName = this.get('componentName');
+    var key, coHostedComponents = [];
+    for (key in App.StackServiceComponent.coHost) {
+      if (App.StackServiceComponent.coHost[key] === componentName) {
+        coHostedComponents.push(key)
+      }
+    }
+    return coHostedComponents;
+  }.property('componentName'),
+
+  // Is any other component co-hosted with this component
+  isOtherComponentCoHosted: function() {
+    return !!this.get('coHostedComponents').length;
+  }.property('coHostedComponents'),
+
+  // Is this component co-hosted with other component
+  isCoHostedComponent: function() {
+    var componentName = this.get('componentName');
+    return !!App.StackServiceComponent.coHost[componentName];
+  }.property('componentName')
+
 });
 });
 
 
-App.StackServiceComponent.FIXTURES = [];
+App.StackServiceComponent.FIXTURES = [];
+
+App.StackServiceComponent.selectionScheme = function (componentName){
+  switch (componentName) {
+    case 'NAMENODE' :
+      return {"else": 0};
+    case 'SECONDARY_NAMENODE' :
+      return {"else": 1};
+    case 'HBASE_MASTER':
+      return {"6": 0, "31": 2, "else": 3};
+    case 'JOBTRACKER':
+    case 'HISTORYSERVER':
+    case 'RESOURCEMANAGER':
+    case 'APP_TIMELINE_SERVER':
+      return {"31": 1, "else": 2};
+    case 'OOZIE_SERVER':
+    case 'FALCON_SERVER' :
+      return {"6": 1, "31": 2, "else": 3};
+    case 'HIVE_SERVER' :
+    case 'HIVE_METASTORE' :
+    case 'WEBHCAT_SERVER' :
+      return {"6": 1, "31": 2, "else": 4};
+    default:
+      return {"else": 0};
+  }
+};
+
+App.StackServiceComponent.cardinality = function (componentName) {
+  switch (componentName) {
+    case 'ZOOKEEPER_SERVER':
+      return {min: 3};
+    case 'HBASE_MASTER':
+      return {min: 1};
+    default:
+      return {min:1, max:1};
+  }
+};
+
+App.StackServiceComponent.coHost = {
+  'HIVE_METASTORE': 'HIVE_SERVER',
+  'WEBHCAT_SERVER': 'HIVE_SERVER'
+};

+ 0 - 2
ambari-web/app/routes/add_host_routes.js

@@ -102,7 +102,6 @@ module.exports = App.WizardRoute.extend({
       controller.setCurrentStep('1');
       controller.setCurrentStep('1');
       controller.set('hideBackButton', true);
       controller.set('hideBackButton', true);
       controller.dataLoading().done(function () {
       controller.dataLoading().done(function () {
-        controller.loadServicesFromServer();
         controller.loadAllPriorSteps();
         controller.loadAllPriorSteps();
         var wizardStep2Controller = router.get('wizardStep2Controller');
         var wizardStep2Controller = router.get('wizardStep2Controller');
         wizardStep2Controller.set('wizardController', controller);
         wizardStep2Controller.set('wizardController', controller);
@@ -184,7 +183,6 @@ module.exports = App.WizardRoute.extend({
         var wizardStep6Controller = router.get('wizardStep6Controller');
         var wizardStep6Controller = router.get('wizardStep6Controller');
         wizardStep6Controller.set('wizardController', controller);
         wizardStep6Controller.set('wizardController', controller);
         controller.connectOutlet('wizardStep6', controller.get('content'));
         controller.connectOutlet('wizardStep6', controller.get('content'));
-        wizardStep6Controller.set('isMasters', false);
       });
       });
     },
     },
     back: Em.Router.transitionTo('step2'),
     back: Em.Router.transitionTo('step2'),

+ 1 - 2
ambari-web/app/routes/add_service_routes.js

@@ -102,9 +102,9 @@ module.exports = App.WizardRoute.extend({
       console.log('in addService.step1:connectOutlets');
       console.log('in addService.step1:connectOutlets');
       var controller = router.get('addServiceController');
       var controller = router.get('addServiceController');
       controller.setCurrentStep('1');
       controller.setCurrentStep('1');
+      controller.setDBProperty('services',undefined);
       controller.set('hideBackButton', true);
       controller.set('hideBackButton', true);
       controller.dataLoading().done(function () {
       controller.dataLoading().done(function () {
-        controller.loadServicesFromServer();
         controller.loadAllPriorSteps();
         controller.loadAllPriorSteps();
         controller.connectOutlet('wizardStep4', controller.get('content.services'));
         controller.connectOutlet('wizardStep4', controller.get('content.services'));
       })
       })
@@ -153,7 +153,6 @@ module.exports = App.WizardRoute.extend({
         var wizardStep6Controller = router.get('wizardStep6Controller');
         var wizardStep6Controller = router.get('wizardStep6Controller');
         wizardStep6Controller.set('wizardController', controller);
         wizardStep6Controller.set('wizardController', controller);
         controller.connectOutlet('wizardStep6', controller.get('content'));
         controller.connectOutlet('wizardStep6', controller.get('content'));
-        wizardStep6Controller.set('isMasters', false);
       })
       })
     },
     },
     back: function(router){
     back: function(router){

+ 3 - 2
ambari-web/app/routes/installer.js

@@ -204,7 +204,8 @@ module.exports = Em.Route.extend({
       var wizardStep3Controller = router.get('wizardStep3Controller');
       var wizardStep3Controller = router.get('wizardStep3Controller');
       installerController.saveConfirmedHosts(wizardStep3Controller);
       installerController.saveConfirmedHosts(wizardStep3Controller);
       installerController.setDBProperty('bootStatus', true);
       installerController.setDBProperty('bootStatus', true);
-      installerController.loadServicesFromServer();
+      installerController.setDBProperty('selectedServiceNames', undefined);
+      installerController.setDBProperty('installedServiceNames', undefined);
       router.transitionTo('step4');
       router.transitionTo('step4');
     },
     },
     exit: function (router) {
     exit: function (router) {
@@ -230,7 +231,7 @@ module.exports = Em.Route.extend({
       var controller = router.get('installerController');
       var controller = router.get('installerController');
       controller.setCurrentStep('4');
       controller.setCurrentStep('4');
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
-      controller.connectOutlet('wizardStep4', controller.get('content.services'));
+      controller.connectOutlet('wizardStep4', App.StackService.find());
     },
     },
     back: Em.Router.transitionTo('step3'),
     back: Em.Router.transitionTo('step3'),
 
 

+ 1 - 1
ambari-web/app/routes/main.js

@@ -706,7 +706,7 @@ module.exports = Em.Route.extend({
           var item = router.get('mainServiceItemController.content');
           var item = router.get('mainServiceItemController.content');
           //if service is not existed then route to default service
           //if service is not existed then route to default service
           if (item.get('isLoaded')) {
           if (item.get('isLoaded')) {
-            if (item.get('isConfigurable')) {
+            if (router.get('mainServiceItemController.isConfigurable')) {
               router.get('mainServiceItemController').connectOutlet('mainServiceInfoConfigs', item);
               router.get('mainServiceItemController').connectOutlet('mainServiceInfoConfigs', item);
             }
             }
             else {
             else {

+ 38 - 37
ambari-web/app/templates/main/admin/highAvailability/step2.hbs

@@ -25,53 +25,54 @@
     <form class="form-horizontal" autocomplete="off">
     <form class="form-horizontal" autocomplete="off">
       <!-- View for array controller -->
       <!-- View for array controller -->
       {{#each servicesMasters}}
       {{#each servicesMasters}}
-      <div class="control-group">
-        <label class="control-label">
-          {{#if isCurNameNode}}
-            {{t common.current}}
-          {{/if}}
-          {{#if isAddNameNode}}
-            {{t common.additional}}
-          {{/if}}
-          {{display_name}}:
-        </label>
-        <div class="controls">
-          {{#if view.shouldUseInputs}}
-            {{view App.InputHostView
-            componentBinding="this"
-            disabledBinding="isInstalled" }}
-          {{else}}
-            {{view App.SelectHostView
-            componentBinding="this"
-            disabledBinding="isInstalled"
-            optionValuePath="content.host_name"
-            optionLabelPath="content.host_info" }}
-          {{/if}}
-          {{#if showAddControl}}
-          {{view App.AddControlView componentNameBinding="component_name"}}
-          {{/if}}
-          {{#if showRemoveControl}}
-          {{view App.RemoveControlView componentNameBinding="component_name" zIdBinding="zId"}}
-          {{/if}}
+        <div class="control-group">
+          <label class="control-label">
+            {{#if isCurNameNode}}
+              {{t common.current}}
+            {{/if}}
+            {{#if isAddNameNode}}
+              {{t common.additional}}
+            {{/if}}
+            {{display_name}}:
+          </label>
+
+          <div class="controls">
+            {{#if view.shouldUseInputs}}
+              {{view App.InputHostView
+              componentBinding="this"
+              disabledBinding="isInstalled" }}
+            {{else}}
+              {{view App.SelectHostView
+              componentBinding="this"
+              disabledBinding="isInstalled"
+              optionValuePath="content.host_name"
+              optionLabelPath="content.host_info" }}
+            {{/if}}
+            {{#if showAddControl}}
+              {{view App.AddControlView componentNameBinding="component_name"}}
+            {{/if}}
+            {{#if showRemoveControl}}
+              {{view App.RemoveControlView componentNameBinding="component_name" serviceComponentIddBinding="serviceComponentId"}}
+            {{/if}}
+          </div>
         </div>
         </div>
-      </div>
       {{/each}}
       {{/each}}
     </form>
     </form>
   </div>
   </div>
 
 
   <div class="host-assignments span5">
   <div class="host-assignments span5">
     {{#each masterHostMapping}}
     {{#each masterHostMapping}}
-    <div class="mapping-box round-corners well">
-      <div class="hostString"><span>{{hostInfo}}</span></div>
-      {{#each masterServices}}
-      <span {{bindAttr class="isInstalled:assignedService:newService :round-corners"}}>{{display_name}}</span>
-      {{/each}}
-    </div>
+      <div class="mapping-box round-corners well">
+        <div class="hostString"><span>{{hostInfo}}</span></div>
+        {{#each masterServices}}
+          <span {{bindAttr class="isInstalled:assignedService:newService :round-corners"}}>{{display_name}}</span>
+        {{/each}}
+      </div>
     {{/each}}
     {{/each}}
 
 
     {{#if remainingHosts}}
     {{#if remainingHosts}}
-    <div class="remaining-hosts round-corners well">
-      <span><strong>{{remainingHosts}}</strong> {{t installer.step5.attention}}</span></div>
+      <div class="remaining-hosts round-corners well">
+        <span><strong>{{remainingHosts}}</strong> {{t installer.step5.attention}}</span></div>
     {{/if}}
     {{/if}}
   </div>
   </div>
   <div style="clear: both;"></div>
   <div style="clear: both;"></div>

+ 1 - 1
ambari-web/app/templates/main/service/item.hbs

@@ -64,7 +64,7 @@
         <!-- dropdown menu links -->
         <!-- dropdown menu links -->
 
 
         <!-- Start/Stop service actions -->
         <!-- Start/Stop service actions -->
-        {{#unless controller.content.isClientsOnly}}
+        {{#unless controller.isClientsOnlyService}}
           <li {{bindAttr class="controller.isStartDisabled:disabled"}}>
           <li {{bindAttr class="controller.isStartDisabled:disabled"}}>
             <a href="javascript:void(null)" {{bindAttr class="controller.isStartDisabled:disabled" }}
             <a href="javascript:void(null)" {{bindAttr class="controller.isStartDisabled:disabled" }}
               {{action "startService" target="controller"}}>
               {{action "startService" target="controller"}}>

+ 7 - 7
ambari-web/app/templates/wizard/step4.hbs

@@ -37,16 +37,16 @@
     </tr>
     </tr>
     </thead>
     </thead>
     <tbody>
     <tbody>
-      {{#each controller}}
-        {{#unless isHidden}}
+    {{#each controller}}
+      {{#unless isHiddenOnSelectServicePage}}
         <tr {{bindAttr class="isSelected:success:"}}>
         <tr {{bindAttr class="isSelected:success:"}}>
-          <td><label class="checkbox">{{view Ember.Checkbox disabledBinding="isDisabled" checkedBinding="isSelected"}}{{displayName}}</label>
+          <td><label class="checkbox">{{view Ember.Checkbox disabledBinding="isInstalled" checkedBinding="isSelected"}}{{displayNameOnSelectServicePage}}</label>
           </td>
           </td>
-          <td>{{version}}</td>
-          <td>{{{description}}}</td>
+          <td>{{serviceVersion}}</td>
+          <td>{{{comments}}}</td>
         </tr>
         </tr>
-        {{/unless}}
-      {{/each}}
+      {{/unless}}
+    {{/each}}
     </tbody>
     </tbody>
   </table>
   </table>
 
 

+ 22 - 27
ambari-web/app/templates/wizard/step5.hbs

@@ -19,9 +19,8 @@
 <h2>{{title}}</h2>
 <h2>{{title}}</h2>
 <div class="alert alert-info">
 <div class="alert alert-info">
   {{t installer.step5.body}}
   {{t installer.step5.body}}
-  {{#if hasHiveServer}}
-    <br>
-    {{t installer.step5.body.hive}}
+  {{#if view.coHostedComponentText}}
+    {{{view.coHostedComponentText}}}
   {{/if}}
   {{/if}}
 </div>
 </div>
 {{#if controller.isLoaded}}
 {{#if controller.isLoaded}}
@@ -47,38 +46,34 @@
                   <div class="span4">
                   <div class="span4">
                     <div class="control-group">
                     <div class="control-group">
                       <label class="pts pull-right">
                       <label class="pts pull-right">
-                        {{#if controller.isReassignHive}}
-                          {{t installer.step5.hiveGroup}}
-                        {{else}}
-                          {{display_name}}:
-                        {{/if}}
+                        {{display_name}}:
                       </label>
                       </label>
                     </div>
                     </div>
                   </div>
                   </div>
                   <div class="span8">
                   <div class="span8">
-                    {{#if isHiveCoHost}}
+                    {{#if isServiceCoHost}}
                       <div class="hostName">
                       <div class="hostName">
                         {{selectedHost}}<i class="icon-asterisks">&#10037;</i>
                         {{selectedHost}}<i class="icon-asterisks">&#10037;</i>
                       </div>
                       </div>
                     {{else}}
                     {{else}}
-                    <div class="control-group">
-                      {{#if view.shouldUseInputs}}
-                        {{view App.InputHostView
-                        componentBinding="this"
-                        disabledBinding="isInstalled" }}
-                      {{else}}
-                        {{view App.SelectHostView
-                        componentBinding="this"
-                        disabledBinding="isInstalled"
-                        optionValuePath="content.host_name"
-                        optionLabelPath="content.host_info" }}
-                      {{/if}}
-                      {{#if showAddControl}}
-                        {{view App.AddControlView componentNameBinding="component_name"}}
-                      {{/if}}
-                      {{#if showRemoveControl}}
-                        {{view App.RemoveControlView componentNameBinding="component_name" zIdBinding="zId"}}
-                      {{/if}}
+                      <div class="control-group">
+                        {{#if view.shouldUseInputs}}
+                          {{view App.InputHostView
+                          componentBinding="this"
+                          disabledBinding="isInstalled" }}
+                        {{else}}
+                          {{view App.SelectHostView
+                          componentBinding="this"
+                          disabledBinding="isInstalled"
+                          optionValuePath="content.host_name"
+                          optionLabelPath="content.host_info" }}
+                        {{/if}}
+                        {{#if showAddControl}}
+                          {{view App.AddControlView componentNameBinding="component_name"}}
+                        {{/if}}
+                        {{#if showRemoveControl}}
+                          {{view App.RemoveControlView componentNameBinding="component_name" serviceComponentIdBinding="serviceComponentId"}}
+                        {{/if}}
                       </div>
                       </div>
                     {{/if}}
                     {{/if}}
                   </div>
                   </div>

+ 32 - 29
ambari-web/app/templates/wizard/step6.hbs

@@ -18,6 +18,7 @@
 
 
 <div id="step6">
 <div id="step6">
   <h2>{{view.title}}</h2>
   <h2>{{view.title}}</h2>
+
   <div class="alert alert-info">{{{view.label}}}</div>
   <div class="alert alert-info">{{{view.label}}}</div>
   {{#if errorMessage}}
   {{#if errorMessage}}
     <div class="alert alert-error">{{errorMessage}}</div>
     <div class="alert alert-error">{{errorMessage}}</div>
@@ -26,39 +27,41 @@
   <div class="pre-scrollable">
   <div class="pre-scrollable">
     <table class="table table-striped" id="component_assign_table">
     <table class="table table-striped" id="component_assign_table">
       <thead>
       <thead>
-        <tr>
-          <th>{{t common.host}}</th>
-          {{#each header in controller.headers}}
+      <tr>
+        <th>{{t common.host}}</th>
+        {{#each header in controller.headers}}
 
 
-            <th>
-              <a href="#" {{bindAttr class="header.allChecked:selected:deselected"}}
-                {{action "selectAllNodes" header target="controller"}}>{{t all}}</a>&nbsp;|&nbsp;<a href="#" {{bindAttr class="header.noChecked:selected:deselected"}}
-                {{action "deselectAllNodes" header target="controller"}}>{{t none}}</a>
-            </th>
+          <th>
+            <a href="#" {{bindAttr class="header.allChecked:selected:deselected header.isDisabled:remove-link"}}
+              {{action "selectAllNodes" header target="controller"}}>{{t all}}</a> &nbsp;|&nbsp; <a
+                  href="#" {{bindAttr class="header.noChecked:selected:deselected header.isDisabled:remove-link"}}
+            {{action "deselectAllNodes" header target="controller"}}>{{t none}}</a>
+          </th>
 
 
-          {{/each}}
-        </tr>
+        {{/each}}
+      </tr>
       </thead>
       </thead>
       <tbody>
       <tbody>
-        {{#if view.pageContent}}
-          {{#each host in view.pageContent}}
-            <tr>
-              {{#view App.WizardStep6HostView hostBinding="host" }}
-                <span class="trim_hostname">{{host.hostName}}</span>
-                {{#if host.hasMaster}}
-                  <i class="icon-asterisks">&#10037;</i>
-                {{/if}}
-              {{/view}}
-              {{#each checkbox in host.checkboxes}}
-                <td>
-                  <label class="checkbox">
-                      <input {{bindAttr checked = "checkbox.checked" disabled="checkbox.isInstalled"}} {{action "checkboxClick" checkbox target="view" }} type="checkbox"/>{{checkbox.title}}
-                  </label>
-                </td>
-              {{/each}}
-            </tr>
-          {{/each}}
-        {{/if}}
+      {{#if view.pageContent}}
+        {{#each host in view.pageContent}}
+          <tr>
+            {{#view App.WizardStep6HostView hostBinding="host" }}
+              <span class="trim_hostname">{{host.hostName}}</span>
+              {{#if host.hasMaster}}
+                <i class=icon-asterisks>&#10037;</i>
+              {{/if}}
+            {{/view}}
+            {{#each checkbox in host.checkboxes}}
+              <td>
+                <label class="checkbox">
+                  <input {{bindAttr checked = "checkbox.checked" disabled="checkbox.isInstalled"}} {{action "checkboxClick" checkbox target="view" }}
+                          type="checkbox"/>{{checkbox.title}}
+                </label>
+              </td>
+            {{/each}}
+          </tr>
+        {{/each}}
+      {{/if}}
       </tbody>
       </tbody>
     </table>
     </table>
   </div>
   </div>

+ 1 - 1
ambari-web/app/templates/wizard/step8.hbs

@@ -53,7 +53,7 @@
 
 
     <div>
     <div>
       {{#if controller.services.length}}
       {{#if controller.services.length}}
-        <p><b>{{t menu.item.services}}</b></p>
+        <p><b>{{t menu.item.services}}:</b></p>
         <ul>
         <ul>
           {{#each controller.services}}
           {{#each controller.services}}
             <li>
             <li>

+ 1 - 1
ambari-web/app/utils/ajax/ajax.js

@@ -954,7 +954,7 @@ var urls = {
     }
     }
   },
   },
   'wizard.service_components': {
   'wizard.service_components': {
-    'real': '{stackUrl}/services?fields=StackServices/comments,StackServices/service_version,serviceComponents/*',
+    'real': '{stackUrl}/services?fields=StackServices/*,serviceComponents/*',
     'mock': '/data/stacks/HDP-2.1/service_components.json',
     'mock': '/data/stacks/HDP-2.1/service_components.json',
     'format': function(data) {
     'format': function(data) {
       return {
       return {

+ 0 - 68
ambari-web/app/utils/component.js

@@ -1,68 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Here will be stored slave functions related to components
- * @type {Object}
- */
-
-var App = require('app');
-module.exports = {
-
-  /**
-   * This needs to be done because mapper functions like App.stackServiceComponentMapper.map(data) does not override
-   * but unions the instances. So on re-navigation if the stack is switched and this function is not called then union of
-   * StackServiceComponent of both the stacks will be mapped to the model.
-   */
-  clearStackModel: function() {
-    if (App.StackServiceComponent.find().get('content').length) {
-      App.StackServiceComponent.find().set('content', []);
-    }
-  },
-
-  /**
-   * Format and load info about components to StackServiceComponent model.
-   *
-   * @method loadStackServiceComponentModel
-   * @param data {object} response from server
-   * @return {object} formatted info about components
-   */
-  loadStackServiceComponentModel: function(data) {
-    this.clearStackModel();
-    var serviceComponents = {items: []};
-    data.items.forEach(function(item){
-      item.serviceComponents.forEach(function(_serviceComponent, indx){
-        var stackServiceComponents =  _serviceComponent.StackServiceComponents;
-        var serviceComponent = {
-          component_name: stackServiceComponents.component_name,
-          service_name: stackServiceComponents.service_name,
-          component_category: stackServiceComponents.component_category,
-          is_master: stackServiceComponents.is_master,
-          is_client: stackServiceComponents.is_client,
-          stack_name: stackServiceComponents.stack_name,
-          stack_version: stackServiceComponents.stack_version,
-          id: indx
-        };
-        serviceComponents.items.pushObject(serviceComponent);
-      }, this);
-    }, this);
-    App.stackServiceComponentMapper.map(serviceComponents);
-    App.handleStackDependedComponents();
-    return serviceComponents;
-  }
-};

+ 146 - 102
ambari-web/app/utils/config.js

@@ -40,7 +40,7 @@ App.config = Em.Object.create({
     "&quot;": '"',
     "&quot;": '"',
     "&apos;": "'"
     "&apos;": "'"
   },
   },
-  
+
   CONFIG_GROUP_NAME_MAX_LENGTH: 18,
   CONFIG_GROUP_NAME_MAX_LENGTH: 18,
 
 
   /**
   /**
@@ -51,8 +51,8 @@ App.config = Em.Object.create({
   /**
   /**
    * Since values end up in XML files (core-sit.xml, etc.), certain
    * Since values end up in XML files (core-sit.xml, etc.), certain
    * XML sensitive characters should be escaped. If not we will have
    * XML sensitive characters should be escaped. If not we will have
-   * an invalid XML document, and services will fail to start. 
-   * 
+   * an invalid XML document, and services will fail to start.
+   *
    * Special characters in XML are defined at
    * Special characters in XML are defined at
    * http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML
    * http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML
    *
    *
@@ -61,7 +61,7 @@ App.config = Em.Object.create({
    * @param toXml {Boolean}
    * @param toXml {Boolean}
    * @return {String}
    * @return {String}
    */
    */
-  escapeXMLCharacters: function(value, toXML) {
+  escapeXMLCharacters: function (value, toXML) {
     var self = this;
     var self = this;
     // To prevent double/triple replacing '&gt;' to '&amp;gt;' to '&amp;amp;gt;', we need
     // To prevent double/triple replacing '&gt;' to '&amp;gt;' to '&amp;amp;gt;', we need
     // to first unescape all XML chars, and then escape them again.
     // to first unescape all XML chars, and then escape them again.
@@ -77,42 +77,87 @@ App.config = Em.Object.create({
     }
     }
   },
   },
 
 
-  preDefinedServiceConfigs: function () {
+  preDefinedGlobalProperties: [],
+
+  setPreDefinedGlobalProperties: function () {
+    var globalProperties = [];
+    if (App.get('isHadoop2Stack')) {
+      globalProperties = require('data/HDP2/global_properties').configProperties;
+    } else {
+      globalProperties = require('data/global_properties').configProperties;
+    }
+    var preDefinedGlobalProperties = globalProperties;
+    var categories = [];
+    var nonServicePages = require('data/service_configs');
+    var services = App.StackService.find().filterProperty('id');
+
+    // Only services that have configTypes associated with it should display service config page
+    // Also Remove HCatalog from this list. HCatalog has global and hive-site related to it but none of them should be exposed under HCatalog Service
+    // HCatalog should be eventually made a part of Hive Service. See AMBARI-6302 description for further details
+    var servicesWithConfigTypes = services.filter(function (service) {
+      var configtypes = service.get('configTypes');
+      return configtypes && !!configtypes.length && service.get('serviceName') != 'HCATALOG';
+    }, this);
+    var serviceTabs = servicesWithConfigTypes.concat(nonServicePages);
+    serviceTabs.forEach(function (stackService) {
+      categories.pushObjects(stackService.get('configCategories'));
+    });
+    var categoryNames = categories.mapProperty('name').uniq();
+    if (!!categoryNames.length) {
+      preDefinedGlobalProperties = globalProperties.filter(function (_globalProperty) {
+        return !_globalProperty.category || (serviceTabs.someProperty('serviceName', _globalProperty.serviceName) &&
+          categoryNames.contains(_globalProperty.category));
+      });
+    }
+    this.set('preDefinedGlobalProperties', preDefinedGlobalProperties);
+  },
+
+  preDefinedServiceConfigs: [],
+
+  setPreDefinedServiceConfigs: function () {
     var configs = this.get('preDefinedGlobalProperties');
     var configs = this.get('preDefinedGlobalProperties');
     var services = [];
     var services = [];
-    $.extend(true, [], require('data/service_configs')).forEach(function (service) {
-      service.configs = configs.filterProperty('serviceName', service.serviceName);
+    var nonServiceTab = require('data/service_configs');
+    var stackServices = App.StackService.find().filterProperty('id');
+    // Only include services that has configTypes related to them for service configuration page
+    // Also Remove HCatalog from this list. HCatalog has global and hive-site related to it but none of them should be exposed under HCatalog Service
+    // HCatalog should be eventually made a part of Hive Service. See AMBARI-6302 description for further details
+    var servicesWithConfigTypes = stackServices.filter(function (service) {
+      var configtypes = service.get('configTypes');
+      return configtypes && !!configtypes.length && service.get('serviceName') != 'HCATALOG';
+    }, this);
+
+    var allTabs = servicesWithConfigTypes.concat(nonServiceTab);
+    allTabs.forEach(function (service) {
+      var serviceConfigs = configs.filterProperty('serviceName', service.get('serviceName'));
+      serviceConfigs = serviceConfigs.filter(function (_globalProperty) {
+        !_globalProperty.category || service.get('configCategories').someProperty('name', _globalProperty.category);
+      });
+      service.set('configs', serviceConfigs);
       services.push(service);
       services.push(service);
     });
     });
-    return services;
-  }.property('preDefinedGlobalProperties'),
+    this.set('preDefinedServiceConfigs', services);
+  },
 
 
   configMapping: function () {
   configMapping: function () {
     if (App.get('isHadoop2Stack')) {
     if (App.get('isHadoop2Stack')) {
-      return $.extend(true, [], require('data/HDP2/config_mapping'));
-    }
-    return $.extend(true, [], require('data/config_mapping'));
-  }.property('App.isHadoop2Stack'),
-
-  preDefinedGlobalProperties: function () {
-    if (App.get('isHadoop2Stack')) {
-      return $.extend(true, [], require('data/HDP2/global_properties').configProperties);
+      return require('data/HDP2/config_mapping');
     }
     }
-    return $.extend(true, [], require('data/global_properties').configProperties);
+    return require('data/config_mapping');
   }.property('App.isHadoop2Stack'),
   }.property('App.isHadoop2Stack'),
 
 
   preDefinedSiteProperties: function () {
   preDefinedSiteProperties: function () {
     if (App.get('isHadoop2Stack')) {
     if (App.get('isHadoop2Stack')) {
-      return $.extend(true, [], require('data/HDP2/site_properties').configProperties);
+      return require('data/HDP2/site_properties').configProperties;
     }
     }
-    return $.extend(true, [], require('data/site_properties').configProperties);
+    return require('data/site_properties').configProperties;
   }.property('App.isHadoop2Stack'),
   }.property('App.isHadoop2Stack'),
 
 
   preDefinedCustomConfigs: function () {
   preDefinedCustomConfigs: function () {
     if (App.get('isHadoop2Stack')) {
     if (App.get('isHadoop2Stack')) {
-      return $.extend(true, [], require('data/HDP2/custom_configs'));
+      return require('data/HDP2/custom_configs');
     }
     }
-    return $.extend(true, [], require('data/custom_configs'));
+    return require('data/custom_configs');
   }.property('App.isHadoop2Stack'),
   }.property('App.isHadoop2Stack'),
 
 
   //categories which contain custom configs
   //categories which contain custom configs
@@ -165,7 +210,7 @@ App.config = Em.Object.create({
   /**
   /**
    * Array of global "service/desired_tag/actual_tag" strings which
    * Array of global "service/desired_tag/actual_tag" strings which
    * indicate different configurations. We cache these so that
    * indicate different configurations. We cache these so that
-   * we dont have to recalculate if two tags are difference.
+   * we don't have to recalculate if two tags are difference.
    */
    */
   differentGlobalTagsCache: [],
   differentGlobalTagsCache: [],
 
 
@@ -173,12 +218,13 @@ App.config = Em.Object.create({
     var category = null;
     var category = null;
     var serviceConfigMetaData = this.get('preDefinedServiceConfigs').findProperty('serviceName', config.serviceName);
     var serviceConfigMetaData = this.get('preDefinedServiceConfigs').findProperty('serviceName', config.serviceName);
     if (serviceConfigMetaData) {
     if (serviceConfigMetaData) {
-      serviceConfigMetaData.configCategories.forEach(function (_category) {
+      var configCategories = serviceConfigMetaData.get('configCategories');
+      configCategories.forEach(function (_category) {
         if (_category.siteFileNames && Array.isArray(_category.siteFileNames) && _category.siteFileNames.contains(config.filename)) {
         if (_category.siteFileNames && Array.isArray(_category.siteFileNames) && _category.siteFileNames.contains(config.filename)) {
           category = _category;
           category = _category;
         }
         }
       });
       });
-      category = (category == null) ? serviceConfigMetaData.configCategories.findProperty('siteFileName', config.filename) : category;
+      category = (category == null) ? configCategories.findProperty('siteFileName', config.filename) : category;
     }
     }
     return category;
     return category;
   },
   },
@@ -198,7 +244,7 @@ App.config = Em.Object.create({
   },
   },
   /**
   /**
    * calculate config properties:
    * calculate config properties:
-   * category, filename, isUserProperty, description   
+   * category, filename, isUserProperty, description
    * @param config
    * @param config
    * @param isAdvanced
    * @param isAdvanced
    * @param advancedConfigs
    * @param advancedConfigs
@@ -212,7 +258,7 @@ App.config = Em.Object.create({
       }
       }
     } else {
     } else {
       var advancedProperty = null;
       var advancedProperty = null;
-      if( isAdvanced ){
+      if (isAdvanced) {
         advancedProperty = advancedConfigs.findProperty('name', config.name);
         advancedProperty = advancedConfigs.findProperty('name', config.name);
       }
       }
 
 
@@ -263,22 +309,22 @@ App.config = Em.Object.create({
 
 
       properties = (properties.length) ? properties.objectAt(0).properties : {};
       properties = (properties.length) ? properties.objectAt(0).properties : {};
       for (var index in properties) {
       for (var index in properties) {
-        var configsPropertyDef =  null;
+        var configsPropertyDef = null;
         var preDefinedConfig = [];
         var preDefinedConfig = [];
         if (_tag.siteName === 'global') {
         if (_tag.siteName === 'global') {
-        // Unlike other site where one site maps to ones service, global site contains configurations for multiple services
-        // So Global Configuration should not be filtered out with serviceName.
+          // Unlike other site where one site maps to ones service, global site contains configurations for multiple services
+          // So Global Configuration should not be filtered out with serviceName.
           preDefinedConfig = preDefinedConfigs.filterProperty('name', index);
           preDefinedConfig = preDefinedConfigs.filterProperty('name', index);
-          preDefinedConfig.forEach(function(_preDefinedConfig){
+          preDefinedConfig.forEach(function (_preDefinedConfig) {
             var isServiceInstalled = selectedServiceNames.contains(_preDefinedConfig.serviceName);
             var isServiceInstalled = selectedServiceNames.contains(_preDefinedConfig.serviceName);
-              if ( isServiceInstalled || _preDefinedConfig.serviceName === 'MISC') {
-                configsPropertyDef = _preDefinedConfig;
-              }
-          },this);
+            if (isServiceInstalled || _preDefinedConfig.serviceName === 'MISC') {
+              configsPropertyDef = _preDefinedConfig;
+            }
+          }, this);
         } else {
         } else {
-          configsPropertyDef = preDefinedConfigs.filterProperty('name',index).findProperty('filename',filename);
+          configsPropertyDef = preDefinedConfigs.filterProperty('name', index).findProperty('filename', filename);
           if (!configsPropertyDef) {
           if (!configsPropertyDef) {
-            configsPropertyDef = preDefinedConfigs.filterProperty('name',index).findProperty('serviceName', serviceName);
+            configsPropertyDef = preDefinedConfigs.filterProperty('name', index).findProperty('serviceName', serviceName);
           }
           }
         }
         }
 
 
@@ -298,7 +344,7 @@ App.config = Em.Object.create({
         if (configsPropertyDef) {
         if (configsPropertyDef) {
           this.setServiceConfigUiAttributes(serviceConfigObj, configsPropertyDef);
           this.setServiceConfigUiAttributes(serviceConfigObj, configsPropertyDef);
         }
         }
-        
+
         if (_tag.siteName === 'global') {
         if (_tag.siteName === 'global') {
           if (configsPropertyDef) {
           if (configsPropertyDef) {
             if (configsPropertyDef.isRequiredByAgent === false) {
             if (configsPropertyDef.isRequiredByAgent === false) {
@@ -321,22 +367,22 @@ App.config = Em.Object.create({
 
 
           serviceConfigObj.displayName = configsPropertyDef ? configsPropertyDef.displayName : index;
           serviceConfigObj.displayName = configsPropertyDef ? configsPropertyDef.displayName : index;
           this.calculateConfigProperties(serviceConfigObj, isAdvanced, advancedConfigs);
           this.calculateConfigProperties(serviceConfigObj, isAdvanced, advancedConfigs);
-          
-          if(serviceConfigObj.get('displayType') == 'directories'
+
+          if (serviceConfigObj.get('displayType') == 'directories'
             && (serviceConfigObj.get('category') == 'DataNode'
             && (serviceConfigObj.get('category') == 'DataNode'
             || serviceConfigObj.get('category') == 'NameNode')) {
             || serviceConfigObj.get('category') == 'NameNode')) {
             var dirs = serviceConfigObj.get('value').split(',').sort();
             var dirs = serviceConfigObj.get('value').split(',').sort();
             serviceConfigObj.set('value', dirs.join(','));
             serviceConfigObj.set('value', dirs.join(','));
             serviceConfigObj.set('defaultValue', dirs.join(','));
             serviceConfigObj.set('defaultValue', dirs.join(','));
           }
           }
-          
-          if(serviceConfigObj.get('displayType') == 'directory'
+
+          if (serviceConfigObj.get('displayType') == 'directory'
             && serviceConfigObj.get('category') == 'SNameNode') {
             && serviceConfigObj.get('category') == 'SNameNode') {
             var dirs = serviceConfigObj.get('value').split(',').sort();
             var dirs = serviceConfigObj.get('value').split(',').sort();
             serviceConfigObj.set('value', dirs[0]);
             serviceConfigObj.set('value', dirs[0]);
             serviceConfigObj.set('defaultValue', dirs[0]);
             serviceConfigObj.set('defaultValue', dirs[0]);
           }
           }
-          
+
           if (serviceConfigObj.get('displayType') == 'masterHosts') {
           if (serviceConfigObj.get('displayType') == 'masterHosts') {
             if (typeof(serviceConfigObj.get('value')) == 'string') {
             if (typeof(serviceConfigObj.get('value')) == 'string') {
               var value = serviceConfigObj.get('value').replace(/\[|]|'|&apos;/g, "").split(',');
               var value = serviceConfigObj.get('value').replace(/\[|]|'|&apos;/g, "").split(',');
@@ -403,8 +449,8 @@ App.config = Em.Object.create({
       if (_site.length == 1) {
       if (_site.length == 1) {
         siteStart.push(_site[0]);
         siteStart.push(_site[0]);
         siteConfigs = siteConfigs.without(_site[0]);
         siteConfigs = siteConfigs.without(_site[0]);
-      } else if (_site.length >1) {
-        _site.forEach(function(site){
+      } else if (_site.length > 1) {
+        _site.forEach(function (site) {
           siteStart.push(site);
           siteStart.push(site);
           siteConfigs = siteConfigs.without(site);
           siteConfigs = siteConfigs.without(site);
         }, this);
         }, this);
@@ -427,7 +473,7 @@ App.config = Em.Object.create({
    */
    */
   mergePreDefinedWithStored: function (storedConfigs, advancedConfigs, selectedServiceNames) {
   mergePreDefinedWithStored: function (storedConfigs, advancedConfigs, selectedServiceNames) {
     var mergedConfigs = [];
     var mergedConfigs = [];
-    var preDefinedConfigs = $.extend(true, [], this.get('preDefinedGlobalProperties').concat(this.get('preDefinedSiteProperties')));
+    var preDefinedConfigs = this.get('preDefinedGlobalProperties').concat(this.get('preDefinedSiteProperties'));
 
 
     storedConfigs = (storedConfigs) ? storedConfigs : [];
     storedConfigs = (storedConfigs) ? storedConfigs : [];
 
 
@@ -449,7 +495,7 @@ App.config = Em.Object.create({
       if (storedCfgs.length <= 1 && preDefinedCfgs.length <= 1) {
       if (storedCfgs.length <= 1 && preDefinedCfgs.length <= 1) {
         var stored = storedCfgs[0];
         var stored = storedCfgs[0];
         var preDefined = preDefinedCfgs[0];
         var preDefined = preDefinedCfgs[0];
-        
+
         if (preDefined && stored) {
         if (preDefined && stored) {
           configData = preDefined;
           configData = preDefined;
           configData.value = stored.value;
           configData.value = stored.value;
@@ -462,25 +508,23 @@ App.config = Em.Object.create({
           configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
           configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
           configData.showLabel = stored.showLabel !== false;
           configData.showLabel = stored.showLabel !== false;
         }
         }
-        else
-          if (!preDefined && stored) {
-            configData = this.addUserProperty(stored, isAdvanced, advancedConfigs);
+        else if (!preDefined && stored) {
+          configData = this.addUserProperty(stored, isAdvanced, advancedConfigs);
+        }
+        else if (preDefined && !stored) {
+          configData = preDefined;
+          configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
+          if (isAdvanced) {
+            var advanced = advancedConfigs.findProperty('name', configData.name);
+            this.setPropertyFromStack(configData, advanced);
           }
           }
-          else
-            if (preDefined && !stored) {
-              configData = preDefined;
-              configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
-              if (isAdvanced) {
-                var advanced = advancedConfigs.findProperty('name', configData.name);
-                this.setPropertyFromStack(configData,advanced);
-              }
-            }
-        
+        }
+
         if (configData.displayType === 'checkbox') {
         if (configData.displayType === 'checkbox') {
           configData.value = configData.value === 'true'; // convert {String} value to {Boolean}
           configData.value = configData.value === 'true'; // convert {String} value to {Boolean}
           configData.defaultValue = configData.value;
           configData.defaultValue = configData.value;
         }
         }
-      
+
         mergedConfigs.push(configData);
         mergedConfigs.push(configData);
       } else {
       } else {
         preDefinedCfgs.forEach(function (cfg) {
         preDefinedCfgs.forEach(function (cfg) {
@@ -494,9 +538,9 @@ App.config = Em.Object.create({
             configData.filename = storedCfg.filename;
             configData.filename = storedCfg.filename;
             configData.description = storedCfg.description;
             configData.description = storedCfg.description;
             configData.description = storedCfg.showLabel !== false;
             configData.description = storedCfg.showLabel !== false;
-          } else if (isAdvanced){
-              advanced = advancedConfigs.filterProperty('filename', configData.filename).findProperty('name', configData.name);
-              this.setPropertyFromStack(configData,advanced);
+          } else if (isAdvanced) {
+            advanced = advancedConfigs.filterProperty('filename', configData.filename).findProperty('name', configData.name);
+            this.setPropertyFromStack(configData, advanced);
           }
           }
           mergedConfigs.push(configData);
           mergedConfigs.push(configData);
         }, this);
         }, this);
@@ -510,7 +554,7 @@ App.config = Em.Object.create({
    * @param configData {Object} Configs that will be binded to the view on step-7 of installer wizard
    * @param configData {Object} Configs that will be binded to the view on step-7 of installer wizard
    * @param advanced {Object} Config property loaded from Server side stack definition
    * @param advanced {Object} Config property loaded from Server side stack definition
    */
    */
-  setPropertyFromStack: function(configData,advanced) {
+  setPropertyFromStack: function (configData, advanced) {
 
 
     // Password fields should be made blank by default in installer wizard
     // Password fields should be made blank by default in installer wizard
     // irrespective of whatever value is sent from stack definition.
     // irrespective of whatever value is sent from stack definition.
@@ -601,17 +645,18 @@ App.config = Em.Object.create({
     var services = [];
     var services = [];
 
 
     this.get('preDefinedServiceConfigs').forEach(function (serviceConfig) {
     this.get('preDefinedServiceConfigs').forEach(function (serviceConfig) {
-      if (allSelectedServiceNames.contains(serviceConfig.serviceName) || serviceConfig.serviceName === 'MISC') {
-        console.log('pushing ' + serviceConfig.serviceName, serviceConfig);
-        if (!installedServiceNames.contains(serviceConfig.serviceName) || serviceConfig.serviceName === 'MISC') {
-          serviceConfig.showConfig = true;
+      var serviceName = serviceConfig.get('serviceName');
+      if (allSelectedServiceNames.contains(serviceName) || serviceName === 'MISC') {
+        console.log('pushing ' + serviceName, serviceConfig);
+        if (!installedServiceNames.contains(serviceName) || serviceName === 'MISC') {
+          serviceConfig.set('showConfig', true);
         }
         }
         services.push(serviceConfig);
         services.push(serviceConfig);
       }
       }
     });
     });
     services.forEach(function (service) {
     services.forEach(function (service) {
       var configsByService = [];
       var configsByService = [];
-      var serviceConfigs = configs.filterProperty('serviceName', service.serviceName);
+      var serviceConfigs = configs.filterProperty('serviceName', service.get('serviceName'));
       serviceConfigs.forEach(function (_config) {
       serviceConfigs.forEach(function (_config) {
         _config.isOverridable = (_config.isOverridable === undefined) ? true : _config.isOverridable;
         _config.isOverridable = (_config.isOverridable === undefined) ? true : _config.isOverridable;
         var serviceConfigProperty = App.ServiceConfigProperty.create(_config);
         var serviceConfigProperty = App.ServiceConfigProperty.create(_config);
@@ -623,13 +668,13 @@ App.config = Em.Object.create({
         serviceConfigProperty.validate();
         serviceConfigProperty.validate();
         configsByService.pushObject(serviceConfigProperty);
         configsByService.pushObject(serviceConfigProperty);
       }, this);
       }, this);
-      var serviceConfig = this.createServiceConfig(service.serviceName);
-      serviceConfig.set('showConfig', service.showConfig);
+      var serviceConfig = this.createServiceConfig(service.get('serviceName'));
+      serviceConfig.set('showConfig', service.get('showConfig'));
 
 
       // Use calculated default values for some configs
       // Use calculated default values for some configs
       var recommendedDefaults = {};
       var recommendedDefaults = {};
-      if (!storedConfigs && service.defaultsProviders) {
-        service.defaultsProviders.forEach(function (defaultsProvider) {
+      if (!storedConfigs && service.get('defaultsProviders')) {
+        service.get('defaultsProviders').forEach(function (defaultsProvider) {
           var defaults = defaultsProvider.getDefaults(localDB);
           var defaults = defaultsProvider.getDefaults(localDB);
           for (var name in defaults) {
           for (var name in defaults) {
             var config = configsByService.findProperty('name', name);
             var config = configsByService.findProperty('name', name);
@@ -646,13 +691,13 @@ App.config = Em.Object.create({
           }
           }
         });
         });
       }
       }
-      if (service.configsValidator) {
-        service.configsValidator.set('recommendedDefaults', recommendedDefaults);
-        var validators = service.configsValidator.get('configValidators');
+      if (service.get('configsValidator')) {
+        service.get('configsValidator').set('recommendedDefaults', recommendedDefaults);
+        var validators = service.get('configsValidator').get('configValidators');
         for (var validatorName in validators) {
         for (var validatorName in validators) {
           var c = configsByService.findProperty('name', validatorName);
           var c = configsByService.findProperty('name', validatorName);
           if (c) {
           if (c) {
-            c.set('serviceValidator', service.configsValidator);
+            c.set('serviceValidator', service.get('configsValidator'));
           }
           }
         }
         }
       }
       }
@@ -713,10 +758,9 @@ App.config = Em.Object.create({
   createServiceConfig: function (serviceName) {
   createServiceConfig: function (serviceName) {
     var preDefinedServiceConfig = App.config.get('preDefinedServiceConfigs').findProperty('serviceName', serviceName);
     var preDefinedServiceConfig = App.config.get('preDefinedServiceConfigs').findProperty('serviceName', serviceName);
     var serviceConfig = App.ServiceConfig.create({
     var serviceConfig = App.ServiceConfig.create({
-      filename: preDefinedServiceConfig.filename,
-      serviceName: preDefinedServiceConfig.serviceName,
-      displayName: preDefinedServiceConfig.displayName,
-      configCategories: preDefinedServiceConfig.configCategories,
+      serviceName: preDefinedServiceConfig.get('serviceName'),
+      displayName: preDefinedServiceConfig.get('displayName'),
+      configCategories: preDefinedServiceConfig.get('configCategories'),
       configs: [],
       configs: [],
       configGroups: []
       configGroups: []
     });
     });
@@ -801,9 +845,9 @@ App.config = Em.Object.create({
          * Properties from mapred-queue-acls.xml are ignored unless App.supports.capacitySchedulerUi is true
          * Properties from mapred-queue-acls.xml are ignored unless App.supports.capacitySchedulerUi is true
          * Properties from capacity-scheduler.xml are ignored unless HDP stack version is 2.x or
          * Properties from capacity-scheduler.xml are ignored unless HDP stack version is 2.x or
          * HDP stack version is 1.x and App.supports.capacitySchedulerUi is true.
          * HDP stack version is 1.x and App.supports.capacitySchedulerUi is true.
-          */
+         */
         if ((fileName !== 'mapred-queue-acls.xml' || App.supports.capacitySchedulerUi) &&
         if ((fileName !== 'mapred-queue-acls.xml' || App.supports.capacitySchedulerUi) &&
-            (fileName !== 'capacity-scheduler.xml' || isHDP2 || App.supports.capacitySchedulerUi)) {
+          (fileName !== 'capacity-scheduler.xml' || isHDP2 || App.supports.capacitySchedulerUi)) {
           properties.push({
           properties.push({
             serviceName: serviceName,
             serviceName: serviceName,
             name: item.property_name,
             name: item.property_name,
@@ -890,7 +934,7 @@ App.config = Em.Object.create({
             serviceConfig.overrides = [];
             serviceConfig.overrides = [];
           }
           }
           if (!serviceConfig.overrides) {
           if (!serviceConfig.overrides) {
-           serviceConfig.set('overrides', []);
+            serviceConfig.set('overrides', []);
           }
           }
           console.log("loadServiceConfigGroupOverridesSuccess(): [" + group + "] OVERRODE(" + serviceConfig.name + "): " + serviceConfig.value + " -> " + hostOverrideValue);
           console.log("loadServiceConfigGroupOverridesSuccess(): [" + group + "] OVERRODE(" + serviceConfig.name + "): " + serviceConfig.value + " -> " + hostOverrideValue);
           serviceConfig.overrides.push({value: hostOverrideValue, group: group});
           serviceConfig.overrides.push({value: hostOverrideValue, group: group});
@@ -1126,7 +1170,7 @@ App.config = Em.Object.create({
       configCategories.removeObject(snCategory);
       configCategories.removeObject(snCategory);
     }
     }
   },
   },
-  
+
   /**
   /**
    * Launches a dialog where an existing config-group can be selected, or a new
    * Launches a dialog where an existing config-group can be selected, or a new
    * one can be created. This is different than the config-group management
    * one can be created. This is different than the config-group management
@@ -1140,7 +1184,7 @@ App.config = Em.Object.create({
    *  is closed, cancelled or OK is pressed.
    *  is closed, cancelled or OK is pressed.
    */
    */
 
 
-  saveGroupConfirmationPopup: function(groupName) {
+  saveGroupConfirmationPopup: function (groupName) {
     App.ModalPopup.show({
     App.ModalPopup.show({
       header: Em.I18n.t('config.group.save.confirmation.header'),
       header: Em.I18n.t('config.group.save.confirmation.header'),
       secondary: Em.I18n.t('config.group.save.confirmation.manage.button'),
       secondary: Em.I18n.t('config.group.save.confirmation.manage.button'),
@@ -1148,7 +1192,7 @@ App.config = Em.Object.create({
       bodyClass: Ember.View.extend({
       bodyClass: Ember.View.extend({
         templateName: require('templates/common/configs/saveConfigGroup')
         templateName: require('templates/common/configs/saveConfigGroup')
       }),
       }),
-      onSecondary: function() {
+      onSecondary: function () {
         App.router.get('mainServiceInfoConfigsController').manageConfigurationGroups();
         App.router.get('mainServiceInfoConfigsController').manageConfigurationGroups();
         this.hide();
         this.hide();
       }
       }
@@ -1177,7 +1221,7 @@ App.config = Em.Object.create({
     });
     });
   },
   },
 
 
-  launchConfigGroupSelectionCreationDialog : function(serviceId, configGroups, configProperty, callback, isInstaller) {
+  launchConfigGroupSelectionCreationDialog: function (serviceId, configGroups, configProperty, callback, isInstaller) {
     var self = this;
     var self = this;
     var availableConfigGroups = configGroups.slice();
     var availableConfigGroups = configGroups.slice();
     // delete Config Groups, that already have selected property overridden
     // delete Config Groups, that already have selected property overridden
@@ -1193,7 +1237,7 @@ App.config = Em.Object.create({
     }, this);
     }, this);
     availableConfigGroups = result;
     availableConfigGroups = result;
     var selectedConfigGroup = availableConfigGroups && availableConfigGroups.length > 0 ?
     var selectedConfigGroup = availableConfigGroups && availableConfigGroups.length > 0 ?
-        availableConfigGroups[0] : null;
+      availableConfigGroups[0] : null;
     var serviceName = App.Service.DisplayNames[serviceId];
     var serviceName = App.Service.DisplayNames[serviceId];
     App.ModalPopup.show({
     App.ModalPopup.show({
       classNames: [ 'sixty-percent-width-modal' ],
       classNames: [ 'sixty-percent-width-modal' ],
@@ -1206,10 +1250,10 @@ App.config = Em.Object.create({
       warningMessage: '&nbsp;',
       warningMessage: '&nbsp;',
       isWarning: false,
       isWarning: false,
       optionSelectConfigGroup: true,
       optionSelectConfigGroup: true,
-      optionCreateConfigGroup: function(){
+      optionCreateConfigGroup: function () {
         return !this.get('optionSelectConfigGroup');
         return !this.get('optionSelectConfigGroup');
       }.property('optionSelectConfigGroup'),
       }.property('optionSelectConfigGroup'),
-      hasExistedGroups: function() {
+      hasExistedGroups: function () {
         return !!this.get('availableConfigGroups').length;
         return !!this.get('availableConfigGroups').length;
       }.property('availableConfigGroups'),
       }.property('availableConfigGroups'),
       availableConfigGroups: availableConfigGroups,
       availableConfigGroups: availableConfigGroups,
@@ -1401,7 +1445,7 @@ App.config = Em.Object.create({
    * PUTs the new configuration-group on the server.
    * PUTs the new configuration-group on the server.
    * Changes possible here are the name, description and
    * Changes possible here are the name, description and
    * host memberships of the configuration-group.
    * host memberships of the configuration-group.
-   * 
+   *
    * @param {App.ConfigGroup} configGroup Configuration group to update
    * @param {App.ConfigGroup} configGroup Configuration group to update
    * @param {Function} successCallback
    * @param {Function} successCallback
    * @param {Function} errorCallback
    * @param {Function} errorCallback
@@ -1414,20 +1458,20 @@ App.config = Em.Object.create({
         tag: configGroup.get('service.id'),
         tag: configGroup.get('service.id'),
         hosts: [],
         hosts: [],
         desired_configs: []
         desired_configs: []
-      }  
+      }
     };
     };
-    configGroup.get('hosts').forEach(function(h){
+    configGroup.get('hosts').forEach(function (h) {
       putConfigGroup.ConfigGroup.hosts.push({
       putConfigGroup.ConfigGroup.hosts.push({
         host_name: h
         host_name: h
       });
       });
     });
     });
-    configGroup.get('configSiteTags').forEach(function(cst){
+    configGroup.get('configSiteTags').forEach(function (cst) {
       putConfigGroup.ConfigGroup.desired_configs.push({
       putConfigGroup.ConfigGroup.desired_configs.push({
         type: cst.get('site'),
         type: cst.get('site'),
         tag: cst.get('tag')
         tag: cst.get('tag')
       });
       });
     });
     });
-    
+
     var sendData = {
     var sendData = {
       name: 'config_groups.update',
       name: 'config_groups.update',
       data: {
       data: {
@@ -1437,12 +1481,12 @@ App.config = Em.Object.create({
       success: 'successFunction',
       success: 'successFunction',
       error: 'errorFunction',
       error: 'errorFunction',
       successFunction: function () {
       successFunction: function () {
-        if(successCallback) {
+        if (successCallback) {
           successCallback();
           successCallback();
         }
         }
       },
       },
       errorFunction: function (xhr, text, errorThrown) {
       errorFunction: function (xhr, text, errorThrown) {
-        if(errorCallback) {
+        if (errorCallback) {
           errorCallback(xhr, text, errorThrown);
           errorCallback(xhr, text, errorThrown);
         }
         }
       }
       }
@@ -1467,12 +1511,12 @@ App.config = Em.Object.create({
       success: 'successFunction',
       success: 'successFunction',
       error: 'errorFunction',
       error: 'errorFunction',
       successFunction: function () {
       successFunction: function () {
-        if(successCallback) {
+        if (successCallback) {
           successCallback();
           successCallback();
         }
         }
       },
       },
       errorFunction: function (xhr, text, errorThrown) {
       errorFunction: function (xhr, text, errorThrown) {
-        if(errorCallback) {
+        if (errorCallback) {
           errorCallback(xhr, text, errorThrown);
           errorCallback(xhr, text, errorThrown);
         }
         }
       }
       }
@@ -1483,7 +1527,7 @@ App.config = Em.Object.create({
 
 
   /**
   /**
    * Gets all the configuration-groups for the given service.
    * Gets all the configuration-groups for the given service.
-   * 
+   *
    * @param serviceId
    * @param serviceId
    *          (string) ID of the service. Ex: HDFS
    *          (string) ID of the service. Ex: HDFS
    */
    */

+ 44 - 68
ambari-web/app/utils/helper.js

@@ -316,79 +316,30 @@ App.format = {
    * @property components
    * @property components
    */
    */
   components: {
   components: {
-    'APP_TIMELINE_SERVER': 'App Timeline Server',
-    'DATANODE': 'DataNode',
+    'API': 'API',
     'DECOMMISSION_DATANODE': 'Update Exclude File',
     'DECOMMISSION_DATANODE': 'Update Exclude File',
-    'DRPC_SERVER': 'DRPC Server',
-    'FALCON': 'Falcon',
-    'FALCON_CLIENT': 'Falcon Client',
-    'FALCON_SERVER': 'Falcon Server',
-    'FALCON_SERVICE_CHECK': 'Falcon Service Check',
+    'DRPC': 'DRPC',
     'FLUME_HANDLER': 'Flume Agent',
     'FLUME_HANDLER': 'Flume Agent',
-    'FLUME_SERVICE_CHECK': 'Flume Service Check',
-    'GANGLIA_MONITOR': 'Ganglia Monitor',
-    'GANGLIA_SERVER': 'Ganglia Server',
-    'GLUSTERFS_CLIENT': 'GLUSTERFS Client',
-    'GLUSTERFS_SERVICE_CHECK': 'GLUSTERFS Service Check',
-    'GMETAD_SERVICE_CHECK': 'Gmetad Service Check',
-    'GMOND_SERVICE_CHECK': 'Gmond Service Check',
-    'HADOOP_CLIENT': 'Hadoop Client',
-    'HBASE_CLIENT': 'HBase Client',
-    'HBASE_MASTER': 'HBase Master',
+    'GLUSTERFS': 'GLUSTERFS',
+    'HBASE': 'HBase',
     'HBASE_REGIONSERVER': 'RegionServer',
     'HBASE_REGIONSERVER': 'RegionServer',
-    'HBASE_SERVICE_CHECK': 'HBase Service Check',
     'HCAT': 'HCat',
     'HCAT': 'HCat',
-    'HCAT_SERVICE_CHECK': 'HCat Service Check',
-    'HDFS_CLIENT': 'HDFS Client',
-    'HDFS_SERVICE_CHECK': 'HDFS Service Check',
+    'HDFS': 'HDFS',
     'HISTORYSERVER': 'History Server',
     'HISTORYSERVER': 'History Server',
-    'HIVE_CLIENT': 'Hive Client',
-    'HIVE_METASTORE': 'Hive Metastore',
     'HIVE_SERVER': 'HiveServer2',
     'HIVE_SERVER': 'HiveServer2',
-    'HIVE_SERVICE_CHECK': 'Hive Service Check',
-    'HUE_SERVER': 'Hue Server',
-    'JAVA_JCE': 'Java JCE',
-    'JOBTRACKER': 'JobTracker',
-    'JOBTRACKER_SERVICE_CHECK': 'JobTracker Service Check',
-    'JOURNALNODE': 'JournalNode',
-    'KERBEROS_ADMIN_CLIENT': 'Kerberos Admin Client',
-    'KERBEROS_CLIENT': 'Kerberos Client',
-    'KERBEROS_SERVER': 'Kerberos Server',
-    'MAPREDUCE2_CLIENT': 'MapReduce2 Client',
-    'MAPREDUCE2_SERVICE_CHECK': 'MapReduce2 Service Check',
-    'MAPREDUCE_CLIENT': 'MapReduce Client',
-    'MAPREDUCE_SERVICE_CHECK': 'MapReduce Service Check',
-    'MYSQL_SERVER': 'MySQL Server',
-    'NAGIOS_SERVER': 'Nagios Server',
-    'NAMENODE': 'NameNode',
-    'NAMENODE_SERVICE_CHECK': 'NameNode Service Check',
-    'NIMBUS': 'Nimbus',
-    'NODEMANAGER': 'NodeManager',
-    'OOZIE_CLIENT': 'Oozie Client',
-    'OOZIE_SERVER': 'Oozie Server',
-    'OOZIE_SERVICE_CHECK': 'Oozie Service Check',
-    'PIG': 'Pig',
-    'PIG_SERVICE_CHECK': 'Pig Service Check',
-    'RESOURCEMANAGER': 'ResourceManager',
+    'JCE': 'JCE',
+    'MAPREDUCE': 'MapReduce',
+    'MAPREDUCE2': 'MapReduce2',
+    'MYSQL': 'MySQL',
+    'REST': 'REST',
     'SECONDARY_NAMENODE': 'SNameNode',
     'SECONDARY_NAMENODE': 'SNameNode',
-    'SQOOP': 'Sqoop',
-    'SQOOP_SERVICE_CHECK': 'Sqoop Service Check',
     'STORM_REST_API': 'Storm REST API Server',
     'STORM_REST_API': 'Storm REST API Server',
-    'STORM_SERVICE_CHECK': 'Storm Service Check',
-    'STORM_UI_SERVER': 'Storm UI Server',
-    'SUPERVISOR': 'Supervisor',
-    'TASKTRACKER': 'TaskTracker',
-    'TEZ_CLIENT': 'Tez Client',
-    'WEBHCAT_SERVER': 'WebHCat Server',
-    'WEBHCAT_SERVICE_CHECK': 'WebHCat Service Check',
-    'YARN_CLIENT': 'YARN Client',
-    'YARN_SERVICE_CHECK': 'YARN Service Check',
+    'WEBHCAT': 'WebHCat',
+    'YARN': 'YARN',
+    'UI': 'UI',
     'ZKFC': 'ZKFailoverController',
     'ZKFC': 'ZKFailoverController',
-    'ZOOKEEPER_CLIENT': 'ZooKeeper Client',
-    'ZOOKEEPER_QUORUM_SERVICE_CHECK': 'ZK Quorum Service Check',
-    'ZOOKEEPER_SERVER': 'ZooKeeper Server',
-    'ZOOKEEPER_SERVICE_CHECK': 'ZooKeeper Service Check',
-    'CLIENT': 'Client'
+    'ZOOKEEPER': 'ZooKeeper',
+    'ZOOKEEPER_QUORUM_SERVICE_CHECK': 'ZK Quorum Service Check'
   },
   },
 
 
   /**
   /**
@@ -419,7 +370,32 @@ App.format = {
    * return {string}
    * return {string}
    */
    */
   role:function (role) {
   role:function (role) {
-    return this.components[role] ? this.components[role] : '';
+    return this.normalizeName(role);
+  },
+
+  /**
+   * Try to format non predefined names to readable format.
+   *
+   * @method normalizeName
+   * @param name {String} - name to format
+   * @return {String}
+   */
+  normalizeName: function(name) {
+    if (!name || typeof name != 'string') return '';
+    if (this.components[name]) return this.components[name];
+    name = name.toLowerCase();
+    var suffixNoSpaces = ['node','tracker','manager'];
+    var suffixRegExp = new RegExp('(\\w+)(' + suffixNoSpaces.join('|') + ')', 'gi');
+    if (/_/g.test(name)) {
+      name = name.split('_').map(function(singleName) {
+        return this.normalizeName(singleName.toUpperCase());
+      }, this).join(' ');
+    } else if(suffixRegExp.test(name)) {
+      suffixRegExp.lastIndex = 0;
+      var matches = suffixRegExp.exec(name);
+      name = matches[1].capitalize() + matches[2].capitalize();
+    };
+    return name.capitalize();
   },
   },
 
 
   /**
   /**
@@ -448,17 +424,17 @@ App.format = {
       } else if (self.command[item]) {
       } else if (self.command[item]) {
         result = result + ' ' + self.command[item];
         result = result + ' ' + self.command[item];
       } else {
       } else {
-        result = result + ' ' + item;
+        result = result + ' ' + self.role(item);
       }
       }
     });
     });
-    if (result === ' nagios_update_ignore ACTIONEXECUTE') {
+    if (result === ' Nagios Update Ignore Actionexecute') {
        result = Em.I18n.t('common.maintenance.task');
        result = Em.I18n.t('common.maintenance.task');
     }
     }
     return result;
     return result;
   },
   },
 
 
   /**
   /**
-   * Convert uppercase status name to downcase.
+   * Convert uppercase status name to lowercase.
    * <br>
    * <br>
    * <br>PENDING - Not queued yet for a host
    * <br>PENDING - Not queued yet for a host
    * <br>QUEUED - Queued for a host
    * <br>QUEUED - Queued for a host

+ 36 - 0
ambari-web/app/utils/string_utils.js

@@ -159,5 +159,41 @@ module.exports = {
     }
     }
     var last_slash = path.lastIndexOf('/');
     var last_slash = path.lastIndexOf('/');
     return (last_slash!=0)?path.substr(0,last_slash):'/';
     return (last_slash!=0)?path.substr(0,last_slash):'/';
+  },
+
+  /**
+   * @method getFormattedStringFromArray Get formatted string of elements to display on the UI
+   * Example:
+   * var arr = [ambari, bigdata, hadoop]
+   * getFormattedStringFromArray(arr);  // ambari, bigdata and hadoop
+   * @param array {Array}  Array of elements
+   * @returns {String}
+   */
+  getFormattedStringFromArray: function (array) {
+    var label = '';
+    array.forEach(function (_arrElement) {
+      if (array.length === 1) {
+        label = _arrElement;
+      }
+      else {
+        if (_arrElement !== array[array.length - 1]) {           // [clients.length - 1]
+          label = label + ' ' + _arrElement;
+          if (_arrElement !== array[array.length - 2]) {
+            label = label + ',';
+          }
+        }
+        else {
+          label = label + ' ' + Em.I18n.t('and') + ' ' + _arrElement;
+        }
+      }
+    }, this);
+    return label.trim();
+  },
+
+  pluralize: function(count, singular, plural) {
+    if (count > 1) {
+      return plural;
+    }
+    return singular;
   }
   }
 };
 };

+ 1 - 2
ambari-web/app/views/common/configs/services_config.js

@@ -488,14 +488,13 @@ App.ServiceConfigsByCategoryView = Ember.View.extend({
     var serviceName = this.get('service.serviceName');
     var serviceName = this.get('service.serviceName');
     var serviceConfigsMetaData = App.config.get('preDefinedServiceConfigs');
     var serviceConfigsMetaData = App.config.get('preDefinedServiceConfigs');
     var serviceConfigMetaData = serviceConfigsMetaData.findProperty('serviceName', serviceName);
     var serviceConfigMetaData = serviceConfigsMetaData.findProperty('serviceName', serviceName);
-    var categoryMetaData = serviceConfigMetaData == null ? null : serviceConfigMetaData.configCategories.findProperty('name', category.get('name'));
+    var categoryMetaData = serviceConfigMetaData == null ? null : serviceConfigMetaData.get('configCategories').findProperty('name', category.get('name'));
     if (categoryMetaData != null) {
     if (categoryMetaData != null) {
       serviceConfigObj.filename = categoryMetaData.siteFileName;
       serviceConfigObj.filename = categoryMetaData.siteFileName;
     }
     }
 
 
     var self = this;
     var self = this;
     App.ModalPopup.show({
     App.ModalPopup.show({
-      // classNames: ['big-modal'],
       classNames: [ 'sixty-percent-width-modal'],
       classNames: [ 'sixty-percent-width-modal'],
       header: "Add Property",
       header: "Add Property",
       primary: 'Add',
       primary: 'Add',

+ 5 - 0
ambari-web/app/views/main/host.js

@@ -84,6 +84,11 @@ App.MainHostView = App.TableView.extend(App.TableServerProvider, {
     });
     });
   }.property('filteredCount'),
   }.property('filteredCount'),
 
 
+  /**
+   * Stub function
+   */
+  updatePaging: function () {},
+
   /**
   /**
    * flag to toggle displaying selected hosts counter
    * flag to toggle displaying selected hosts counter
    */
    */

+ 1 - 8
ambari-web/app/views/main/host/addHost/step4_view.js

@@ -20,12 +20,5 @@
 var App = require('app');
 var App = require('app');
 
 
 App.AddHostStep4View = Em.View.extend({
 App.AddHostStep4View = Em.View.extend({
-
-  templateName: require('templates/main/host/addHost/step4'),
-
-
-  didInsertElement: function() {
-
-  }
-
+  templateName: require('templates/main/host/addHost/step4')
 });
 });

+ 4 - 3
ambari-web/app/views/main/host/configs_service_menu.js

@@ -28,8 +28,8 @@ App.MainHostServiceMenuView = Em.CollectionView.extend({
       hostComponents.forEach(function (hc) {
       hostComponents.forEach(function (hc) {
         var service = hc.get('service');
         var service = hc.get('service');
         if (service) {
         if (service) {
-        var serviceName = service.get('serviceName');
-          if(!['PIG', 'SQOOP', 'HCATALOG', 'GANGLIA'].contains(serviceName)){
+          var serviceName = service.get('serviceName');
+          if(!App.get('services.noConfigTypes').concat('HCATALOG').contains(serviceName)){
             if (!services.findProperty('serviceName', serviceName)) {
             if (!services.findProperty('serviceName', serviceName)) {
               services.push(service);
               services.push(service);
             }
             }
@@ -39,7 +39,8 @@ App.MainHostServiceMenuView = Em.CollectionView.extend({
         }
         }
       });
       });
     }
     }
-    return misc.sortByOrder(App.Service.servicesSortOrder, services);
+    var stackServices = App.StackService.find().mapProperty('serviceName');
+    return misc.sortByOrder(stackServices, services);
   }.property('host'),
   }.property('host'),
   
   
   host: function(){
   host: function(){

+ 4 - 2
ambari-web/app/views/main/service/info/summary.js

@@ -64,7 +64,9 @@ App.MainServiceInfoSummaryView = Em.View.extend({
    */
    */
   collapsedSections: null,
   collapsedSections: null,
 
 
-  servicesHaveClients: ["GLUSTERFS", "OOZIE", "ZOOKEEPER", "HIVE", "MAPREDUCE2", "TEZ", "SQOOP", "PIG","FALCON"],
+  servicesHaveClients: function() {
+    return App.get('services.hasClient');
+  }.property('App.services.hasClient'),
 
 
   sumMasterComponentView : Em.View.extend({
   sumMasterComponentView : Em.View.extend({
     didInsertElement: function() {
     didInsertElement: function() {
@@ -382,7 +384,7 @@ App.MainServiceInfoSummaryView = Em.View.extend({
    * Alerts panel not display for PIG, SQOOP and TEZ Service
    * Alerts panel not display for PIG, SQOOP and TEZ Service
    */
    */
   isNoAlertsService: function () {
   isNoAlertsService: function () {
-    return !!this.get('service.serviceName') && ['PIG', 'SQOOP', 'TEZ'].contains(this.get('service.serviceName'));
+    return !!this.get('service.serviceName') && App.get('services.clientOnly').contains(this.get('service.serviceName'));
   }.property(''),
   }.property(''),
 
 
   gangliaUrl:function () {
   gangliaUrl:function () {

+ 5 - 5
ambari-web/app/views/main/service/item.js

@@ -30,7 +30,7 @@ App.MainServiceItemView = Em.View.extend({
     var serviceName = service.get('serviceName');
     var serviceName = service.get('serviceName');
     var disableRefreshConfgis = !service.get('isRestartRequired');
     var disableRefreshConfgis = !service.get('isRestartRequired');
 
 
-    if (service.get('isClientsOnly')) {
+    if (this.get('controller.isClientsOnlyService')) {
       if (serviceName != 'TEZ') {
       if (serviceName != 'TEZ') {
         options.push({action: 'runSmokeTest', cssClass: 'icon-thumbs-up-alt', 'label': Em.I18n.t('services.service.actions.run.smoke')});
         options.push({action: 'runSmokeTest', cssClass: 'icon-thumbs-up-alt', 'label': Em.I18n.t('services.service.actions.run.smoke')});
       }
       }
@@ -84,13 +84,13 @@ App.MainServiceItemView = Em.View.extend({
       options.push({action:'turnOnOffPassive', cssClass: 'icon-medkit', context:requestLabel, 'label':passiveLabel , disabled: false});
       options.push({action:'turnOnOffPassive', cssClass: 'icon-medkit', context:requestLabel, 'label':passiveLabel , disabled: false});
     }
     }
     return options;
     return options;
-  }.property('controller.content', 'controller.isStopDisabled'),
+  }.property('controller.content', 'controller.isStopDisabled','controller.isClientsOnlyService'),
   isMaintenanceActive: function() {
   isMaintenanceActive: function() {
     return this.get('maintenance').length !== 0;
     return this.get('maintenance').length !== 0;
   }.property('maintenance'),
   }.property('maintenance'),
-  hasConfigTab: function(){
-    return this.get("controller.content.isConfigurable");
-  }.property('controller.content.isConfigurable'),
+  hasConfigTab: function() {
+    return !App.get('services.noConfigTypes').concat('HCATALOG').contains('controller.content.serviceName');
+  }.property('controller.content.serviceName','App.services.noConfigTypes'),
 
 
   didInsertElement: function () {
   didInsertElement: function () {
     this.get('controller').setStartStopState();
     this.get('controller').setStartStopState();

+ 16 - 6
ambari-web/app/views/main/service/menu.js

@@ -26,7 +26,8 @@ App.MainServiceMenuView = Em.CollectionView.extend({
     var items = App.router.get('mainServiceController.content').filter(function(item){
     var items = App.router.get('mainServiceController.content').filter(function(item){
       return !this.get('disabledServices').contains(item.get('id'));
       return !this.get('disabledServices').contains(item.get('id'));
     }, this);
     }, this);
-    return misc.sortByOrder(App.Service.servicesSortOrder, items);
+    var stackServices = App.StackService.find().mapProperty('serviceName');
+    return misc.sortByOrder(stackServices, items);
   }.property('App.router.mainServiceController.content', 'App.router.mainServiceController.content.length'),
   }.property('App.router.mainServiceController.content', 'App.router.mainServiceController.content.length'),
 
 
   didInsertElement:function () {
   didInsertElement:function () {
@@ -73,12 +74,16 @@ App.MainServiceMenuView = Em.CollectionView.extend({
       return this.get('content.criticalAlertsCount');
       return this.get('content.criticalAlertsCount');
     }.property('content.criticalAlertsCount'),
     }.property('content.criticalAlertsCount'),
 
 
+    isConfigurable: function () {
+      return !App.get('services.noConfigTypes').concat('HCATALOG').contains('content.serviceName');
+    }.property('App.services.noConfigTypes','content.serviceName'),
+
     link: function() {
     link: function() {
       var stateName = (['summary','configs'].contains(App.router.get('currentState.name')))
       var stateName = (['summary','configs'].contains(App.router.get('currentState.name')))
-        ? this.get('content.isConfigurable') ?  App.router.get('currentState.name') : 'summary'
+        ? this.get('isConfigurable') ?  App.router.get('currentState.name') : 'summary'
         : 'summary';
         : 'summary';
       return "#/main/services/" + this.get('content.id') + "/" + stateName;
       return "#/main/services/" + this.get('content.id') + "/" + stateName;
-    }.property('App.router.currentState.name', 'parentView.activeServiceId'),
+    }.property('App.router.currentState.name', 'parentView.activeServiceId', 'isConfigurable'),
 
 
     refreshRestartRequiredMessage: function() {
     refreshRestartRequiredMessage: function() {
       var restarted, componentsCount, hostsCount, message, tHosts, tComponents;
       var restarted, componentsCount, hostsCount, message, tHosts, tComponents;
@@ -115,7 +120,8 @@ App.TopNavServiceMenuView = Em.CollectionView.extend({
     var items = App.router.get('mainServiceController.content').filter(function(item){
     var items = App.router.get('mainServiceController.content').filter(function(item){
       return !this.get('disabledServices').contains(item.get('id'));
       return !this.get('disabledServices').contains(item.get('id'));
     }, this);
     }, this);
-    return misc.sortByOrder(App.Service.servicesSortOrder, items);
+    var stackServices = App.StackService.find().mapProperty('serviceName');
+    return misc.sortByOrder(stackServices, items);
   }.property('App.router.mainServiceController.content', 'App.router.mainServiceController.content.length'),
   }.property('App.router.mainServiceController.content', 'App.router.mainServiceController.content.length'),
 
 
   didInsertElement:function () {
   didInsertElement:function () {
@@ -160,12 +166,16 @@ App.TopNavServiceMenuView = Em.CollectionView.extend({
       return this.get('content.criticalAlertsCount');
       return this.get('content.criticalAlertsCount');
     }.property('content.criticalAlertsCount'),
     }.property('content.criticalAlertsCount'),
 
 
+    isConfigurable: function () {
+      return !App.get('services.noConfigTypes').concat('HCATALOG').contains('content.serviceName');
+    }.property('App.services.noConfigTypes','content.serviceName'),
+
     link: function() {
     link: function() {
       var stateName = (['summary','configs'].contains(App.router.get('currentState.name')))
       var stateName = (['summary','configs'].contains(App.router.get('currentState.name')))
-        ? this.get('content.isConfigurable') ?  App.router.get('currentState.name') : 'summary'
+        ? this.get('isConfigurable') ?  App.router.get('currentState.name') : 'summary'
         : 'summary';
         : 'summary';
       return "#/main/services/" + this.get('content.id') + "/" + stateName;
       return "#/main/services/" + this.get('content.id') + "/" + stateName;
-    }.property('App.router.currentState.name', 'parentView.activeServiceId'),
+    }.property('App.router.currentState.name', 'parentView.activeServiceId','isConfigurable'),
 
 
     refreshRestartRequiredMessage: function() {
     refreshRestartRequiredMessage: function() {
       var restarted, componentsCount, hostsCount, message, tHosts, tComponents;
       var restarted, componentsCount, hostsCount, message, tHosts, tComponents;

+ 3 - 2
ambari-web/app/views/main/service/service.js

@@ -52,7 +52,8 @@ App.MainDashboardServiceHealthView = Em.View.extend({
   },
   },
 
 
   healthStatus: function () {
   healthStatus: function () {
-    if (this.get('service.isClientsOnly')) {
+    var isClientOnlyService = App.get('services.clientOnly').contains(this.get('service.serviceName'));
+    if (isClientOnlyService) {
       return 'icon-laptop';
       return 'icon-laptop';
     }
     }
     if (this.get('service.passiveState') != 'OFF') {
     if (this.get('service.passiveState') != 'OFF') {
@@ -82,7 +83,7 @@ App.MainDashboardServiceHealthView = Em.View.extend({
     }
     }
 
 
     return 'health-status-' + status;
     return 'health-status-' + status;
-  }.property('service.healthStatus','service.passiveState','service.isClientsOnly'),
+  }.property('service.healthStatus','service.passiveState','service.serviceName'),
 
 
   healthStatusClass: function () {
   healthStatusClass: function () {
     switch (this.get('healthStatus')) {
     switch (this.get('healthStatus')) {

+ 22 - 5
ambari-web/app/views/wizard/step5_view.js

@@ -17,6 +17,7 @@
  */
  */
 
 
 var App = require('app');
 var App = require('app');
+var stringUtils = require('utils/string_utils');
 
 
 App.WizardStep5View = Em.View.extend({
 App.WizardStep5View = Em.View.extend({
 
 
@@ -33,14 +34,30 @@ App.WizardStep5View = Em.View.extend({
 
 
   didInsertElement: function () {
   didInsertElement: function () {
     this.get('controller').loadStep();
     this.get('controller').loadStep();
-  }
+    this.setCoHostedComponentText();
+  },
+
+  coHostedComponentText: '',
+
+  setCoHostedComponentText: function () {
+    var coHostedComponents = App.StackServiceComponent.find().filterProperty('isOtherComponentCoHosted').filterProperty('stackService.isSelected');
+    var coHostedComponentsText = '';
+    coHostedComponents.forEach(function (serviceComponent, index) {
+      var coHostedComponentsDisplayNames = serviceComponent.get('coHostedComponents').map(function (item) {
+        return App.StackServiceComponent.find().findProperty('componentName', item).get('displayName');
+      });
+      var componentTextArr = [serviceComponent.get('displayName')].concat(coHostedComponentsDisplayNames);
+      coHostedComponents[index] = stringUtils.getFormattedStringFromArray(componentTextArr);
+      coHostedComponentsText += '<br/>' + Em.I18n.t('installer.step5.body.coHostedComponents').format(coHostedComponents[index]);
+    }, this);
 
 
+    this.set('coHostedComponentText', coHostedComponentsText);
+  }
 });
 });
 
 
 App.InputHostView = Em.TextField.extend(App.SelectHost, {
 App.InputHostView = Em.TextField.extend(App.SelectHost, {
 
 
   attributeBindings: ['disabled'],
   attributeBindings: ['disabled'],
-
   /**
   /**
    * Saved typeahead component
    * Saved typeahead component
    * @type {$}
    * @type {$}
@@ -162,7 +179,7 @@ App.RemoveControlView = Em.View.extend({
    * Index for multiple component
    * Index for multiple component
    * @type {number}
    * @type {number}
    */
    */
-  zId: null,
+  serviceComponentId: null,
 
 
   /**
   /**
    * Current component name
    * Current component name
@@ -182,6 +199,6 @@ App.RemoveControlView = Em.View.extend({
    * @method click
    * @method click
    */
    */
   click: function () {
   click: function () {
-    this.get('controller').removeComponent(this.get('componentName'), this.get("zId"));
+    this.get('controller').removeComponent(this.get('componentName'), this.get("serviceComponentId"));
   }
   }
-});
+});

+ 3 - 10
ambari-web/app/views/wizard/step6_view.js

@@ -53,14 +53,9 @@ App.WizardStep6View = App.TableView.extend({
    */
    */
   didInsertElement: function () {
   didInsertElement: function () {
     var controller = this.get('controller');
     var controller = this.get('controller');
-    if (controller.get('isMasters')) {
-      this.set('label', Em.I18n.t('installer.step6.addHostWizard.body'));
-      this.set('title', Em.I18n.t('installer.step5.header'));
-    }
-    else {
-      this.set('title', Em.I18n.t('installer.step6.header'));
-      this.setLabel();
-    }
+    this.set('title', Em.I18n.t('installer.step6.header'));
+    this.setLabel();
+
     App.tooltip($('body'), {selector: '[rel=tooltip]'});
     App.tooltip($('body'), {selector: '[rel=tooltip]'});
     controller.loadStep();
     controller.loadStep();
   },
   },
@@ -113,8 +108,6 @@ App.WizardStep6HostView = Em.View.extend({
    * @method didInsertElement
    * @method didInsertElement
    */
    */
   didInsertElement: function () {
   didInsertElement: function () {
-    if(this.get('controller.isMasters')) return;
-
     var components = this.get('controller').getMasterComponentsForHost(this.get('host.hostName'));
     var components = this.get('controller').getMasterComponentsForHost(this.get('host.hostName'));
     if (components && components.length > 0) {
     if (components && components.length > 0) {
       components = components.map(function (_component) {
       components = components.map(function (_component) {

+ 2 - 14
ambari-web/test/app_test.js

@@ -92,14 +92,15 @@ describe('#App', function() {
 
 
     var globalProperties = require('data/HDP2/global_properties');
     var globalProperties = require('data/HDP2/global_properties');
     var siteProperties = require('data/HDP2/site_properties');
     var siteProperties = require('data/HDP2/site_properties');
+
     var reviewConfigs = require('data/review_configs');
     var reviewConfigs = require('data/review_configs');
     var disableResult = App.disableComponent(testableComponent);
     var disableResult = App.disableComponent(testableComponent);
 
 
+
     describe('#disableComponent()', function() {
     describe('#disableComponent()', function() {
       // copy
       // copy
       var _globalProperties = $.extend({}, globalProperties);
       var _globalProperties = $.extend({}, globalProperties);
       var _siteProperties = $.extend({}, siteProperties);
       var _siteProperties = $.extend({}, siteProperties);
-      var _reviewConfigs = JSON.parse(JSON.stringify(reviewConfigs));
 
 
       describe('result validation', function() {
       describe('result validation', function() {
 
 
@@ -139,12 +140,6 @@ describe('#App', function() {
           expect(_siteProperties.configProperties.mapProperty('name')).to.not.include.members(expectedInfo.properties.site_properties);
           expect(_siteProperties.configProperties.mapProperty('name')).to.not.include.members(expectedInfo.properties.site_properties);
         });
         });
 
 
-        it('should remove review config for component', function() {
-          var reviewConfig = _reviewConfigs.findProperty('config_name', 'services')
-            .config_value.findProperty('service_name', testableComponent.get('serviceName'))
-            .service_components.mapProperty('component_name');
-          expect(reviewConfig).to.not.include(expectedInfo.reviewConfigs.component_name);
-        });
       });
       });
     });
     });
 
 
@@ -158,13 +153,6 @@ describe('#App', function() {
       it('should add site properties of component', function() {
       it('should add site properties of component', function() {
         expect(siteProperties.configProperties.mapProperty('name')).to.include.members(expectedInfo.properties.site_properties);
         expect(siteProperties.configProperties.mapProperty('name')).to.include.members(expectedInfo.properties.site_properties);
       });
       });
-
-      it('should add review config for component', function() {
-        var reviewConfig = reviewConfigs.findProperty('config_name', 'services')
-          .config_value.findProperty('service_name', testableComponent.get('serviceName'))
-          .get('service_components').mapProperty('component_name');
-        expect(reviewConfig).to.include(expectedInfo.reviewConfigs.component_name);
-      });
     });
     });
 
 
     modelSetup.restoreStackVersion(this);
     modelSetup.restoreStackVersion(this);

+ 10 - 10
ambari-web/test/controllers/main/host/add_controller_test.js

@@ -119,30 +119,30 @@ describe('App.AddHostController', function () {
       {
       {
         title: 'Service is not in stack',
         title: 'Service is not in stack',
         services: [
         services: [
-          {
+          Em.Object.create({
             serviceName: 'TEST',
             serviceName: 'TEST',
             isSelected: true
             isSelected: true
-          }
+          })
         ],
         ],
         result: []
         result: []
       },
       },
       {
       {
         title: 'Service does not have any clients',
         title: 'Service does not have any clients',
         services: [
         services: [
-          {
+          Em.Object.create({
             serviceName: 'GANGLIA',
             serviceName: 'GANGLIA',
             isSelected: true
             isSelected: true
-          }
+          })
         ],
         ],
         result: []
         result: []
       },
       },
       {
       {
         title: 'StackServiceComponent is empty',
         title: 'StackServiceComponent is empty',
         services: [
         services: [
-          {
+          Em.Object.create({
             serviceName: 'HDFS',
             serviceName: 'HDFS',
             isSelected: true
             isSelected: true
-          }
+          })
         ],
         ],
         result: []
         result: []
       }
       }
@@ -160,10 +160,10 @@ describe('App.AddHostController', function () {
     it('HDFS has uninstalled client', function () {
     it('HDFS has uninstalled client', function () {
       modelSetup.setupStackServiceComponent();
       modelSetup.setupStackServiceComponent();
       var services = [
       var services = [
-        {
+        Em.Object.create({
           serviceName: 'HDFS',
           serviceName: 'HDFS',
           isSelected: true
           isSelected: true
-        }
+        })
       ];
       ];
       controller.set('content.services', services);
       controller.set('content.services', services);
       controller.saveClients();
       controller.saveClients();
@@ -186,10 +186,10 @@ describe('App.AddHostController', function () {
     it('HDFS has installed client', function () {
     it('HDFS has installed client', function () {
       modelSetup.setupStackServiceComponent();
       modelSetup.setupStackServiceComponent();
       var services = [
       var services = [
-        {
+        Em.Object.create({
           serviceName: 'HDFS',
           serviceName: 'HDFS',
           isSelected: true
           isSelected: true
-        }
+        })
       ];
       ];
       App.store.load(App.HostComponent, {
       App.store.load(App.HostComponent, {
         id: 'HDFS_CLIENT_host1',
         id: 'HDFS_CLIENT_host1',

+ 1 - 0
ambari-web/test/controllers/main/host/details_test.js

@@ -913,6 +913,7 @@ describe('App.MainHostDetailsController', function () {
       controller.doDecommissionRegionServer.restore();
       controller.doDecommissionRegionServer.restore();
       controller.doDecommission.restore();
       controller.doDecommission.restore();
       controller.showBackgroundOperationsPopup.restore();
       controller.showBackgroundOperationsPopup.restore();
+      controller.doDecommissionRegionServer.restore();
     });
     });
 
 
     it('HDFS service', function () {
     it('HDFS service', function () {

+ 27 - 148
ambari-web/test/controllers/wizard/step4_test.js

@@ -30,7 +30,7 @@ describe('App.WizardStep4Controller', function () {
   var controller = App.WizardStep4Controller.create();
   var controller = App.WizardStep4Controller.create();
   services.forEach(function(serviceName, index){
   services.forEach(function(serviceName, index){
     controller.pushObject(Ember.Object.create({
     controller.pushObject(Ember.Object.create({
-      'serviceName':serviceName, 'isSelected': true, 'canBeSelected': true, 'isInstalled': false, 'isDisabled': 'HDFS' === serviceName
+      'serviceName':serviceName, 'isSelected': true, 'canBeSelected': true, 'isInstalled': false, 'isDisabled': 'HDFS' === serviceName, isDFS: 'HDFS' === serviceName
     }));
     }));
   });
   });
 
 
@@ -78,145 +78,14 @@ describe('App.WizardStep4Controller', function () {
   });
   });
 
 
   describe('#selectMinimum()', function () {
   describe('#selectMinimum()', function () {
-    it('should set isSelected false for all not disabled services', function () {
+    it('should set isSelected false for all services', function () {
       controller.setEach('isSelected', true);
       controller.setEach('isSelected', true);
       controller.selectMinimum();
       controller.selectMinimum();
-      expect(controller.findProperty('serviceName', 'HDFS').get('isSelected')).to.equal(true);
+      expect(controller.findProperty('serviceName', 'HDFS').get('isSelected')).to.equal(false);
       expect(controller.filterProperty('isDisabled', false).everyProperty('isSelected', false)).to.equal(true);
       expect(controller.filterProperty('isDisabled', false).everyProperty('isSelected', false)).to.equal(true);
     });
     });
   });
   });
 
 
-  describe('#needToAddMapReduce()', function () {
-    it('should return true if Pig is selected and MapReduce is not selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'PIG').set('isSelected', true);
-      expect(controller.needToAddMapReduce()).to.equal(true);
-    });
-
-    it('should return true if Oozie is selected and MapReduce is not selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'OOZIE').set('isSelected', true);
-      expect(controller.needToAddMapReduce()).to.equal(true);
-    });
-
-    it('should return true if Hive is selected and MapReduce is not selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'HIVE').set('isSelected', true);
-      expect(controller.needToAddMapReduce()).to.equal(true);
-    });
-
-    it('should return false if MapReduce is selected or Pig, Oozie and Hive are not selected', function () {
-      controller.findProperty('serviceName', 'MAPREDUCE').set('isSelected', true);
-      expect(controller.needToAddMapReduce()).to.equal(false);
-      controller.setEach('isSelected', false);
-      expect(controller.needToAddMapReduce()).to.equal(false);
-    });
-  });
-
-  describe('#needToAddYarnMapReduce2()', function () {
-    it('should return true if Pig is selected and YARN+MapReduce2 is not selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'PIG').set('isSelected', true);
-      expect(controller.needToAddYarnMapReduce2()).to.equal(true);
-    });
-
-    it('should return true if Oozie is selected and YARN+MapReduce2 is not selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'OOZIE').set('isSelected', true);
-      expect(controller.needToAddYarnMapReduce2()).to.equal(true);
-    });
-
-    it('should return true if Hive is selected and YARN+MapReduce2 is not selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'HIVE').set('isSelected', true);
-      expect(controller.needToAddYarnMapReduce2()).to.equal(true);
-    });
-
-    it('should return false if YARN+MapReduce2 is selected or Pig, Oozie and Hive are not selected', function () {
-      controller.findProperty('serviceName', 'YARN').set('isSelected', true);
-      expect(controller.needToAddYarnMapReduce2()).to.equal(false);
-      controller.setEach('isSelected', false);
-      expect(controller.needToAddYarnMapReduce2()).to.equal(false);
-    });
-  });
-
-  describe('#needToAddZooKeeper()', function () {
-    beforeEach(function() {
-      ajax_send = App.ajax.send;
-      App.ajax.send = function() {};
-    });
-
-    afterEach(function() {
-      App.ajax.send = ajax_send;
-    });
-    var originalStackVersion = App.get('currentStackVersion');
-
-    it('should return false if ZOOKEEPER is selected and Hadoop version above 2', function () {
-      App.set('currentStackVersion', 'HDP-2.1.1');
-      controller.findProperty('serviceName', 'ZOOKEEPER').set('isSelected', true);
-      expect(controller.needToAddZooKeeper()).to.equal(false);
-    });
-    it('should return true if ZOOKEEPER is not selected and Hadoop version above 2', function () {
-      controller.findProperty('serviceName', 'ZOOKEEPER').set('isSelected', false);
-      expect(controller.needToAddZooKeeper()).to.equal(true);
-    });
-    it('should return false if none of the HBASE, HIVE, WEBHCAT, STORM is selected and Hadoop version below 2', function () {
-      App.set('currentStackVersion', 'HDP-1.3.0');
-      expect(controller.needToAddZooKeeper()).to.equal(false);
-    });
-    it('should return true if HBASE is not selected and Hadoop version below 2', function () {
-      controller.findProperty('serviceName', 'HBASE').set('isSelected', true);
-      expect(controller.needToAddZooKeeper()).to.equal(true);
-    });
-    it('should return true if HBASE, HIVE, WEBHCAT, STORM are selected and Hadoop version below 2', function () {
-      controller.findProperty('serviceName', 'HIVE').set('isSelected', true);
-      controller.findProperty('serviceName', 'WEBHCAT').set('isSelected', true);
-      controller.findProperty('serviceName', 'STORM').set('isSelected', true);
-      expect(controller.needToAddZooKeeper()).to.equal(true);
-      App.set('currentStackVersion', originalStackVersion);
-    });
-  });
-
-  describe('#gangliaOrNagiosNotSelected()', function () {
-    it('should return true if Nagios or Ganglia is not selected', function () {
-      controller.setEach('isSelected', true);
-      controller.findProperty('serviceName', 'NAGIOS').set('isSelected', false);
-      expect(controller.gangliaOrNagiosNotSelected()).to.equal(true);
-      controller.setEach('isSelected', true);
-      controller.findProperty('serviceName', 'GANGLIA').set('isSelected', false);
-      expect(controller.gangliaOrNagiosNotSelected()).to.equal(true);
-    });
-
-    it('should return false if Nagios and Ganglia is selected', function () {
-      controller.setEach('isSelected', false);
-      controller.findProperty('serviceName', 'GANGLIA').set('isSelected', true);
-      controller.findProperty('serviceName', 'NAGIOS').set('isSelected', true);
-      expect(controller.gangliaOrNagiosNotSelected()).to.equal(false);
-    });
-  });
-
-  describe('#needToAddTez()', function () {
-    it('should return false if YARN is present, but not selected', function () {
-      controller.findProperty('serviceName', 'YARN').set('isSelected', false);
-      expect(controller.needToAddTez()).to.equal(false);
-    });
-    it('should return true if YARN is selected', function () {
-      controller.findProperty('serviceName', 'YARN').set('isSelected', true);
-      expect(controller.needToAddTez()).to.equal(true);
-    });
-  });
-
-  describe('#needToAddOozie()', function () {
-    it('should return false if FALCON is present, but not selected', function () {
-      controller.findProperty('serviceName', 'FALCON').set('isSelected', false);
-      expect(controller.needToAddOozie()).to.equal(false);
-    });
-    it('should return true if FALCON is selected', function () {
-      controller.findProperty('serviceName', 'FALCON').set('isSelected', true);
-      expect(controller.needToAddOozie()).to.equal(true);
-    });
-  });
-
   describe('#noDFSs()', function () {
   describe('#noDFSs()', function () {
     it('should return true if HDFS is not selected and GLUSTERFS is absent', function () {
     it('should return true if HDFS is not selected and GLUSTERFS is absent', function () {
       controller.findProperty('serviceName', 'HDFS').set('isSelected', false);
       controller.findProperty('serviceName', 'HDFS').set('isSelected', false);
@@ -228,7 +97,7 @@ describe('App.WizardStep4Controller', function () {
     });
     });
     it('should return true if HDFS is not selected and GLUSTERFS is not selected, but present', function () {
     it('should return true if HDFS is not selected and GLUSTERFS is not selected, but present', function () {
       controller.pushObject(Ember.Object.create({
       controller.pushObject(Ember.Object.create({
-        'serviceName':'GLUSTERFS', 'isSelected': false, 'canBeSelected': true, 'isInstalled': false, 'isDisabled': false
+        'serviceName':'GLUSTERFS', 'isSelected': false, 'canBeSelected': true, 'isInstalled': false, 'isDisabled': false, 'isDFS': true
       }));
       }));
       controller.findProperty('serviceName', 'HDFS').set('isSelected', false);
       controller.findProperty('serviceName', 'HDFS').set('isSelected', false);
       expect(controller.noDFSs()).to.equal(true);
       expect(controller.noDFSs()).to.equal(true);
@@ -256,7 +125,7 @@ describe('App.WizardStep4Controller', function () {
     });
     });
   });
   });
 
 
-  describe('#checkDependencies()', function () {
+  describe('#setGroupedServices()', function () {
     var testCases = [
     var testCases = [
       {
       {
         title: 'should set HCATALOG and WEBHCAT isSelected to true when HIVE is selected',
         title: 'should set HCATALOG and WEBHCAT isSelected to true when HIVE is selected',
@@ -327,10 +196,13 @@ describe('App.WizardStep4Controller', function () {
         controller.clear();
         controller.clear();
         for(var id in testCase.condition) {
         for(var id in testCase.condition) {
           controller.pushObject(Ember.Object.create({
           controller.pushObject(Ember.Object.create({
-            'serviceName':id, 'isSelected': testCase.condition[id], 'canBeSelected': true, 'isInstalled': false
+            'serviceName':id, 'isSelected': testCase.condition[id], 'canBeSelected': true, 'isInstalled': false,
+            coSelectedServices: function() {
+              return App.StackService.coSelected[this.get('serviceName')] || [];
+            }.property('serviceName')
           }));
           }));
         }
         }
-        controller.checkDependencies();
+        controller.setGroupedServices();
         for(var service in testCase.result) {
         for(var service in testCase.result) {
           expect(controller.findProperty('serviceName', service).get('isSelected')).to.equal(testCase.result[service]);
           expect(controller.findProperty('serviceName', service).get('isSelected')).to.equal(testCase.result[service]);
         }
         }
@@ -381,6 +253,14 @@ describe('App.WizardStep4Controller', function () {
   });
   });
 
 
   describe('#validateMonitoring', function() {
   describe('#validateMonitoring', function() {
+    beforeEach(function() {
+      sinon.stub(controller, 'monitoringCheckPopup', Em.K);
+      sinon.stub(App.router, 'send', Em.K);
+    });
+    afterEach(function() {
+      controller.monitoringCheckPopup.restore();
+      App.router.send.restore();
+    });
     Em.A([
     Em.A([
         {
         {
           gangliaOrNagiosNotSelected: true,
           gangliaOrNagiosNotSelected: true,
@@ -398,12 +278,11 @@ describe('App.WizardStep4Controller', function () {
         }
         }
       ]).forEach(function (test) {
       ]).forEach(function (test) {
         it(test.m, function () {
         it(test.m, function () {
-          sinon.stub(controller, 'monitoringCheckPopup', Em.K);
-          sinon.stub(App.router, 'send', Em.K);
           sinon.stub(controller, 'gangliaOrNagiosNotSelected', function() {
           sinon.stub(controller, 'gangliaOrNagiosNotSelected', function() {
             return test.gangliaOrNagiosNotSelected;
             return test.gangliaOrNagiosNotSelected;
           });
           });
           controller.validateMonitoring();
           controller.validateMonitoring();
+          controller.gangliaOrNagiosNotSelected.restore();
           if (test.e.monitoringCheckPopup) {
           if (test.e.monitoringCheckPopup) {
            expect(controller.monitoringCheckPopup.calledOnce).to.equal(true);
            expect(controller.monitoringCheckPopup.calledOnce).to.equal(true);
           }
           }
@@ -416,9 +295,6 @@ describe('App.WizardStep4Controller', function () {
           else {
           else {
             expect(App.router.send.called).to.equal(false);
             expect(App.router.send.called).to.equal(false);
           }
           }
-          controller.gangliaOrNagiosNotSelected.restore();
-          controller.monitoringCheckPopup.restore();
-          App.router.send.restore();
         });
         });
       });
       });
   });
   });
@@ -426,9 +302,11 @@ describe('App.WizardStep4Controller', function () {
   describe('#submit', function() {
   describe('#submit', function() {
     beforeEach(function() {
     beforeEach(function() {
       sinon.stub(controller, 'validateMonitoring', Em.K);
       sinon.stub(controller, 'validateMonitoring', Em.K);
+      sinon.stub(controller, 'setGroupedServices', Em.K);
     });
     });
     afterEach(function() {
     afterEach(function() {
       controller.validateMonitoring.restore();
       controller.validateMonitoring.restore();
+      controller.setGroupedServices.restore();
     });
     });
     it('if not isSubmitDisabled shound\'t do nothing', function() {
     it('if not isSubmitDisabled shound\'t do nothing', function() {
       controller.reopen({isSubmitDisabled: true});
       controller.reopen({isSubmitDisabled: true});
@@ -436,19 +314,20 @@ describe('App.WizardStep4Controller', function () {
       expect(controller.validateMonitoring.called).to.equal(false);
       expect(controller.validateMonitoring.called).to.equal(false);
     });
     });
     it('if isSubmitDisabled and not submitChecks should call validateMonitoring', function() {
     it('if isSubmitDisabled and not submitChecks should call validateMonitoring', function() {
+      sinon.stub(controller, 'isSubmitChecksFailed', function() { return false; });
       controller.reopen({
       controller.reopen({
         isSubmitDisabled: false,
         isSubmitDisabled: false,
         submitChecks: []
         submitChecks: []
       });
       });
       controller.submit();
       controller.submit();
       expect(controller.validateMonitoring.calledOnce).to.equal(true);
       expect(controller.validateMonitoring.calledOnce).to.equal(true);
+      controller.isSubmitChecksFailed.restore();
     });
     });
     it('if isSubmitDisabled and some submitChecks true shouldn\'t call validateMonitoring', function() {
     it('if isSubmitDisabled and some submitChecks true shouldn\'t call validateMonitoring', function() {
       controller.reopen({
       controller.reopen({
         isSubmitDisabled: false,
         isSubmitDisabled: false,
         submitChecks: [
         submitChecks: [
           {
           {
-            checkCallback: 'needToAddMapReduce',
             popupParams: [
             popupParams: [
               {serviceName: 'MAPREDUCE', selected: true},
               {serviceName: 'MAPREDUCE', selected: true},
               'mapreduceCheck'
               'mapreduceCheck'
@@ -456,10 +335,10 @@ describe('App.WizardStep4Controller', function () {
           }
           }
         ]
         ]
       });
       });
-      sinon.stub(controller, 'needToAddMapReduce', function() {return true;});
+      sinon.stub(controller, 'isSubmitChecksFailed', function() { return true; });
       controller.submit();
       controller.submit();
+      controller.isSubmitChecksFailed.restore();
       expect(controller.validateMonitoring.called).to.equal(false);
       expect(controller.validateMonitoring.called).to.equal(false);
-      controller.needToAddMapReduce.restore();
     });
     });
     it('if isSubmitDisabled and some submitChecks false should call validateMonitoring', function() {
     it('if isSubmitDisabled and some submitChecks false should call validateMonitoring', function() {
       controller.reopen({
       controller.reopen({
@@ -474,10 +353,10 @@ describe('App.WizardStep4Controller', function () {
           }
           }
         ]
         ]
       });
       });
-      sinon.stub(controller, 'needToAddMapReduce', function() {return false;});
+      sinon.stub(controller, 'isSubmitChecksFailed', function() { return false; });
       controller.submit();
       controller.submit();
+      controller.isSubmitChecksFailed.restore();
       expect(controller.validateMonitoring.calledOnce).to.equal(true);
       expect(controller.validateMonitoring.calledOnce).to.equal(true);
-      controller.needToAddMapReduce.restore();
     });
     });
   });
   });
 
 

File diff suppressed because it is too large
+ 229 - 415
ambari-web/test/controllers/wizard/step5_test.js


+ 0 - 6
ambari-web/test/controllers/wizard/step6_test.js

@@ -56,9 +56,6 @@ describe('App.WizardStep6Controller', function () {
       masterComponentHosts: {},
       masterComponentHosts: {},
       services: services
       services: services
     });
     });
-    sinon.stub(controller, 'getComponentDisplayName', function (c) {
-      return App.format.components[c];
-    });
 
 
     var h = {}, m = [];
     var h = {}, m = [];
     Em.A(['host0', 'host1', 'host2', 'host3']).forEach(function (hostName) {
     Em.A(['host0', 'host1', 'host2', 'host3']).forEach(function (hostName) {
@@ -77,9 +74,6 @@ describe('App.WizardStep6Controller', function () {
 
 
   });
   });
 
 
-  afterEach(function () {
-    controller.getComponentDisplayName.restore();
-  });
 
 
   describe('#loadStep', function () {
   describe('#loadStep', function () {
     Em.A([
     Em.A([

+ 153 - 0
ambari-web/test/controllers/wizard/step8_test.js

@@ -17,6 +17,7 @@
  */
  */
 
 
 var App = require('app');
 var App = require('app');
+var modelSetup = require('test/init_model_test');
 require('utils/ajax/ajax_queue');
 require('utils/ajax/ajax_queue');
 require('controllers/main/admin/security');
 require('controllers/main/admin/security');
 require('controllers/main/service/info/configs');
 require('controllers/main/service/info/configs');
@@ -487,6 +488,158 @@ describe('App.WizardStep8Controller', function () {
       });
       });
   });
   });
 
 
+  describe('#loadServices()', function() {
+    var serviceComponentGenerator = function(componentName, displayName, componentValue) {
+      return Em.Object.create({
+        component_name: componentName,
+        display_name: displayName,
+        component_value: componentValue
+      })
+    };
+
+    var slaveComponentGenerator = function(componentName, hosts) {
+      return Em.Object.create({
+        componentName: componentName,
+        hosts: hosts.map(function(host) { return {'hostName' : host } })
+      });
+    };
+    var masterComponentGenerator = function(componentName, hostName) {
+      return Em.Object.create({
+        component: componentName,
+        hostName: hostName
+      });
+    };
+
+    var serviceConfigGenerator = function(name, value) {
+      return Em.Object.create({
+        name: name,
+        value: value
+      });
+    }
+    before(function() {
+      modelSetup.setupStackServiceComponent();
+      var services = ['HDFS', 'YARN', 'TEZ', 'NAGIOS', 'GANGLIA','OOZIE'];
+      this.controller = App.WizardStep8Controller.create({
+        content: {
+          services: App.StackService.find().setEach('isSelected', true).setEach('isInstalled', false).filterProperty('stackVersion', '2.1').filter(function(service) {
+            return services.contains(service.get('serviceName'));
+          }),
+          slaveComponentHosts: Em.A([
+            slaveComponentGenerator('DATANODE', ['h1','h2']),
+            slaveComponentGenerator('NODEMANAGER', ['h1']),
+            slaveComponentGenerator('CLIENT', ['h1'])
+          ]),
+          masterComponentHosts: Em.A([
+            masterComponentGenerator('NAMENODE', 'h1'),
+            masterComponentGenerator('SECONDARY_NAMENODE', 'h2'),
+            masterComponentGenerator('APP_TIMELINE_SERVER', 'h1'),
+            masterComponentGenerator('RESOURCEMANAGER', 'h1'),
+            masterComponentGenerator('NAGIOS_SERVER', 'h1'),
+            masterComponentGenerator('GANGLIA_SERVER', 'h2'),
+            masterComponentGenerator('OOZIE_SERVER', 'h2')
+          ]),
+          serviceConfigProperties: Em.A([
+            serviceConfigGenerator('nagios_web_login', 'admin'),
+            serviceConfigGenerator('nagios_contact', 'admin@admin.com'),
+            serviceConfigGenerator('oozie_database', 'New Derby Database'),
+            serviceConfigGenerator('oozie_derby_database', '')
+          ])
+        }
+      });
+      var _this = this;
+      this.controller.reopen({
+        wizardController: {
+          getDBProperty: function() {
+            return _this.controller.get('content.serviceConfigProperties')
+          }
+        }
+      });
+      this.controller.loadServices();
+    });
+
+    var tests = [
+      {
+        service_name: 'HDFS',
+        display_name: 'HDFS',
+        service_components: Em.A([
+          serviceComponentGenerator('NAMENODE', 'NameNode', 'h1'),
+          serviceComponentGenerator('DATANODE', 'DataNode', '2 hosts'),
+          serviceComponentGenerator('SECONDARY_NAMENODE', 'SNameNode', 'h2')
+        ])
+      },
+      {
+        service_name: 'YARN',
+        display_name: 'YARN + MapReduce2',
+        service_components: Em.A([
+          serviceComponentGenerator('RESOURCEMANAGER', 'ResourceManager', 'h1'),
+          serviceComponentGenerator('NODEMANAGER', 'NodeManager', '1 host'),
+          serviceComponentGenerator('APP_TIMELINE_SERVER', 'App Timeline Server', 'h1')
+        ])
+      },
+      {
+        service_name: 'TEZ',
+        display_name: 'Tez',
+        service_components: Em.A([
+          serviceComponentGenerator('CLIENT', 'Clients', '1 host')
+        ])
+      },
+      {
+        service_name: 'NAGIOS',
+        display_name: 'Nagios',
+        service_components: Em.A([
+          serviceComponentGenerator('NAGIOS_SERVER', 'Server', 'h1'),
+          serviceComponentGenerator('Custom', 'Administrator', 'admin / (admin@admin.com)')
+        ])
+      },
+      {
+        service_name: 'GANGLIA',
+        display_name: 'Ganglia',
+        service_components: Em.A([
+          serviceComponentGenerator('GANGLIA_SERVER', 'Server', 'h2')
+        ])
+      },
+      {
+        service_name: 'OOZIE',
+        display_name: 'Oozie',
+        service_components: Em.A([
+          serviceComponentGenerator('OOZIE_SERVER', 'Server', 'h2'),
+          serviceComponentGenerator('Custom', 'Database', ' (New Derby Database)')
+        ])
+      }
+    ];
+
+    tests.forEach(function(test) {
+      describe('Load review for `' + test.service_name + '` service', function(){
+        it('{0} service should be displayed as {1}'.format(test.service_name, test.display_name), function() {
+          expect(this.controller.get('services').findProperty('service_name', test.service_name).get('display_name')).to.eql(test.display_name);
+        });
+        it('{0}: all components present'.format(test.service_name), function() {
+          var serviceObj = this.controller.get('services').findProperty('service_name', test.service_name);
+          expect(test.service_components.length).to.be.eql(serviceObj.get('service_components.length'));
+        });
+        test.service_components.forEach(function(serviceComponent) {
+          var testMessage = '`{0}` component present with `{1}` value and displayed as `{2}`';
+          it(testMessage.format(serviceComponent.get('component_name'), serviceComponent.get('component_value'), serviceComponent.get('display_name')), function() {
+            var serviceObj = this.controller.get('services').findProperty('service_name', test.service_name);
+            var component;
+            if (serviceComponent.get('component_name') === 'Custom') {
+              component = serviceObj.get('service_components').findProperty('display_name', serviceComponent.get('display_name'));
+            } else
+              component = serviceObj.get('service_components').findProperty('component_name', serviceComponent.get('component_name'));
+            if (serviceComponent.get('component_name') !== 'Custom')
+              expect(component.get('component_name')).to.eql(serviceComponent.get('component_name'));
+            expect(component.get('component_value')).to.eql(serviceComponent.get('component_value'));
+            expect(component.get('display_name')).to.eql(serviceComponent.get('display_name'));
+          });
+        });
+      })
+    });
+
+    after(function() {
+      modelSetup.cleanStackServiceComponent();
+    });
+  });
+
   describe('#removeHiveConfigs', function () {
   describe('#removeHiveConfigs', function () {
     Em.A([
     Em.A([
         {
         {

+ 2 - 0
ambari-web/test/controllers/wizard/step9_test.js

@@ -23,6 +23,8 @@ require('models/stack_service_component');
 require('models/hosts');
 require('models/hosts');
 require('controllers/wizard/step9_controller');
 require('controllers/wizard/step9_controller');
 require('utils/helper');
 require('utils/helper');
+require('utils/ajax/ajax');
+
 var modelSetup = require('test/init_model_test');
 var modelSetup = require('test/init_model_test');
 var c, obj;
 var c, obj;
 describe('App.InstallerStep9Controller', function () {
 describe('App.InstallerStep9Controller', function () {

+ 3 - 9
ambari-web/test/init_model_test.js

@@ -19,21 +19,15 @@
 var App = require('app');
 var App = require('app');
 require('models/stack_service_component');
 require('models/stack_service_component');
 require('mappers/server_data_mapper');
 require('mappers/server_data_mapper');
-require('mappers/stack_service_component_mapper');
+require('mappers/stack_service_mapper');
 
 
 module.exports = {
 module.exports = {
   setupStackServiceComponent: function() {
   setupStackServiceComponent: function() {
     /**
     /**
-     * initialization of App.StackServiceComponent model
+     * initialization of App.StackServiceComponent and App.StackService models
      * @type {*}
      * @type {*}
      */
      */
-    var data = {items: Em.A([])};
-    require('test/service_components').items.forEach(function(i) {
-      i.serviceComponents.forEach(function(sc) {
-        data.items.pushObject(sc.StackServiceComponents);
-      });
-    });
-    App.stackServiceComponentMapper.map(data);
+    App.stackServiceMapper.map(require('test/service_components'));
   },
   },
   cleanStackServiceComponent: function(){
   cleanStackServiceComponent: function(){
     App.StackServiceComponent.find().set('content',[]);
     App.StackServiceComponent.find().set('content',[]);

File diff suppressed because it is too large
+ 486 - 65
ambari-web/test/service_components.js


+ 0 - 71
ambari-web/test/utils/component_test.js

@@ -22,75 +22,4 @@ require('models/host_component');
 require('models/stack_service_component');
 require('models/stack_service_component');
 
 
 describe('utils/component', function(){
 describe('utils/component', function(){
-  describe('#loadStackServiceComponentModel()', function(){
-    var data = {
-      "items": [
-        {
-          "serviceComponents": [
-            {
-              "StackServiceComponents": {
-                "component_category": "CLIENT",
-                "component_name": "FALCON_CLIENT",
-                "is_client": true,
-                "is_master": false,
-                "service_name": "FALCON",
-                "stack_name": "HDP",
-                "stack_version": "2.1"
-              }
-            },
-            {
-              "StackServiceComponents": {
-                "component_category": "MASTER",
-                "component_name": "FALCON_SERVER",
-                "is_client": false,
-                "is_master": true,
-                "service_name": "FALCON",
-                "stack_name": "HDP",
-                "stack_version": "2.1"
-              }
-            }
-          ]
-        },
-        {
-          "serviceComponents": [
-            {
-              "StackServiceComponents": {
-                "component_category": "SLAVE",
-                "component_name": "GANGLIA_MONITOR",
-                "is_client": false,
-                "is_master": false,
-                "service_name": "GANGLIA",
-                "stack_name": "HDP",
-                "stack_version": "2.1"
-              }
-            },
-            {
-              "StackServiceComponents": {
-                "component_category": "MASTER",
-                "component_name": "GANGLIA_SERVER",
-                "is_client": false,
-                "is_master": true,
-                "service_name": "GANGLIA",
-                "stack_name": "HDP",
-                "stack_version": "2.1"
-              }
-            }
-          ]
-        }
-      ]
-    };
-
-    afterEach(function(){
-      App.StackServiceComponent.find().set('content', []);
-    });
-
-    it('should return 4 components', function(){
-      expect(component.loadStackServiceComponentModel(data).items.length).to.eql(4);
-    });
-
-    it('should load data to StackServiceComponent model', function(){
-      component.loadStackServiceComponentModel(data);
-      expect(App.StackServiceComponent.find().get('content')).have.length(4);
-    });
-  });
 });
 });

+ 86 - 0
ambari-web/test/utils/helper_test.js

@@ -204,6 +204,92 @@ describe('utils/helper', function() {
           });
           });
         });
         });
       });
       });
+      describe('#normalizeName()', function() {
+        var testMessage = '`{0}` should be converted to `{1}`';
+        var tests = {
+          'APP_TIMELINE_SERVER': 'App Timeline Server',
+          'DATANODE': 'DataNode',
+          'DECOMMISSION_DATANODE': 'Update Exclude File',
+          'DRPC_SERVER': 'DRPC Server',
+          'FALCON': 'Falcon',
+          'FALCON_CLIENT': 'Falcon Client',
+          'FALCON_SERVER': 'Falcon Server',
+          'FALCON_SERVICE_CHECK': 'Falcon Service Check',
+          'FLUME_HANDLER': 'Flume Agent',
+          'FLUME_SERVICE_CHECK': 'Flume Service Check',
+          'GANGLIA_MONITOR': 'Ganglia Monitor',
+          'GANGLIA_SERVER': 'Ganglia Server',
+          'GLUSTERFS_CLIENT': 'GLUSTERFS Client',
+          'GLUSTERFS_SERVICE_CHECK': 'GLUSTERFS Service Check',
+          'GMETAD_SERVICE_CHECK': 'Gmetad Service Check',
+          'GMOND_SERVICE_CHECK': 'Gmond Service Check',
+          'HADOOP_CLIENT': 'Hadoop Client',
+          'HBASE_CLIENT': 'HBase Client',
+          'HBASE_MASTER': 'HBase Master',
+          'HBASE_REGIONSERVER': 'RegionServer',
+          'HBASE_SERVICE_CHECK': 'HBase Service Check',
+          'HCAT': 'HCat',
+          'HCAT_SERVICE_CHECK': 'HCat Service Check',
+          'HDFS': 'HDFS',
+          'HDFS_CLIENT': 'HDFS Client',
+          'HDFS_SERVICE_CHECK': 'HDFS Service Check',
+          'HISTORYSERVER': 'History Server',
+          'HIVE_CLIENT': 'Hive Client',
+          'HIVE_METASTORE': 'Hive Metastore',
+          'HIVE_SERVER': 'HiveServer2',
+          'HIVE_SERVICE_CHECK': 'Hive Service Check',
+          'HUE_SERVER': 'Hue Server',
+          'JAVA_JCE': 'Java JCE',
+          'JOBTRACKER': 'JobTracker',
+          'JOBTRACKER_SERVICE_CHECK': 'JobTracker Service Check',
+          'JOURNALNODE': 'JournalNode',
+          'KERBEROS_ADMIN_CLIENT': 'Kerberos Admin Client',
+          'KERBEROS_CLIENT': 'Kerberos Client',
+          'KERBEROS_SERVER': 'Kerberos Server',
+          'MAPREDUCE2_CLIENT': 'MapReduce2 Client',
+          'MAPREDUCE2_SERVICE_CHECK': 'MapReduce2 Service Check',
+          'MAPREDUCE_CLIENT': 'MapReduce Client',
+          'MAPREDUCE_SERVICE_CHECK': 'MapReduce Service Check',
+          'MYSQL_SERVER': 'MySQL Server',
+          'NAGIOS_SERVER': 'Nagios Server',
+          'NAMENODE': 'NameNode',
+          'NAMENODE_SERVICE_CHECK': 'NameNode Service Check',
+          'NIMBUS': 'Nimbus',
+          'NODEMANAGER': 'NodeManager',
+          'OOZIE_CLIENT': 'Oozie Client',
+          'OOZIE_SERVER': 'Oozie Server',
+          'OOZIE_SERVICE_CHECK': 'Oozie Service Check',
+          'PIG': 'Pig',
+          'PIG_SERVICE_CHECK': 'Pig Service Check',
+          'RESOURCEMANAGER': 'ResourceManager',
+          'SECONDARY_NAMENODE': 'SNameNode',
+          'SQOOP': 'Sqoop',
+          'SQOOP_SERVICE_CHECK': 'Sqoop Service Check',
+          'STORM_REST_API': 'Storm REST API Server',
+          'STORM_SERVICE_CHECK': 'Storm Service Check',
+          'STORM_UI_SERVER': 'Storm UI Server',
+          'SUPERVISOR': 'Supervisor',
+          'TASKTRACKER': 'TaskTracker',
+          'TEZ_CLIENT': 'Tez Client',
+          'WEBHCAT_SERVER': 'WebHCat Server',
+          'WEBHCAT_SERVICE_CHECK': 'WebHCat Service Check',
+          'YARN_CLIENT': 'YARN Client',
+          'YARN_SERVICE_CHECK': 'YARN Service Check',
+          'ZKFC': 'ZKFailoverController',
+          'ZOOKEEPER_CLIENT': 'ZooKeeper Client',
+          'ZOOKEEPER_QUORUM_SERVICE_CHECK': 'ZK Quorum Service Check',
+          'ZOOKEEPER_SERVER': 'ZooKeeper Server',
+          'ZOOKEEPER_SERVICE_CHECK': 'ZooKeeper Service Check',
+          'CLIENT': 'Client'
+        };
+        for (var inputName in tests) {
+          (function(name) {
+            it(testMessage.format(name, tests[name]), function() {
+              expect(App.format.normalizeName(name)).to.eql(tests[name]);
+            });
+          })(inputName)
+        }
+      });
     });
     });
   });
   });
   describe('#App.permit()', function() {
   describe('#App.permit()', function() {

+ 3 - 1
ambari-web/test/views/wizard/step5_view_test.js

@@ -52,6 +52,7 @@ describe('App.WizardStep5View', function() {
 });
 });
 
 
 describe('App.SelectHostView', function() {
 describe('App.SelectHostView', function() {
+  var models = require('test/init_model_test');
 
 
   beforeEach(function() {
   beforeEach(function() {
     view = App.SelectHostView.create({
     view = App.SelectHostView.create({
@@ -65,17 +66,18 @@ describe('App.SelectHostView', function() {
 
 
     beforeEach(function() {
     beforeEach(function() {
       sinon.stub(view, 'initContent', Em.K);
       sinon.stub(view, 'initContent', Em.K);
+      models.setupStackServiceComponent();
     });
     });
 
 
     afterEach(function() {
     afterEach(function() {
       view.initContent.restore();
       view.initContent.restore();
+      models.cleanStackServiceComponent();
     });
     });
 
 
     it('should call initContent', function() {
     it('should call initContent', function() {
       view.click();
       view.click();
       expect(view.initContent.calledOnce).to.be.true;
       expect(view.initContent.calledOnce).to.be.true;
     });
     });
-
   });
   });
 
 
   describe('#didInsertElement', function() {
   describe('#didInsertElement', function() {

Some files were not shown because too many files changed in this diff