You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2012/12/09 16:05:21 UTC

svn commit: r1419001 - in /incubator/ambari/branches/AMBARI-666: ./ ambari-web/app/controllers/ ambari-web/app/controllers/wizard/ ambari-web/app/models/ ambari-web/app/routes/ ambari-web/app/templates/wizard/ ambari-web/app/utils/ ambari-web/app/views...

Author: yusaku
Date: Sun Dec  9 15:05:19 2012
New Revision: 1419001

URL: http://svn.apache.org/viewvc?rev=1419001&view=rev
Log:
AMBARI-1048. Integrate slave configuration parameters with respective service on step7 of installer wizard. (Jaimin Jetly via yusaku)

Modified:
    incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt
    incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer.js
    incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/slave_component_groups_controller.js
    incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step3_controller.js
    incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step7_controller.js
    incubator/ambari/branches/AMBARI-666/ambari-web/app/models/service_config.js
    incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js
    incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/slave_component_hosts.hbs
    incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/slave_hosts.hbs
    incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step7.hbs
    incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/db.js
    incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/controls_view.js
    incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/step7_view.js

Modified: incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt (original)
+++ incubator/ambari/branches/AMBARI-666/AMBARI-666-CHANGES.txt Sun Dec  9 15:05:19 2012
@@ -12,6 +12,9 @@ AMBARI-666 branch (unreleased changes)
 
   NEW FEATURES
 
+  AMBARI-1048. Integrate slave configuration parameters with respective
+  service on step7 of installer wizard. (Jaimin Jetly via yusaku)
+
   AMBARI-1031. Check for host registration at step3 of installer wizard 
   and retrieve information for RAM and no. of cores. (Jaimin Jetly via
   yusaku)

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer.js?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/installer.js Sun Dec  9 15:05:19 2012
@@ -34,6 +34,7 @@ App.InstallerController = App.WizardCont
     masterComponentHosts: null,
     serviceConfigProperties: null,
     advancedServiceConfig: null,
+    slaveGroupProperties: null,
     controllerName: 'installerController'
   }),
 
@@ -135,7 +136,7 @@ App.InstallerController = App.WizardCont
       hostsInfo.localRepo = false;
       hostsInfo.localRepoPath = '';
     }
-    hostsInfo.bootRequestId =  App.db.getBootRequestId() || null;
+    hostsInfo.bootRequestId = App.db.getBootRequestId() || null;
     hostsInfo.sshKey = '';
     hostsInfo.passphrase = '';
     hostsInfo.confirmPassphrase = '';
@@ -255,7 +256,8 @@ App.InstallerController = App.WizardCont
       servicesInfo[index].isInstalled = false;
     });
     this.set('content.services', servicesInfo);
-    console.log('installerController.loadServices: loaded data ', servicesInfo);
+    console.log('installerController.loadServices: loaded data ', JSON.stringify(servicesInfo));
+    console.log("The type odf serviceInfo: " + typeof servicesInfo);
     console.log('selected services ', servicesInfo.filterProperty('isSelected', true).mapProperty('serviceName'));
   },
 
