You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ja...@apache.org on 2013/12/05 19:23:11 UTC

git commit: AMBARI-3837. NameNode HA wizard: Configuration changes should be surfaced on ui. (jaimin)

Updated Branches:
  refs/heads/trunk 796eab5e5 -> bdb466979


AMBARI-3837. NameNode HA wizard: Configuration changes should be surfaced on ui. (jaimin)


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

Branch: refs/heads/trunk
Commit: bdb4669791cf2d29bdaac4db3d478bb27acd80d0
Parents: 796eab5
Author: Jaimin Jetly <ja...@hortonworks.com>
Authored: Thu Dec 5 10:22:44 2013 -0800
Committer: Jaimin Jetly <ja...@hortonworks.com>
Committed: Thu Dec 5 10:22:56 2013 -0800

----------------------------------------------------------------------
 .../admin/highAvailability/step3_controller.js  | 149 ++++++++++++++++++-
 .../admin/highAvailability/step5_controller.js  |  64 +-------
 .../admin/highAvailability/step9_controller.js  |  33 +---
 .../admin/highAvailability/wizard_controller.js |  31 +++-
 ambari-web/app/messages.js                      |  12 +-
 .../app/routes/high_availability_routes.js      |  14 +-
 .../main/admin/highAvailability/step3.hbs       |  38 +++--
 ambari-web/app/utils/helper.js                  |   3 +
 .../main/admin/highAvailability/step3_view.js   |   4 +-
 9 files changed, 235 insertions(+), 113 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/bdb46697/ambari-web/app/controllers/main/admin/highAvailability/step3_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/step3_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/step3_controller.js