@@ -308,7 +310,7 @@ App.InstallerController = App.WizardCont
 
   /**
    * Save slaveHostComponents to main controller
-   * @param stepController
+   * @param stepController called at the submission of step6
    */
   saveSlaveComponentHosts: function (stepController) {
 
@@ -420,6 +422,21 @@ App.InstallerController = App.WizardCont
 
     App.db.setServiceConfigProperties(serviceConfigProperties);
     this.set('content.serviceConfigProperties', serviceConfigProperties);
+
+    var slaveConfigProperties = [];
+    stepController.get('stepConfigs').forEach(function (_content) {
+      if (_content.get('configCategories').someProperty('isForSlaveComponent', true)) {
+        var slaveCategory = _content.get('configCategories').findProperty('isForSlaveComponent', true);
+        slaveCategory.get('slaveConfigs.groups').forEach(function (_group) {
+          _group.get('properties').forEach(function (_property) {
+            _property.set('storeValue', _property.get('value'));
+          }, this);
+        }, this);
+        slaveConfigProperties.pushObject(slaveCategory.get('slaveConfigs'));
+      }
+    }, this)
+    App.db.setSlaveProperties(slaveConfigProperties);
+    this.set('content.slaveGroupProperties', slaveConfigProperties);
   },
 
   /**
@@ -434,6 +451,33 @@ App.InstallerController = App.WizardCont
   },
 
   /**
+   * Load properties for group of slaves to model
+   */
+  loadSlaveGroupProperties: function () {
+    var groupConfigProperties = App.db.getSlaveProperties() ? App.db.getSlaveProperties() : this.get('content.slaveComponentHosts');
+    if (groupConfigProperties) {
+      groupConfigProperties.forEach(function (_slaveComponentObj) {
+        if (_slaveComponentObj.groups) {
+          var groups = [];
+          _slaveComponentObj.groups.forEach(function (_group) {
+            var properties = [];
+            _group.properties.forEach(function (_property) {
+              var property = App.ServiceConfigProperty.create(_property);
+              property.set('value', _property.storeValue);
+              properties.pushObject(property);
+            }, this);
+            _group.properties = properties;
+            groups.pushObject(App.Group.create(_group));
+          }, this);
+          _slaveComponentObj.groups = groups;
+        }
+      }, this);
+    }
+    this.set('content.slaveGroupProperties', groupConfigProperties);
+  },
+
+
+  /**
    * Load information about hosts with clients components
    */
   loadClients: function () {
@@ -477,6 +521,7 @@ App.InstallerController = App.WizardCont
       case '8':
       case '7':
         this.loadServiceConfigProperties();
+        this.loadSlaveGroupProperties();
       case '6':
         this.loadSlaveComponentHosts();
         this.loadClients();
@@ -498,7 +543,7 @@ App.InstallerController = App.WizardCont
    * Generate serviceComponents as pr the stack definition  and save it to localdata
    * called form stepController step4WizardController
    */
-  loadServiceComponents : function (stepController, displayOrderConfig, apiUrl) {
+  loadServiceComponents: function (stepController, displayOrderConfig, apiUrl) {
     var self = this;
     var method = 'GET';
     var testUrl = '/data/wizard/stack/hdp/version/1.2.0.json';
@@ -520,8 +565,8 @@ App.InstallerController = App.WizardCont
           displayName: null,
           isDisabled: true,
           isSelected: true,
-          description:null,
-          version:null
+          description: null,
+          version: null
         });
 
         var data = [];
@@ -533,7 +578,7 @@ App.InstallerController = App.WizardCont
           var myService = Service.create({
             serviceName: entry.name,
             displayName: displayOrderConfig[i].displayName,
-            isDisabled: i === 0 ,
+            isDisabled: i === 0,
             isSelected: true,
             isHidden: displayOrderConfig[i].isHidden,
             description: entry.comment,
@@ -611,7 +656,7 @@ App.InstallerController = App.WizardCont
    * called form stepController step8WizardController or step9WizardController
    */
   installServices: function (isRetry) {
-    if(!isRetry && this.get('content.cluster.requestId')){
+    if (!isRetry && this.get('content.cluster.requestId')) {
       return;
     }
 
@@ -653,11 +698,11 @@ App.InstallerController = App.WizardCont
         console.log("TRACE: value of the url is: " + url);
         console.log("TRACE: error code status is: " + request.status);
         console.log('Error message is: ' + request.responseText);
-          var clusterStatus = {
-            status: 'PENDING',
-            isInstallError: false,
-            isCompleted: false
-          };
+        var clusterStatus = {
+          status: 'PENDING',
+          isInstallError: false,
+          isCompleted: false
+        };
 
         self.saveClusterStatus(clusterStatus);
       },

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/slave_component_groups_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/slave_component_groups_controller.js?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/slave_component_groups_controller.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/slave_component_groups_controller.js Sun Dec  9 15:05:19 2012
@@ -20,68 +20,144 @@ var App = require('app');
  * Used to manage slave component config. User could create different settings for separate group
  * @type {*}
  */
-App.SlaveComponentGroupsController = Em.ArrayController.extend({
+App.SlaveComponentGroupsController = Em.Controller.extend({
 
   name: 'slaveComponentGroupsController',
 
   contentBinding: 'App.router.wizardStep7Controller.slaveComponentHosts',
 
+  stepConfigsBinding: 'App.router.wizardStep7Controller.stepConfigs',
+
   serviceBinding: 'App.router.wizardStep7Controller.selectedService',
 
+  servicesBinding: 'App.router.wizardStep7Controller.content.services',
+
+  clearStep: function () {
+
+  },
+
+  loadStep: function () {
+    this.clearStep();
+    this.loadGroups();
+  },
+
+  loadGroups: function () {
+
+    this.get('stepConfigs').forEach(function (_serviceConfig) {
+      var categoryConfig = _serviceConfig.get('configCategories');
+      if (categoryConfig.someProperty('isForSlaveComponent', true)) {
+        var slaveCategory = categoryConfig.findProperty('isForSlaveComponent', true);
+        if (this.get('content')) {
+          if (this.get('content').someProperty('componentName', slaveCategory.get('name').toUpperCase())) {
+            var component = this.get('content').findProperty('componentName', slaveCategory.get('name').toUpperCase());
+            var slaveConfigs = slaveCategory.get('slaveConfigs');
+            slaveCategory.set('slaveConfigs', component);
+            var slaveGroups = [];
+            if (component.groups) {
+              component.groups.forEach(function (_group) {
+                slaveGroups.pushObject(_group);
+              }, this);
+              slaveCategory.set('slaveConfigs.groups', slaveGroups);
+            }
+            slaveCategory.set('slaveConfigs.componentName', component.componentName);
+            slaveCategory.set('slaveConfigs.displayName', component.displayName);
+            /*slaveCategory.set('slaveConfigs.groups.name', component.get('name'));
+             slaveCategory.set('slaveConfigs.groups.index', component.get('index'));
+             slaveCategory.set('slaveConfigs.groups.type', component.get('type'));
+             slaveCategory.set('slaveConfigs.groups.active', component.get('active'));*/
+            if (!slaveCategory.get('slaveConfigs.groups')) {
+              slaveCategory.set('slaveConfigs.groups', []);
+              var componentProperties = this.componentProperties(_serviceConfig.serviceName);
+              var defaultGroup = {name: 'Default', index: 'default', type: 'default', active: true, properties: componentProperties};
+              slaveCategory.get('slaveConfigs.groups').pushObject(App.Group.create(defaultGroup));
+            }
+          }
+        }
+      }
+    }, this);
+    debugger;
+  },
+
+  componentProperties: function (serviceName) {
+
+    var serviceConfigs = require('data/service_configs').findProperty('serviceName', serviceName);
+
+    var configs = [];
+    var componentName = null;
+    switch (serviceName) {
+      case 'HDFS':
+        componentName = 'DataNode';
+        break;
+      case 'MAPREDUCE':
+        componentName = 'TaskTracker';
+        break;
+      case 'HBASE':
+        componentName = 'RegionServer';
+    }
+    var slaveConfigs = serviceConfigs.configs.filterProperty('category', componentName);
+    slaveConfigs.forEach(function (_serviceConfigProperty) {
+      var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);
+      configs.pushObject(serviceConfigProperty);
+      serviceConfigProperty.validate();
+    }, this);
+    return configs;
+  },
+
   selectedComponentName: function () {
     switch (App.router.get('wizardStep7Controller.selectedService.serviceName')) {
       case 'HDFS':
-        return 'DATANODE';
+        return { name: 'DATANODE',
+          displayName: 'DataNode'};
       case 'MAPREDUCE':
-        return 'TASKTRACKER';
+        return { name: 'TASKTRACKER',
+          displayName: 'TaskTracker'};
+
       case 'HBASE':
-        return 'HBASE_REGIONSERVER';
+        return { name: 'HBASE_REGIONSERVER',
+          displayName: 'RegionServer'};
       default:
         return null;
     }
 
   }.property('App.router.wizardStep7Controller.selectedService'),
 
-  selectedComponentDisplayName: function() {
-    return App.format.role(this.get('selectedComponentName'));
+  selectedComponentDisplayName: function () {
+    return App.format.role(this.get('selectedComponentName').name);
   }.property('selectedComponentName'),
 
   selectedSlaveComponent: function () {
-    var selectedComponentName = this.get('selectedComponentName');
-    if (selectedComponentName) {
-      return this.findProperty('componentName', selectedComponentName);
-    }
-  }.property('selectedComponentName'),
+    var selectedComponentName = this.get('selectedComponentName').displayName;
+    var configs = null;
+    this.get('stepConfigs').forEach(function (_serviceConfig) {
+      var categoryConfig = _serviceConfig.get('configCategories');
+      if (categoryConfig.someProperty('name', selectedComponentName)) {
+        configs = categoryConfig.findProperty('name', selectedComponentName).get('slaveConfigs');
+      }
+    }, this);
+    debugger;
+    return configs;
+  }.property('selectedComponentName', 'stepConfigs.@each.configCategories','stepConfigs.@each.configCategories.@each.slaveConfigs'),
 
   hosts: function () {
-    var selectedComponentName = this.get('selectedComponentName');
-    if (selectedComponentName) {
-      var component = this.findProperty('componentName', selectedComponentName);
-      if(component){
-        return component.hosts;
-      }
+    if (this.get('selectedSlaveComponent')) {
+      return this.get('selectedSlaveComponent').hosts;
     }
-  }.property('@each.hosts', 'selectedComponentName'),
+  }.property('selectedSlaveComponent'),
 
   groups: function () {
     var hosts = this.get('hosts');
-    if(hosts){
+    if (hosts) {
       return hosts.mapProperty('group').uniq();
     }
   }.property('hosts'),
 
   componentGroups: function () {
     var component = this.get('selectedSlaveComponent');
-    if(component){
-        if (!component.groups) {
-          component.groups = [];
-          var defaultGroup = {name: 'Default', index: 'default', type: 'default', active: true};
-          component.groups.pushObject(defaultGroup);
-        }
-        return component.groups;
+    if (component && component.groups) {
+      return component.groups;
     }
     return [];
-  }.property('selectedSlaveComponent'),
+  }.property('selectedSlaveComponent', 'selectedSlaveComponent.groups','stepConfigs.@each'),
 
   getGroupsForDropDown: function () {
     return this.get('componentGroups').getEach('name');
@@ -91,7 +167,7 @@ App.SlaveComponentGroupsController = Em.
     var componentGroups = this.get('componentGroups');
     if (componentGroups) {
       var active = componentGroups.findProperty('active', true);
-      if (active){
+      if (active) {
         return active;
       }
     }
@@ -159,7 +235,7 @@ App.SlaveComponentGroupsController = Em.
     var newGroupName = 'New Group';
     component.groups.setEach('active', false);
     var newGroups = component.groups.filterProperty('name', newGroupName);
-    if (newGroups.length === 0){
+    if (newGroups.length === 0) {
       component.newGroupIndex = 0;
     }
     else {
@@ -167,8 +243,8 @@ App.SlaveComponentGroupsController = Em.
       this.checkGroupName();
       newGroupName = 'New Group ' + component.newGroupIndex;
     }
-    var newGroup = {name: newGroupName, index: component.newGroupIndex, type: 'new', active: true};
-    component.groups.pushObject(newGroup);
+    var newGroup = {name: newGroupName, index: component.newGroupIndex, type: 'new', active: true, properties: this.componentProperties(App.router.get('wizardStep7Controller.selectedService.serviceName'))};
+    component.groups.pushObject(App.Group.create(newGroup));
     $('.remove-group-error').hide();
   },
 
@@ -192,7 +268,7 @@ App.SlaveComponentGroupsController = Em.
 
   getHostsByGroup: function (group) {
     var hosts = this.get('hosts');
-    if(hosts){
+    if (hosts) {
       return hosts.filterProperty('group', group.name);
     }
   },
@@ -203,8 +279,7 @@ App.SlaveComponentGroupsController = Em.
    */
   showSlaveComponentGroup: function (event) {
     var component = this.get('selectedSlaveComponent');
-    if(!component.groups){
-      debugger;
+    if (!component.groups) {
     }
     component.groups.setEach('active', false);
     var group = component.groups.filterProperty('name', event.context.name);
@@ -260,7 +335,7 @@ App.SlaveComponentGroupsController = Em.
       return true;
     else {
       var assignedHosts = component.hosts.filterProperty('group', group.name);
-      if (assignedHosts.length !== 0){
+      if (assignedHosts.length !== 0) {
         assignedHosts.setEach('group', newGroupName);
       }
       var groupFilter = component.groups.filterProperty('name', group.name);
@@ -268,5 +343,4 @@ App.SlaveComponentGroupsController = Em.
     }
     return false;
   }
-
 });

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step3_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step3_controller.js?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step3_controller.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step3_controller.js Sun Dec  9 15:05:19 2012
@@ -44,6 +44,15 @@ App.WizardStep3Controller = Em.Controlle
 
   navigateStep: function () {
     this.loadStep();
+    if (App.testMode && App.skipBootstrap) {
+      this.get('hosts').forEach(function (_host) {
+        _host.set('bootStatus', 'REGISTERED');
+        _host.set('bootLog', 'Success');
+      }, this);
+      this.set('bootHosts', this.get('hosts'));
+      this.stopRegistration();
+      return;
+    }
     if (this.get('content.hosts.manualInstall') !== true) {
       if (App.db.getBootStatus() === false) {
         this.startBootstrap();
@@ -245,7 +254,7 @@ App.WizardStep3Controller = Em.Controlle
     //TODO: uncomment following line after the hook up with the API call
     console.log('stopBootstrap() called');
     // this.set('isSubmitDisabled',false);
-    Ember.run.later(this, function(){
+    Ember.run.later(this, function () {
       this.startRegistration();
     }, 1000);
   },
@@ -403,7 +412,7 @@ App.WizardStep3Controller = Em.Controlle
           var self = this;
           var button = $(this.get('element')).find('.textTrigger');
           button.click(function () {
-            if(self.get('isTextArea')){
+            if (self.get('isTextArea')) {
               $(this).text('click to highlight');
             } else {
               $(this).text('press CTRL+C');
@@ -424,7 +433,7 @@ App.WizardStep3Controller = Em.Controlle
         },
         isTextArea: false,
         textArea: Em.TextArea.extend({
-          didInsertElement: function(){
+          didInsertElement: function () {
             var element = $(this.get('element'));
             element.width($(this.get('parentView').get('element')).width() - 10);
             element.height($(this.get('parentView').get('element')).height());

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step7_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step7_controller.js?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step7_controller.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/controllers/wizard/step7_controller.js Sun Dec  9 15:05:19 2012
@@ -40,7 +40,7 @@ App.WizardStep7Controller = Em.Controlle
 
   isSubmitDisabled: function () {
     return !this.stepConfigs.everyProperty('errorCount', 0);
-  }.property('stepConfigs.@each.errorCount'),
+  }.property('stepConfigs.@each.errorCount','content.slaveGroupProperties.@each.groups.@each.errorCount'),
 
   selectedServiceNames: function () {
     return this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false).mapProperty('serviceName');
@@ -51,8 +51,8 @@ App.WizardStep7Controller = Em.Controlle
   }.property('content.masterComponentHosts'),
 
   slaveComponentHosts: function () {
-    return this.get('content.slaveComponentHosts');
-  }.property('content.slaveComponentHosts'),
+    return this.get('content.slaveGroupProperties');
+  }.property('content.slaveGroupProperties','content.slaveComponentHosts'),
 
   serviceConfigs: require('data/service_configs'),
   configMapping: require('data/config_mapping'),
@@ -118,7 +118,6 @@ App.WizardStep7Controller = Em.Controlle
     }
   },
 
-
   /**
    * Render a custom conf-site box for entering properties that will be written in *-site.xml files of the services
    */

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/models/service_config.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/models/service_config.js?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/models/service_config.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/models/service_config.js Sun Dec  9 15:05:19 2012
@@ -29,12 +29,18 @@ App.ServiceConfig = Ember.Object.extend(
   configs: null,
 
   errorCount: function () {
-    return this.get('configs').filterProperty('isValid', false).filterProperty('isVisible', true).get('length');
-  }.property('configs.@each.isValid', 'configs.@each.isVisible')
+    var masterErrors = this.get('configs').filterProperty('isValid', false).filterProperty('isVisible', true).get('length');
+    var slaveErrors = 0;
+    this.get('configCategories').forEach(function(_category){
+    slaveErrors += _category.get('slaveErrorCount');
+    },this);
+    return masterErrors + slaveErrors;
+  }.property('configs.@each.isValid', 'configs.@each.isVisible', 'configCategories.@each.slaveErrorCount')
 });
 
 App.ServiceConfigCategory = Ember.Object.extend({
   name: null,
+  slaveConfigs: null,
 
   isForMasterComponent: function () {
     var masterServices = [ 'NameNode', 'SNameNode', 'JobTracker', 'HBase Master', 'Oozie Master',
@@ -46,9 +52,31 @@ App.ServiceConfigCategory = Ember.Object
   isForSlaveComponent: function () {
     return this.get('name') === 'DataNode' || this.get('name') === 'TaskTracker' ||
       this.get('name') === 'RegionServer';
-  }.property('name')
+  }.property('name'),
+
+  slaveErrorCount: function () {
+    var length = 0;
+    if (this.get('slaveConfigs.groups')) {
+      this.get('slaveConfigs.groups').forEach(function (_group) {
+        length += _group.get('errorCount');
+      }, this);
+    }
+    return length;
+  }.property('slaveConfigs.groups.@each.errorCount')
 });
 
+App.Group = Ember.Object.extend({
+  name: null,
+  hostNames: null,
+  properties: null,
+  errorCount: function () {
+    if (this.get('properties')) {
+      return this.get('properties').filterProperty('isValid', false).filterProperty('isVisible', true).get('length');
+    }
+  }.property('properties.@each.isValid', 'properties.@each.isVisible')
+});
+
+
 App.ServiceConfigProperty = Ember.Object.extend({
 
   id: '', //either 'puppet var' or 'site property'

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js Sun Dec  9 15:05:19 2012
@@ -221,6 +221,7 @@ module.exports = Em.Route.extend({
         controller.saveSlaveComponentHosts(wizardStep6Controller);
         controller.get('content').set('serviceConfigProperties', null);
         App.db.setServiceConfigProperties(null);
+        App.db.setSlaveProperties(null);
         controller.loadAdvancedConfigs();
         router.transitionTo('step7');
       }
@@ -229,10 +230,14 @@ module.exports = Em.Route.extend({
 
   step7: Em.Route.extend({
     route: '/step7',
-    connectOutlets: function (router, context) {
+    enter: function (router) {
+      console.log('in /wizardStep7Controller:enter');
       var controller = router.get('installerController');
       controller.setCurrentStep('7', false);
       controller.loadAllPriorSteps();
+    },
+    connectOutlets: function (router, context) {
+      var controller = router.get('installerController');
       controller.connectOutlet('wizardStep7', controller.get('content'));
     },
     back: Em.Router.transitionTo('step6'),
@@ -257,7 +262,7 @@ module.exports = Em.Route.extend({
     next: function (router) {
       var installerController = router.get('installerController');
       var wizardStep8Controller = router.get('wizardStep8Controller');
-      installerController.installServices();   //TODO: Uncomment for the actual hookup
+      installerController.installServices();
       installerController.setInfoForStep9();
       router.transitionTo('step9');
     }

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/slave_component_hosts.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/slave_component_hosts.hbs?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/slave_component_hosts.hbs (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/slave_component_hosts.hbs Sun Dec  9 15:05:19 2012
@@ -23,11 +23,10 @@
   </a>
 {{else}}
   <a href="#" {{action showEditSlaveComponentGroups view.serviceConfig.category target="controller"}}>
-    {{#if view.hasOneHost}}
-      {{view.hosts.firstObject.hostName}}
-    {{/if}}
     {{#if view.hasMultipleHosts}}
-      {{view.hosts.firstObject.hostName}} and {{view.otherLength}}
+    {{view.hosts.firstObject.hostName}} and {{view.otherLength}}
+    {{else}}
+    {{view.hosts.firstObject.hostName}}
     {{/if}}
   </a>
 {{/if}}

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/slave_hosts.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/slave_hosts.hbs?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/slave_hosts.hbs (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/slave_hosts.hbs Sun Dec  9 15:05:19 2012
@@ -17,14 +17,13 @@
 }}
 
 {{#if view.hasNoHosts}}
-  No host assigned
+No host assigned
 {{else}}
-  <a href="#" {{action showEditSlaveComponentGroups view.serviceConfig.category target="controller"}}>
-    {{#if view.hasOneHost}}
-      {{hosts.firstObject.hostName}}
-    {{/if}}
-    {{#if view.hasMultipleHosts}}
-      {{hosts.firstObject.hostName}} and {{view.otherLength}}
-    {{/if}}
-  </a>
+<a href="#" {{action showEditSlaveComponentGroups view.serviceConfig.category target="controller"}}>
+  {{#if view.hasMultipleHosts}}
+  {{hosts.firstObject.hostName}} and {{view.otherLength}}
+  {{else}}
+  {{hosts.firstObject.hostName}}
+  {{/if}}
+</a>
 {{/if}}

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step7.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step7.hbs?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step7.hbs (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/templates/wizard/step7.hbs Sun Dec  9 15:05:19 2012
@@ -25,12 +25,12 @@
 
   <ul class="nav nav-tabs">
     {{#each service in controller.stepConfigs}}
-      {{#view App.WizardStep7.ServiceConfigTab}}
-        <a class="active" href="#{{unbound service.serviceName}}"
-           data-toggle="tab" {{action selectService service target="view"}}>
-          {{service.displayName}}{{#if service.errorCount}}<span
-          class="badge badge-important">{{service.errorCount}}</span>{{/if}}</a>
-      {{/view}}
+    {{#view App.WizardStep7.ServiceConfigTab}}
+    <a class="active" href="#{{unbound service.serviceName}}"
+       data-toggle="tab" {{action selectService service target="view"}}>
+      {{service.displayName}}{{#if service.errorCount}}<span
+      class="badge badge-important">{{service.errorCount}}</span>{{/if}}</a>
+    {{/view}}
     {{/each}}
   </ul>
 
@@ -49,73 +49,72 @@
       </div>
 
       {{#unless category.isForSlaveComponent}}
-        {{#view App.WizardStep7.ServiceConfigsByCategoryView categoryBinding="category" serviceConfigsBinding="selectedService.configs"}}
-          <form class="form-horizontal">
+      {{#view App.WizardStep7.ServiceConfigsByCategoryView categoryBinding="category" serviceConfigsBinding="selectedService.configs"}}
+      <form class="form-horizontal">
 
-            {{#each view.categoryConfigs}}
-              {{#if isVisible}}
-              <div {{bindAttr class="errorMessage:error: :control-group"}}>
-                <label class="control-label">{{displayName}}</label>
-
-                <div class="controls">
-                  {{view viewClass serviceConfigBinding="this" categoryConfigsBinding="view.categoryConfigs"}}
-                  <span class="help-inline">{{errorMessage}}</span>
-                </div>
-              </div>
-              {{/if}}
-            {{/each}}
+        {{#each view.categoryConfigs}}
+        {{#if isVisible}}
+        <div {{bindAttr class="errorMessage:error: :control-group"}}>
+          <label class="control-label">{{displayName}}</label>
+
+          <div class="controls">
+            {{view viewClass serviceConfigBinding="this" categoryConfigsBinding="view.categoryConfigs"}}
+            <span class="help-inline">{{errorMessage}}</span>
+          </div>
+        </div>
+        {{/if}}
+        {{/each}}
 
-          </form>
-        {{/view}}
+      </form>
+      {{/view}}
       {{/unless}}
 
       {{#if category.isForSlaveComponent}}
-        {{#view App.WizardStep7.ServiceConfigsByCategoryView categoryBinding="category" serviceConfigsBinding="selectedService.configs" controllerBinding="App.router.slaveComponentGroupsController"}}
-            <div class="slave-component-group-menu">
-              {{view App.SlaveComponentGroupsMenu}}
-            </div>
-
-            {{#view App.AddSlaveComponentGroupButton slaveComponentNameBinding="category.name"}}
-            <a
-              class="btn add-slave-component-group btn-large" {{action addSlaveComponentGroup target="controller"}}><i
-              class="icon-plus"></i></a>
-            {{/view}}
-            <div class="remove-group-error control-group warning">
-              <span class="help-inline">You cannot delete this group since there are hosts assigned to it. You must assign them to another group before you can delete this group.</span>
-            </div>
-
-            <form class="form-horizontal">
-
-              {{#view App.SlaveComponentChangeGroupNameView}}
-                <label class="control-label">Group name</label>
-
-                <div class="controls">
-                  <div class="span6">
-                    <input class="span9" type="text" {{bindAttr value="view.content.name"}}>
-                    <button class="btn" {{action changeGroupName target="view"}}>Save</button>
-                  </div>
-                  <span class="help-inline">{{view.errorMessage}}</span>
-                </div>
-              {{/view}}
-
-
-              {{#each view.categoryConfigs}}
-                {{#if isVisible}}
-                <div {{bindAttr class="errorMessage:error: :control-group"}}>
-                  <label class="control-label">{{displayName}}</label>
-
-                  <div class="controls">
-                    {{view viewClass serviceConfigBinding="this" categoryConfigsBinding="view.categoryConfigs"}}
-                    <span class="help-inline">{{errorMessage}}</span>
-                  </div>
-                </div>
-                {{/if}}
-              {{/each}}
+      {{#view App.WizardStep7.ServiceConfigsByCategoryView categoryBinding="category" serviceConfigsBinding="selectedService.configs" controllerBinding="App.router.slaveComponentGroupsController"}}
+      <div class="slave-component-group-menu">
+        {{view App.SlaveComponentGroupsMenu}}
+      </div>
+
+      {{#view App.AddSlaveComponentGroupButton slaveComponentNameBinding="category.name"}}
+      <a
+        class="btn add-slave-component-group btn-large" {{action addSlaveComponentGroup target="controller"}}><i
+        class="icon-plus"></i></a>
+      {{/view}}
+      <div class="remove-group-error control-group warning">
+        <span class="help-inline">You cannot delete this group since there are hosts assigned to it. You must assign them to another group before you can delete this group.</span>
+      </div>
+
+      <form class="form-horizontal">
 
-            </form>
+        {{#view App.SlaveComponentChangeGroupNameView}}
+        <label class="control-label">Group name</label>
 
+        <div class="controls">
+          <div class="span6">
+            <input class="span9"
+                   type="text" {{bindAttr value="view.content.name"}}>
+            <button class="btn" {{action changeGroupName target="view"}}>Save
+            </button>
+          </div>
+          <span class="help-inline">{{view.errorMessage}}</span>
+        </div>
+        {{/view}}
 
+        {{#view App.SlaveGroupPropertiesView}}
+        {{#each view.groupConfigs}}
+        {{#if this.isVisible}}
+        <div {{bindAttr class="errorMessage:error: :control-group"}}>
+          <label class="control-label">{{this.displayName}}</label>
+          <div class="controls">
+            {{view this.viewClass serviceConfigBinding="this"}}
+            <span class="help-inline">{{this.errorMessage}}</span>
+          </div>
+        </div>
+        {{/if}}
+        {{/each}}
         {{/view}}
+      </form>
+      {{/view}}
       {{/if}}
     </div>
     {{/each}}
@@ -128,7 +127,8 @@
   <div class="btn-area">
     <a class="btn" {{action back}}>&larr; Back</a>
 
-    <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
+    <a
+      class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
       {{action submit target="controller"}}>Next &rarr;</a>
   </div>
 </div>

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/db.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/db.js?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/db.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/db.js Sun Dec  9 15:05:19 2012
@@ -51,9 +51,9 @@ App.db.cleanUp = function () {
       'loginName': '',
       'authenticated': false
     },
-    'Installer' : {},
-    'AddHost' : {},
-    'AddService' : {}
+    'Installer': {},
+    'AddHost': {},
+    'AddService': {}
   };
   console.log("In cleanup./..");
   localStorage.setObject('ambari', App.db.data);
@@ -201,7 +201,7 @@ App.db.setServiceConfigs = function (ser
   localStorage.setObject('ambari', App.db.data);
 };
 
-App.db.setAdvancedServiceConfig = function(serviceConfigs) {
+App.db.setAdvancedServiceConfig = function (serviceConfigs) {
   App.db.data = localStorage.getObject('ambari');
   App.db.data.Installer.advanceServiceConfigs = serviceConfigs;
   localStorage.setObject('ambari', App.db.data);
@@ -213,6 +213,12 @@ App.db.setServiceConfigProperties = func
   localStorage.setObject('ambari', App.db.data);
 };
 
+App.db.setSlaveProperties = function (slaveProperties) {
+  App.db.data = localStorage.getObject('ambari');
+  App.db.data.Installer.slaveProperties = slaveProperties;
+  localStorage.setObject('ambari', App.db.data);
+};
+
 App.db.setClusterStatus = function (status) {
   App.db.data = localStorage.getObject('ambari');
   App.db.data.Installer.clusterStatus = status;
@@ -358,7 +364,7 @@ App.db.getServiceConfigs = function () {
   return App.db.data.Installer.serviceConfigs;
 };
 
-App.db.getAdvancedServiceConfig = function() {
+App.db.getAdvancedServiceConfig = function () {
   App.db.data = localStorage.getObject('ambari');
   return App.db.data.Installer.advanceServiceConfigs;
 };
@@ -368,6 +374,12 @@ App.db.getServiceConfigProperties = func
   return App.db.data.Installer.configProperties;
 };
 
+App.db.getSlaveProperties = function () {
+  App.db.data = localStorage.getObject('ambari');
+  return App.db.data.Installer.slaveProperties;
+};
+
+
 App.db.getClusterStatus = function () {
   console.log('TRACE: Entering db:getClusterStatus function');
   App.db.data = localStorage.getObject('ambari');

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/controls_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/controls_view.js?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/controls_view.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/controls_view.js Sun Dec  9 15:05:19 2012
@@ -57,9 +57,9 @@ App.ServiceConfigTextField = Ember.TextF
     // sets the width of the field depending on display type
     if (['directory', 'url', 'email', 'user', 'host'].contains(this.get('serviceConfig.displayType'))) {
       return ['span6'];
-    } else if(this.get('serviceConfig.displayType') === 'advanced'){
+    } else if (this.get('serviceConfig.displayType') === 'advanced') {
       return ['span6'];
-    } else{
+    } else {
       return ['input-small'];
     }
   }.property('serviceConfig.displayType'),
@@ -249,8 +249,8 @@ App.ServiceConfigMultipleHostsDisplay = 
   hasNoHosts: function () {
     console.log('view', this.get('viewName')); //to know which View cause errors
     console.log('controller', this.get('controller').name); //should be slaveComponentGroupsController
-    if(!this.get('value')){
-     // debugger;
+    if (!this.get('value')) {
+      // debugger;
       return true;
     }
     return this.get('value').length === 0;
@@ -283,7 +283,7 @@ App.ServiceConfigMultipleHostsDisplay = 
  */
 App.ServiceConfigMasterHostsView = Ember.View.extend(App.ServiceConfigMultipleHostsDisplay, {
 
-  viewName : "serviceConfigMasterHostsView",
+  viewName: "serviceConfigMasterHostsView",
   valueBinding: 'serviceConfig.value',
 
   classNames: ['master-hosts', 'span6'],
@@ -295,12 +295,12 @@ App.ServiceConfigMasterHostsView = Ember
   showHosts: function () {
     var serviceConfig = this.get('serviceConfig');
     App.ModalPopup.show({
-      header: serviceConfig.  category + ' Hosts',
+      header: serviceConfig.category + ' Hosts',
       bodyClass: Ember.View.extend({
         serviceConfig: serviceConfig,
         templateName: require('templates/wizard/master_hosts_popup')
       }),
-      onPrimary:function(){
+      onPrimary: function () {
         this.hide();
       },
       secondary: null
@@ -315,21 +315,25 @@ App.ServiceConfigMasterHostsView = Ember
  */
 App.SlaveComponentGroupsMenu = Em.CollectionView.extend({
 
-  content: function(){
+  content: function () {
     return this.get('controller.componentGroups');
   }.property('controller.componentGroups'),
 
-  tagName:'ul',
+  tagName: 'ul',
   classNames: ["nav", "nav-tabs"],
 
-  itemViewClass:Em.View.extend({
-    classNameBindings:["active"],
+  itemViewClass: Em.View.extend({
+    classNameBindings: ["active"],
 
-    active:function(){
+    active: function () {
       return this.get('content.active');
     }.property('content.active'),
 
-    template:Ember.Handlebars.compile('<a {{action showSlaveComponentGroup view.content target="controller"}} href="#"> {{view.content.name}}</a><i {{action removeSlaveComponentGroup view.content target="controller"}} class="icon-remove"></i>')
+    errorCount: function () {
+      return this.get('content.properties').filterProperty('isValid', false).filterProperty('isVisible', true).get('length');
+    }.property('content.properties.@each.isValid','content.properties.@each.isVisible'),
+
+    template: Ember.Handlebars.compile('<a {{action showSlaveComponentGroup view.content target="controller"}} href="#"> {{view.content.name}}{{#if view.errorCount}}<span class="badge badge-important">{{view.errorCount}}</span>{{/if}}</a><i {{action removeSlaveComponentGroup view.content target="controller"}} class="icon-remove"></i>')
   })
 });
 
@@ -360,17 +364,17 @@ App.AddSlaveComponentGroupButton = Ember
  */
 App.ServiceConfigSlaveHostsView = Ember.View.extend(App.ServiceConfigMultipleHostsDisplay, {
 
-  viewName : 'serviceConfigSlaveHostsView',
+  viewName: 'serviceConfigSlaveHostsView',
 
   classNames: ['slave-hosts', 'span6'],
   valueBinding: 'hosts',
 
-  group: function(){
+  group: function () {
     return this.get('controller.activeGroup');
   }.property('controller.activeGroup'),
 
-  hosts: function(){
-    if (this.get('group')){
+  hosts: function () {
+    if (this.get('group')) {
       return this.get('controller').getHostsByGroup(this.get('group'))
     }
   }.property('controller.hosts.@each.group', 'group'),
@@ -383,20 +387,44 @@ App.ServiceConfigSlaveHostsView = Ember.
 });
 
 /**
+ * properties for present active slave group
+ * @type {*}
+ */
+App.SlaveGroupPropertiesView = Ember.View.extend({
+
+  viewName: 'serviceConfigSlaveHostsView',
+
+  group: function () {
+    return this.get('controller.activeGroup');
+  }.property('controller.activeGroup'),
+
+  groupConfigs: function () {
+    console.log("************************************************************************");
+    console.log("The value of group is: " + this.get('group'));
+    console.log("************************************************************************");
+    return this.get('group.properties');
+  }.property('group.properties.@each').cacheable(),
+
+  errorCount: function () {
+    return this.get('group.properties').filterProperty('isValid', false).filterProperty('isVisible', true).get('length');
+  }.property('configs.@each.isValid', 'configs.@each.isVisible')
+});
+
+/**
  * DropDown component for <code>select hosts for groups</code> popup
  * @type {*}
  */
 App.SlaveComponentDropDownGroupView = Ember.View.extend({
 
-  viewName : "slaveComponentDropDownGroupView",
+  viewName: "slaveComponentDropDownGroupView",
 
   /**
    * On change handler for <code>select hosts for groups</code> popup
    * @param event
    */
-  changeGroup: function(event) {
+  changeGroup: function (event) {
     var host = this.get('content');
-    var groupName = $('#'+this.get('elementId') + ' select').val();
+    var groupName = $('#' + this.get('elementId') + ' select').val();
     this.get('controller').changeHostGroup(host, groupName);
   },
 
@@ -405,7 +433,7 @@ App.SlaveComponentDropDownGroupView = Em
     /**
      * Whether current value(OptionTag value) equals to host value(assigned to SlaveComponentDropDownGroupView.content)
      */
-    selected: function(){
+    selected: function () {
       return this.get('parentView.content.group') === this.get('content');
     }.property('content')
   })
@@ -421,10 +449,10 @@ App.SlaveComponentChangeGroupNameView = 
   classNames: ['control-group'],
   classNameBindings: 'error',
   error: false,
-  setError: function(){
+  setError: function () {
     this.set('error', false);
   }.observes('controller.activeGroup'),
-  errorMessage: function(){
+  errorMessage: function () {
     return this.get('error') ? 'group with this name already exist' : '';
   }.property('error'),
 
@@ -432,9 +460,9 @@ App.SlaveComponentChangeGroupNameView = 
    * Onclick handler for saving updated group name
    * @param event
    */
-  changeGroupName: function(event) {
-    var inputVal = $('#'+this.get('elementId') + ' input[type="text"]').val();
-    if (inputVal !== this.get('content.name')){
+  changeGroupName: function (event) {
+    var inputVal = $('#' + this.get('elementId') + ' input[type="text"]').val();
+    if (inputVal !== this.get('content.name')) {
       var result = this.get('controller').changeSlaveGroupName(this.get('content'), inputVal);
       this.set('error', result);
     }

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/step7_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/step7_view.js?rev=1419001&r1=1419000&r2=1419001&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/step7_view.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/step7_view.js Sun Dec  9 15:05:19 2012
@@ -25,7 +25,9 @@ App.WizardStep7View = Em.View.extend({
 
   didInsertElement: function () {
     var controller = this.get('controller');
+    var slaveController = App.router.get('slaveComponentGroupsController');
     controller.loadStep();
+    slaveController.loadStep();
   },
   onToggleBlock: function(event){
     $(document.getElementById(event.context.name)).toggle('blind', 500);
@@ -58,6 +60,7 @@ App.WizardStep7.ServiceConfigsByCategory
       this.set('category.isCollapsed', false);
     }
   },
+
   layout: Ember.Handlebars.compile('<div {{bindAttr id="view.category.name"}} class="accordion-body collapse in"><div class="accordion-inner">{{yield}}</div></div>')
 });