index e9fe9bb..c222047 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/step3_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/step3_controller.js
@@ -19,6 +19,153 @@
 var App = require('app');
 
 App.HighAvailabilityWizardStep3Controller = Em.Controller.extend({
-  name:"highAvailabilityWizardStep3Controller"
+  name: "highAvailabilityWizardStep3Controller",
+  selectedService: null,
+  stepConfigs: [],
+  serverConfigData: {},
+  haConfig: $.extend(true, {}, require('data/HDP2/ha_properties').haConfig),
+  once: false,
+
+  clearStep: function () {
+    this.get('stepConfigs').clear();
+    this.serverConfigData = {};
+  },
+
+  loadStep: function () {
+    this.clearStep();
+    this.loadConfigsTags();
+  },
+
+  loadConfigsTags: function () {
+    App.ajax.send({
+      name: 'config.tags',
+      sender: this,
+      success: 'onLoadConfigsTags',
+      error: 'onTaskError'
+    });
+  },
+
+
+  onLoadConfigsTags: function (data) {
+    var urlParams = [];
+    var hdfsSiteTag = data.Clusters.desired_configs['hdfs-site'].tag;
+    var coreSiteTag = data.Clusters.desired_configs['core-site'].tag;
+    urlParams.push('(type=hdfs-site&tag=' + hdfsSiteTag + ')');
+    urlParams.push('(type=core-site&tag=' + coreSiteTag + ')');
+    this.set("hdfsSiteTag", {name : "hdfsSiteTag", value : hdfsSiteTag});
+    this.set("coreSiteTag", {name : "coreSiteTag", value : coreSiteTag});
+
+    if (App.Service.find().someProperty('serviceName', 'HBASE')) {
+      var hbaseSiteTag = data.Clusters.desired_configs['hbase-site'].tag;
+      urlParams.push('(type=hbase-site&tag=' + hbaseSiteTag + ')');
+      this.set("hbaseSiteTag", {name : "hbaseSiteTag", value : hbaseSiteTag});
+    }
+    App.ajax.send({
+      name: 'admin.get.all_configurations',
+      sender: this,
+      data: {
+        urlParams: urlParams.join('|')
+      },
+      success: 'onLoadConfigs',
+      error: 'onTaskError'
+    });
+  },
+
+  onLoadConfigs: function (data) {
+    this.set('serverConfigData',data);
+    this.tweakServiceConfigs(this.get('haConfig.configs'));
+    this.renderServiceConfigs(this.get('haConfig'));
+  },
+
+
+  tweakServiceConfigs: function(configs) {
+    var nameServiceId = this.get('content.nameServiceId');
+    var nameServiceConfig = configs.findProperty('name','dfs.nameservices');
+    this.setConfigInitialValue(nameServiceConfig,nameServiceId);
+    var defaultFsConfig = configs.findProperty('name','fs.defaultFS');
+    this.setConfigInitialValue(defaultFsConfig, "hdfs://" + nameServiceId);
+    this.tweakServiceConfigNames(configs,nameServiceId);
+    this.tweakServiceConfigValues(configs,nameServiceId);
+  },
+
+  tweakServiceConfigNames: function(configs,nameServiceId) {
+    var regex = new RegExp("\\$\\{dfs.nameservices\\}","g");
+    configs.forEach(function(config) {
+      if (config.name.contains("${dfs.nameservices}")) {
+        config.name = config.name.replace(regex,nameServiceId);
+        config.displayName = config.displayName.replace(regex,nameServiceId);
+      }
+    }, this);
+  },
+
+  tweakServiceConfigValues: function(configs,nameServiceId) {
+    var currentNameNodeHost = this.get('content.masterComponentHosts').findProperty('isCurNameNode').hostName;
+    var newNameNodeHost = this.get('content.masterComponentHosts').findProperty('isAddNameNode').hostName;
+    var journalNodeHosts = this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE').mapProperty('hostName');
+    var zooKeeperHosts = this.get('content.masterComponentHosts').filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName');
+    var config = configs.findProperty('name','dfs.namenode.rpc-address.' + nameServiceId + '.nn1');
+    this.setConfigInitialValue(config,currentNameNodeHost + ':8020');
+    config = configs.findProperty('name','dfs.namenode.rpc-address.' + nameServiceId + '.nn2');
+    this.setConfigInitialValue(config,newNameNodeHost + ':8020');
+    config = configs.findProperty('name','dfs.namenode.http-address.' + nameServiceId + '.nn1');
+    this.setConfigInitialValue(config,currentNameNodeHost + ':50070');
+    config = configs.findProperty('name','dfs.namenode.http-address.' + nameServiceId + '.nn2');
+    this.setConfigInitialValue(config,newNameNodeHost + ':50070');
+    config = configs.findProperty('name','dfs.namenode.https-address.' + nameServiceId + '.nn1');
+    this.setConfigInitialValue(config,currentNameNodeHost + ':50470');
+    config = configs.findProperty('name','dfs.namenode.https-address.' + nameServiceId + '.nn2');
+    this.setConfigInitialValue(config,newNameNodeHost + ':50470');
+    config = configs.findProperty('name','dfs.namenode.shared.edits.dir');
+    this.setConfigInitialValue(config,'qjournal://' + journalNodeHosts[0] + ':8485;' + journalNodeHosts[1] + ':8485;' + journalNodeHosts[2] + ':8485/' + nameServiceId);
+    config = configs.findProperty('name','ha.zookeeper.quorum');
+    this.setConfigInitialValue(config,zooKeeperHosts[0] + ':2181,' + zooKeeperHosts[1] + ':2181,' + zooKeeperHosts[2] + ':2181');
+    config = configs.findProperty('name','hbase.rootdir');
+    if (App.Service.find().someProperty('serviceName', 'HBASE')) {
+     var value = this.get('serverConfigData.items').findProperty('type', 'hbase-site').properties['hbase.rootdir'].replace(/\/\/[^\/]*/, '//' + nameServiceId);
+     this.setConfigInitialValue(config,value);
+    }
+  },
+
+  setConfigInitialValue: function(config,value) {
+    config.value = value;
+    config.defaultValue = value;
+  },
+
+  renderServiceConfigs: function (_serviceConfig) {
+    var serviceConfig = App.ServiceConfig.create({
+      serviceName: _serviceConfig.serviceName,
+      displayName: _serviceConfig.displayName,
+      configCategories: [],
+      showConfig: true,
+      configs: []
+    });
+
+    _serviceConfig.configCategories.forEach(function (_configCategory) {
+      if (App.Service.find().someProperty('serviceName', _configCategory.name)) {
+        serviceConfig.configCategories.pushObject(_configCategory);
+      }
+    }, this);
+
+    this.loadComponentConfigs(_serviceConfig, serviceConfig);
+
+    this.get('stepConfigs').pushObject(serviceConfig);
+    this.set('selectedService', this.get('stepConfigs').objectAt(0));
+    this.once = true;
+  },
+
+  /**
+   * Load child components to service config object
+   * @param _componentConfig
+   * @param componentConfig
+   */
+  loadComponentConfigs: function (_componentConfig, componentConfig) {
+    _componentConfig.configs.forEach(function (_serviceConfigProperty) {
+      var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);
+      componentConfig.configs.pushObject(serviceConfigProperty);
+      serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
+      serviceConfigProperty.validate();
+    }, this);
+  }
+
 });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/bdb46697/ambari-web/app/controllers/main/admin/highAvailability/step5_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/step5_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/step5_controller.js
index 45c8c80..b263277 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/step5_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/step5_controller.js
@@ -24,7 +24,7 @@ App.HighAvailabilityWizardStep5Controller = App.HighAvailabilityProgressPageCont
 
   isHA: true,
 
-  commands: ['stopAllServices', 'installNameNode', 'installJournalNodes', 'startJournalNodes', 'disableSNameNode', 'reconfigureHDFS'],
+  commands: ['stopAllServices', 'installNameNode', 'installJournalNodes', 'reconfigureHDFS', 'startJournalNodes', 'disableSNameNode'],
 
   hdfsSiteTag : "",
   coreSiteTag : "",
@@ -77,63 +77,9 @@ App.HighAvailabilityWizardStep5Controller = App.HighAvailabilityProgressPageCont
   },
 
   reconfigureHDFS: function () {
-    this.loadConfigsTags();
-  },
-
-  loadConfigsTags: function () {
-    App.ajax.send({
-      name: 'config.tags',
-      sender: this,
-      success: 'onLoadConfigsTags',
-      error: 'onTaskError'
-    });
-  },
-
-  onLoadConfigsTags: function (data) {
-    var hdfsSiteTag = data.Clusters.desired_configs['hdfs-site'].tag;
-    var coreSiteTag = data.Clusters.desired_configs['core-site'].tag;
-    this.set("hdfsSiteTag", {name : "hdfsSiteTag", value : hdfsSiteTag});
-    this.set("coreSiteTag", {name : "coreSiteTag", value : coreSiteTag});
-    App.ajax.send({
-      name: 'admin.high_availability.load_configs',
-      sender: this,
-      data: {
-        hdfsSiteTag: hdfsSiteTag,
-        coreSiteTag: coreSiteTag
-      },
-      success: 'onLoadConfigs',
-      error: 'onTaskError'
-    });
-  },
-
-  onLoadConfigs: function (data) {
+    var data = this.get('content.serviceConfigProperties');
     var hdfsSiteProperties = data.items.findProperty('type', 'hdfs-site').properties;
     var coreSiteProperties = data.items.findProperty('type', 'core-site').properties;
-
-    var currentNameNodeHost = this.get('content.masterComponentHosts').findProperty('isCurNameNode').hostName;
-    var newNameNodeHost = this.get('content.masterComponentHosts').findProperty('isAddNameNode').hostName;
-    var journalNodeHosts = this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE').mapProperty('hostName');
-    var zooKeeperHosts = this.get('content.masterComponentHosts').filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName');
-    var nameServiceId = this.get('content.nameServiceId');
-
-    //hdfs-site configs changes
-    hdfsSiteProperties['dfs.nameservices'] = nameServiceId;
-    hdfsSiteProperties['dfs.ha.namenodes.' + nameServiceId] = 'nn1,nn2';
-    hdfsSiteProperties['dfs.namenode.rpc-address.' + nameServiceId + '.nn1'] = currentNameNodeHost + ':8020';
-    hdfsSiteProperties['dfs.namenode.rpc-address.' + nameServiceId + '.nn2'] = newNameNodeHost + ':8020';
-    hdfsSiteProperties['dfs.namenode.http-address.' + nameServiceId + '.nn1'] = currentNameNodeHost + ':50070';
-    hdfsSiteProperties['dfs.namenode.http-address.' + nameServiceId + '.nn2'] = newNameNodeHost + ':50070';
-    hdfsSiteProperties['dfs.namenode.https-address.' + nameServiceId + '.nn1'] = currentNameNodeHost + ':50470';
-    hdfsSiteProperties['dfs.namenode.https-address.' + nameServiceId + '.nn2'] = newNameNodeHost + ':50470';
-    hdfsSiteProperties['dfs.namenode.shared.edits.dir'] = 'qjournal://' + journalNodeHosts[0] + ':8485;' + journalNodeHosts[1] + ':8485;' + journalNodeHosts[2] + ':8485/' + nameServiceId;
-    hdfsSiteProperties['dfs.client.failover.proxy.provider.' + nameServiceId] = 'org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider';
-    hdfsSiteProperties['dfs.ha.fencing.methods'] = 'shell(/bin/true)';
-    hdfsSiteProperties['dfs.journalnode.edits.dir'] = '/grid/0/hdfs/journal';
-    hdfsSiteProperties['dfs.ha.automatic-failover.enabled'] = 'true';
-
-    //core-site configs changes
-    coreSiteProperties['ha.zookeeper.quorum'] = zooKeeperHosts[0] + ':2181,' + zooKeeperHosts[1] + ':2181,' + zooKeeperHosts[2] + ':2181';
-    coreSiteProperties['fs.defaultFS'] = 'hdfs://' + nameServiceId;
     this.set('configsSaved', false);
     App.ajax.send({
       name: 'admin.high_availability.save_configs',
@@ -164,10 +110,10 @@ App.HighAvailabilityWizardStep5Controller = App.HighAvailabilityProgressPageCont
       this.set('configsSaved', true);
       return;
     }
-    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'NAMENODE').mapProperty('hostName');
+    var nnHostNames = this.get('content.masterComponentHosts').filterProperty('component', 'NAMENODE').mapProperty('hostName');
+    var jnHostNames = this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE').mapProperty('hostName');
+    var hostNames = $.extend([], nnHostNames, jnHostNames);
     this.createComponent('HDFS_CLIENT', hostNames);
-    App.router.get(this.get('content.controllerName')).saveConfigTag(this.get("hdfsSiteTag"));
-    App.router.get(this.get('content.controllerName')).saveConfigTag(this.get("coreSiteTag"));
     App.router.get(this.get('content.controllerName')).saveHdfsClientHosts(hostNames);
     App.clusterStatus.setClusterStatus({
       clusterName: this.get('content.cluster.name'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/bdb46697/ambari-web/app/controllers/main/admin/highAvailability/step9_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/step9_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/step9_controller.js
index 1670eac..b2f8268 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/step9_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/step9_controller.js
@@ -60,38 +60,8 @@ App.HighAvailabilityWizardStep9Controller = App.HighAvailabilityProgressPageCont
   },
 
   reconfigureHBase: function () {
-    this.loadConfigsTags();
-  },
-
-  loadConfigsTags: function () {
-    App.ajax.send({
-      name: 'config.tags',
-      sender: this,
-      success: 'onLoadConfigsTags',
-      error: 'onTaskError'
-    });
-  },
-
-  onLoadConfigsTags: function (data) {
-    var hbaseSiteTag = data.Clusters.desired_configs['hbase-site'].tag;
-    this.set("hbaseSiteTag", {name : "hbaseSiteTag", value : hbaseSiteTag});
-    App.ajax.send({
-      name: 'admin.high_availability.load_hbase_configs',
-      sender: this,
-      data: {
-        hbaseSiteTag: hbaseSiteTag
-      },
-      success: 'onLoadConfigs',
-      error: 'onTaskError'
-    });
-  },
-
-  onLoadConfigs: function (data) {
+    var data = this.get('content.serviceConfigProperties');
     var hbaseSiteProperties = data.items.findProperty('type', 'hbase-site').properties;
-    var nameServiceId = this.get('content.nameServiceId');
-
-    //hbase-site configs changes
-    hbaseSiteProperties['hbase.rootdir'] = hbaseSiteProperties['hbase.rootdir'].replace(/\/\/[^\/]*/, '//' + nameServiceId);
 
     App.ajax.send({
       name: 'admin.high_availability.save_configs',
@@ -106,7 +76,6 @@ App.HighAvailabilityWizardStep9Controller = App.HighAvailabilityProgressPageCont
   },
 
   saveConfigTag: function () {
-    App.router.get(this.get('content.controllerName')).saveConfigTag(this.get("hbaseSiteTag"));
     App.clusterStatus.setClusterStatus({
       clusterName: this.get('content.cluster.name'),
       clusterState: 'HIGH_AVAILABILITY_DEPLOY',

http://git-wip-us.apache.org/repos/asf/ambari/blob/bdb46697/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
index e120235..76f5aa0 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/wizard_controller.js
@@ -37,6 +37,7 @@ App.HighAvailabilityWizardController = App.WizardController.extend({
     services: null,
     slaveComponentHosts: null,
     masterComponentHosts: null,
+    serviceConfigProperties: [],
     serviceName: 'MISC',
     hdfsUser:"hdfs",
     nameServiceId: '',
@@ -183,6 +184,25 @@ App.HighAvailabilityWizardController = App.WizardController.extend({
     this.set('content.hdfsClientHostNames', hostNames);
   },
 
+    /**
+     * Save config properties
+     * @param stepController HighAvailabilityWizardStep3Controller
+     */
+  saveServiceConfigProperties: function(stepController) {
+    var serviceConfigProperties = [];
+    var data = stepController.get('serverConfigData');
+
+    var _content = stepController.get('stepConfigs')[0];
+    _content.get('configs').forEach(function (_configProperties) {
+      var siteObj = data.items.findProperty('type', _configProperties.get('filename'));
+      if (siteObj) {
+        siteObj.properties[_configProperties.get('name')] = _configProperties.get('value');
+      }
+    }, this);
+    this.setDBProperty('serviceConfigProperties', data);
+    this.set('content.serviceConfigProperties', data);
+  },
+
   loadHdfsClientHosts: function(){
     var hostNames = App.db.getHighAvailabilityWizardHdfsClientHosts();
     if (!(hostNames instanceof Array)) {
@@ -207,6 +227,14 @@ App.HighAvailabilityWizardController = App.WizardController.extend({
     this.set('content.tasksStatuses', statuses);
   },
 
+  /**
+   * Load serviceConfigProperties to model
+   */
+  loadServiceConfigProperties: function () {
+    var serviceConfigProperties = this.getDBProperty('serviceConfigProperties');
+    this.set('content.serviceConfigProperties', serviceConfigProperties);
+  },
+
   saveRequestIds: function(requestIds){
     App.db.setHighAvailabilityWizardRequestIds(requestIds);
     this.set('content.requestIds', requestIds);
@@ -248,12 +276,13 @@ App.HighAvailabilityWizardController = App.WizardController.extend({
       case '7':
       case '6':
       case '5':
-        this.loadNameServiceId();
         this.loadTasksStatuses();
         this.loadRequestIds();
         this.loadLogs();
       case '4':
       case '3':
+        this.loadNameServiceId();
+        this.loadServiceConfigProperties();
       case '2':
         this.loadServicesFromServer();
         this.loadMasterComponentHosts();

http://git-wip-us.apache.org/repos/asf/ambari/blob/bdb46697/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 2958b10..2e61af6 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -714,9 +714,9 @@ Em.I18n.translations = {
   'admin.highAvailability.wizard.step5.task0.title':'Stop All Services',
   'admin.highAvailability.wizard.step5.task1.title':'Install Additional NameNode',
   'admin.highAvailability.wizard.step5.task2.title':'Install JournalNodes',
-  'admin.highAvailability.wizard.step5.task3.title':'Start JournalNodes',
-  'admin.highAvailability.wizard.step5.task4.title':'Disable Secondary NameNode',
-  'admin.highAvailability.wizard.step5.task5.title':'Reconfigure HDFS',
+  'admin.highAvailability.wizard.step5.task3.title':'Reconfigure HDFS',
+  'admin.highAvailability.wizard.step5.task4.title':'Start JournalNodes',
+  'admin.highAvailability.wizard.step5.task5.title':'Disable Secondary NameNode',
 
   'admin.highAvailability.wizard.step7.task0.title':'Start ZooKeeper Servers',
   'admin.highAvailability.wizard.step7.task1.title':'Start NameNode',
@@ -800,7 +800,11 @@ Em.I18n.translations = {
     '<li>You will be able to proceed once Ambari detects that the NameNode is in Safe Mode and the Checkpoint has been created successfully.</li>'+
     '<div class="alert alert-warn">If the <b>Next</b> button is enabled before you run the <b>"Step 3: Create a Checkpoint"</b> command, it means there is a recent Checkpoint already and you may proceed without running the <b>"Step 3: Create a Checkpoint"</b> command.</div>' +
     '</ol>',
-  'admin.highAvailability.wizard.step3.body':'Confirm your host selections.',
+  'admin.highAvailability.wizard.step3.confirm.host.body':'<b>Confirm your host selections.</b>',
+  'admin.highAvailability.wizard.step3.confirm.config.body':'<div class="alert alert-info">' +
+    '<b>Review Configuration Changes.</b></br>' +
+    'The following lists the configuration changes that will be made by the Wizard to enable NameNode HA. This information is for <b> review only </b> and is not editable except for the  <b>dfs.journalnode.edits.dir</b> property' +
+    '</div>',
   'admin.highAvailability.wizard.step2.body':'Select a host that will be running the additional NameNode.<br/> In addition,' +
     ' select the hosts to run JournalNodes, which store NameNode edit logs in a fault tolerant manner.',
   'admin.highAvailability.wizard.step1.body':'This wizard will walk you through enabling NameNode HA on your cluster.<br/>' +

http://git-wip-us.apache.org/repos/asf/ambari/blob/bdb46697/ambari-web/app/routes/high_availability_routes.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/high_availability_routes.js b/ambari-web/app/routes/high_availability_routes.js
index 2994351..546118e 100644
--- a/ambari-web/app/routes/high_availability_routes.js
+++ b/ambari-web/app/routes/high_availability_routes.js
@@ -154,6 +154,8 @@ module.exports = Em.Route.extend({
         localdb: App.db.data
       });
       controller.saveMasterComponentHosts(highAvailabilityWizardStep2Controller);
+      controller.get('content').set('serviceConfigProperties', null);
+      controller.setDBProperty('serviceConfigProperties', null);
       router.transitionTo('step3');
     },
     back: function (router) {
@@ -175,11 +177,17 @@ module.exports = Em.Route.extend({
       return false;
     },
     next: function (router) {
+      var controller = router.get('highAvailabilityWizardController');
+      var stepController = router.get('highAvailabilityWizardStep3Controller');
+      controller.saveServiceConfigProperties(stepController);
+      controller.saveConfigTag(stepController.get("hdfsSiteTag"));
+      controller.saveConfigTag(stepController.get("coreSiteTag"));
+      if (App.Service.find().someProperty('serviceName', 'HBASE')) {
+        controller.saveConfigTag(stepController.get("hbaseSiteTag"));
+      }
       router.transitionTo('step4');
     },
-    back: function (router) {
-      router.transitionTo('step2');
-    }
+    back: Em.Router.transitionTo('step2')
   }),
 
   step4: Em.Route.extend({

http://git-wip-us.apache.org/repos/asf/ambari/blob/bdb46697/ambari-web/app/templates/main/admin/highAvailability/step3.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/highAvailability/step3.hbs b/ambari-web/app/templates/main/admin/highAvailability/step3.hbs
index da16c02..3cab571 100644
--- a/ambari-web/app/templates/main/admin/highAvailability/step3.hbs
+++ b/ambari-web/app/templates/main/admin/highAvailability/step3.hbs
@@ -20,25 +20,28 @@
 <h2>{{t admin.highAvailability.wizard.step3.header}}</h2>
 
 <div class="alert alert-info">
-  {{t admin.highAvailability.wizard.step3.body}}
+  {{t admin.highAvailability.wizard.step3.confirm.host.body}}
 </div>
 
-<div id="step8-content" class="well pre-scrollable">
+<div id="ha-step3-content" class="well pre-scrollable">
   <div id="step8-info">
     <table id="ha-step3-review-table">
       <tr>
         <td>{{t admin.highAvailability.wizard.step3.curNameNode}}</td>
-        <td>{{view.curNameNode}}</td><td></td>
+        <td>{{view.curNameNode}}</td>
+        <td></td>
       </tr>
       <tr>
         <td>{{t admin.highAvailability.wizard.step3.secNameNode}}</td>
         <td>{{view.secondaryNameNode}}</td>
-        <td class="to-be-disabled-red"><i class="icon-minus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeDeleted}}</td>
+        <td class="to-be-disabled-red"><i
+                class="icon-minus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeDeleted}}</td>
       </tr>
       <tr>
         <td>{{t admin.highAvailability.wizard.step3.addNameNode}}</td>
         <td>{{view.addNameNode}}</td>
-        <td class="to-be-installed-green"><i class="icon-plus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeInstalled}}</td>
+        <td class="to-be-installed-green"><i
+                class="icon-plus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeInstalled}}</td>
       </tr>
       <tr>
         <td>{{t admin.highAvailability.wizard.step3.journalNode}}</td>
@@ -51,9 +54,12 @@
         </td>
         <td>
           <ul>
-            <div class="to-be-installed-green"><i class="icon-plus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeInstalled}}</div>
-            <div class="to-be-installed-green"><i class="icon-plus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeInstalled}}</div>
-            <div class="to-be-installed-green"><i class="icon-plus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeInstalled}}</div>
+            <div class="to-be-installed-green"><i
+                    class="icon-plus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeInstalled}}</div>
+            <div class="to-be-installed-green"><i
+                    class="icon-plus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeInstalled}}</div>
+            <div class="to-be-installed-green"><i
+                    class="icon-plus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeInstalled}}</div>
           </ul>
         </td>
       </tr>
@@ -61,7 +67,15 @@
   </div>
 </div>
 
- <div class="btn-area">
-   <a class="btn" {{action back}}>&larr; {{t common.back}}</a>
-   <a class="btn btn-success pull-right" {{action next}}>{{t common.next}} &rarr;</a>
- </div>
+
+<div id="serviceConfig">
+
+  {{{t admin.highAvailability.wizard.step3.confirm.config.body}}}
+
+  {{view App.ServiceConfigView isNotEditableBinding="controller.isNotEditable"}}
+</div>
+
+<div class="btn-area">
+  <a class="btn" {{action back}}>&larr; {{t common.back}}</a>
+  <a class="btn btn-success pull-right" {{action next}}>{{t common.next}} &rarr;</a>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/bdb46697/ambari-web/app/utils/helper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/helper.js b/ambari-web/app/utils/helper.js
index 03ffa2a..79a665f 100644
--- a/ambari-web/app/utils/helper.js
+++ b/ambari-web/app/utils/helper.js
@@ -26,6 +26,9 @@ String.prototype.endsWith = function(suffix) {
 String.prototype.startsWith = function (prefix){
   return this.indexOf(prefix) == 0;
 };
+String.prototype.contains = function(substring) {
+  return this.indexOf(substring) != -1;
+};
 
 /**
  * convert ip address string to long int

http://git-wip-us.apache.org/repos/asf/ambari/blob/bdb46697/ambari-web/app/views/main/admin/highAvailability/step3_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/highAvailability/step3_view.js b/ambari-web/app/views/main/admin/highAvailability/step3_view.js
index 7c0c995..eaf6902 100644
--- a/ambari-web/app/views/main/admin/highAvailability/step3_view.js
+++ b/ambari-web/app/views/main/admin/highAvailability/step3_view.js
@@ -22,7 +22,9 @@ var App = require('app');
 App.HighAvailabilityWizardStep3View = Em.View.extend({
 
   templateName: require('templates/main/admin/highAvailability/step3'),
-
+  didInsertElement: function () {
+    this.get('controller').loadStep();
+  },
   curNameNode: function () {
     var nN = this.get('controller.content.masterComponentHosts').findProperty('isCurNameNode', true);
     return nN.hostName;