You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ak...@apache.org on 2014/07/15 18:43:12 UTC

[4/4] git commit: AMBARI-6490. RM HA Wizard: routing and skeleton. (akovalenko)

AMBARI-6490. RM HA Wizard: routing and skeleton. (akovalenko)


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

Branch: refs/heads/trunk
Commit: b86433949bb2796f329e8093e256c311026e9fe2
Parents: 95833e8
Author: Aleksandr Kovalenko <ak...@hortonworks.com>
Authored: Tue Jul 15 19:40:52 2014 +0300
Committer: Aleksandr Kovalenko <ak...@hortonworks.com>
Committed: Tue Jul 15 19:40:53 2014 +0300

----------------------------------------------------------------------
 ambari-web/app/config.js                        |   1 +
 ambari-web/app/controllers.js                   |  35 +-
 .../rollbackHA/rollback_wizard_controller.js    | 159 ++++++
 .../nameNode/rollbackHA/step1_controller.js     |  26 +
 .../nameNode/rollbackHA/step2_controller.js     |  36 ++
 .../nameNode/rollbackHA/step3_controller.js     |  23 +
 .../nameNode/rollback_controller.js             | 492 +++++++++++++++++++
 .../nameNode/step1_controller.js                |  37 ++
 .../nameNode/step2_controller.js                | 140 ++++++
 .../nameNode/step3_controller.js                | 171 +++++++
 .../nameNode/step4_controller.js                |  65 +++
 .../nameNode/step5_controller.js                | 127 +++++
 .../nameNode/step6_controller.js                |  76 +++
 .../nameNode/step7_controller.js                |  39 ++
 .../nameNode/step8_controller.js                |  26 +
 .../nameNode/step9_controller.js                | 118 +++++
 .../nameNode/wizard_controller.js               | 300 +++++++++++
 .../resourceManager/step1_controller.js         |  24 +
 .../resourceManager/step2_controller.js         |  24 +
 .../resourceManager/step3_controller.js         |  24 +
 .../resourceManager/step4_controller.js         |  26 +
 .../resourceManager/wizard_controller.js        |  60 +++
 .../highAvailability/rollback_controller.js     | 492 -------------------
 .../admin/highAvailability/step1_controller.js  |  37 --
 .../admin/highAvailability/step2_controller.js  | 140 ------
 .../admin/highAvailability/step3_controller.js  | 171 -------
 .../admin/highAvailability/step4_controller.js  |  65 ---
 .../admin/highAvailability/step5_controller.js  | 127 -----
 .../admin/highAvailability/step6_controller.js  |  76 ---
 .../admin/highAvailability/step7_controller.js  |  39 --
 .../admin/highAvailability/step8_controller.js  |  26 -
 .../admin/highAvailability/step9_controller.js  | 118 -----
 .../admin/highAvailability/wizard_controller.js | 300 -----------
 .../main/admin/highAvailability_controller.js   |  22 +
 .../rollbackHA/rollback_wizard_controller.js    | 159 ------
 .../main/admin/rollbackHA/step1_controller.js   |  26 -
 .../main/admin/rollbackHA/step2_controller.js   |  36 --
 .../main/admin/rollbackHA/step3_controller.js   |  23 -
 .../main/admin/stack_upgrade_controller.js      |   7 -
 .../controllers/main/service/add_controller.js  |   7 -
 ambari-web/app/controllers/main/service/item.js |   5 +
 .../main/service/reassign_controller.js         |   8 -
 ambari-web/app/controllers/wizard.js            |   8 +
 ambari-web/app/messages.js                      |  13 +
 ambari-web/app/models/service.js                |   3 +-
 .../app/routes/high_availability_routes.js      |   2 +-
 ambari-web/app/routes/main.js                   |   1 +
 .../app/routes/rm_high_availability_routes.js   | 162 ++++++
 ambari-web/app/routes/rollbackHA_routes.js      |   2 +-
 ambari-web/app/styles/application.less          |   8 +
 .../templates/main/admin/highAvailability.hbs   |  10 +-
 .../highAvailability/nameNode/rollback.hbs      |  21 +
 .../nameNode/rollbackHA/rollback_wizard.hbs     |  40 ++
 .../nameNode/rollbackHA/step1.hbs               |  50 ++
 .../nameNode/rollbackHA/step2.hbs               |  27 +
 .../nameNode/rollbackHA/step3.hbs               |  24 +
 .../admin/highAvailability/nameNode/step1.hbs   |  41 ++
 .../admin/highAvailability/nameNode/step2.hbs   |  83 ++++
 .../admin/highAvailability/nameNode/step3.hbs   |  79 +++
 .../admin/highAvailability/nameNode/step4.hbs   |  27 +
 .../admin/highAvailability/nameNode/step5.hbs   |  18 +
 .../admin/highAvailability/nameNode/step6.hbs   |  27 +
 .../admin/highAvailability/nameNode/step7.hbs   |  18 +
 .../admin/highAvailability/nameNode/step8.hbs   |  25 +
 .../admin/highAvailability/nameNode/step9.hbs   |  18 +
 .../admin/highAvailability/nameNode/wizard.hbs  |  50 ++
 .../highAvailability/resourceManager/step1.hbs  |  24 +
 .../highAvailability/resourceManager/step2.hbs  |  24 +
 .../highAvailability/resourceManager/step3.hbs  |  24 +
 .../highAvailability/resourceManager/step4.hbs  |  24 +
 .../highAvailability/resourceManager/wizard.hbs |  45 ++
 .../main/admin/highAvailability/rollback.hbs    |  21 -
 .../main/admin/highAvailability/step1.hbs       |  41 --
 .../main/admin/highAvailability/step2.hbs       |  83 ----
 .../main/admin/highAvailability/step3.hbs       |  79 ---
 .../main/admin/highAvailability/step4.hbs       |  27 -
 .../main/admin/highAvailability/step5.hbs       |  18 -
 .../main/admin/highAvailability/step6.hbs       |  27 -
 .../main/admin/highAvailability/step7.hbs       |  18 -
 .../main/admin/highAvailability/step8.hbs       |  25 -
 .../main/admin/highAvailability/step9.hbs       |  18 -
 .../main/admin/highAvailability/wizard.hbs      |  50 --
 .../main/admin/rollbackHA/rollback_wizard.hbs   |  40 --
 .../templates/main/admin/rollbackHA/step1.hbs   |  50 --
 .../templates/main/admin/rollbackHA/step2.hbs   |  27 -
 .../templates/main/admin/rollbackHA/step3.hbs   |  24 -
 ambari-web/app/utils/db.js                      |   1 +
 ambari-web/app/views.js                         |  35 +-
 .../nameNode/rollbackHA/rollback_wizard_view.js |  49 ++
 .../nameNode/rollbackHA/step1_view.js           |  81 +++
 .../nameNode/rollbackHA/step2_view.js           |  36 ++
 .../nameNode/rollbackHA/step3_view.js           |  30 ++
 .../highAvailability/nameNode/rollback_view.js  |  29 ++
 .../highAvailability/nameNode/step1_view.js     |  34 ++
 .../highAvailability/nameNode/step2_view.js     |  28 ++
 .../highAvailability/nameNode/step3_view.js     |  44 ++
 .../highAvailability/nameNode/step4_view.js     |  44 ++
 .../highAvailability/nameNode/step5_view.js     |  25 +
 .../highAvailability/nameNode/step6_view.js     |  44 ++
 .../highAvailability/nameNode/step7_view.js     |  25 +
 .../highAvailability/nameNode/step8_view.js     |  32 ++
 .../highAvailability/nameNode/step9_view.js     |  29 ++
 .../highAvailability/nameNode/wizard_view.js    | 115 +++++
 .../resourceManager/step1_view.js               |  26 +
 .../resourceManager/step2_view.js               |  26 +
 .../resourceManager/step3_view.js               |  26 +
 .../resourceManager/step4_view.js               |  26 +
 .../resourceManager/wizard_view.js              |  55 +++
 .../admin/highAvailability/rollback_view.js     |  29 --
 .../main/admin/highAvailability/step1_view.js   |  34 --
 .../main/admin/highAvailability/step2_view.js   |  28 --
 .../main/admin/highAvailability/step3_view.js   |  44 --
 .../main/admin/highAvailability/step4_view.js   |  44 --
 .../main/admin/highAvailability/step5_view.js   |  25 -
 .../main/admin/highAvailability/step6_view.js   |  44 --
 .../main/admin/highAvailability/step7_view.js   |  25 -
 .../main/admin/highAvailability/step8_view.js   |  32 --
 .../main/admin/highAvailability/step9_view.js   |  29 --
 .../main/admin/highAvailability/wizard_view.js  | 115 -----
 .../admin/rollbackHA/rollback_wizard_view.js    |  49 --
 .../views/main/admin/rollbackHA/step1_view.js   |  81 ---
 .../views/main/admin/rollbackHA/step2_view.js   |  36 --
 .../views/main/admin/rollbackHA/step3_view.js   |  30 --
 ambari-web/app/views/main/service/item.js       |  23 +-
 124 files changed, 3778 insertions(+), 3089 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/config.js b/ambari-web/app/config.js
index 03079d4..37eb065 100644
--- a/ambari-web/app/config.js
+++ b/ambari-web/app/config.js
@@ -71,6 +71,7 @@ App.supports = {
   ldapGroupMapping: false,
   localRepositories: true,
   highAvailability: true,
+  resourceManagerHighAvailability: false,
   deleteHost: true,
   autoRollbackHA: false,
   appTimelineServer: true,

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers.js b/ambari-web/app/controllers.js
index f83d56d..c5543ce 100644
--- a/ambari-web/app/controllers.js
+++ b/ambari-web/app/controllers.js
@@ -28,23 +28,28 @@ require('controllers/main');
 require('controllers/main/dashboard');
 require('controllers/main/admin');
 require('controllers/main/admin/highAvailability_controller');
-require('controllers/main/admin/highAvailability/wizard_controller');
+require('controllers/main/admin/highAvailability/nameNode/wizard_controller');
 require('controllers/main/admin/highAvailability/progress_controller');
 require('controllers/main/admin/highAvailability/progress_popup_controller');
-require('controllers/main/admin/highAvailability/rollback_controller');
-require('controllers/main/admin/highAvailability/step1_controller');
-require('controllers/main/admin/highAvailability/step2_controller');
-require('controllers/main/admin/highAvailability/step3_controller');
-require('controllers/main/admin/highAvailability/step4_controller');
-require('controllers/main/admin/highAvailability/step5_controller');
-require('controllers/main/admin/highAvailability/step6_controller');
-require('controllers/main/admin/highAvailability/step7_controller');
-require('controllers/main/admin/highAvailability/step8_controller');
-require('controllers/main/admin/highAvailability/step9_controller');
-require('controllers/main/admin/rollbackHA/step1_controller');
-require('controllers/main/admin/rollbackHA/step2_controller');
-require('controllers/main/admin/rollbackHA/step3_controller');
-require('controllers/main/admin/rollbackHA/rollback_wizard_controller');
+require('controllers/main/admin/highAvailability/nameNode/rollback_controller');
+require('controllers/main/admin/highAvailability/nameNode/step1_controller');
+require('controllers/main/admin/highAvailability/nameNode/step2_controller');
+require('controllers/main/admin/highAvailability/nameNode/step3_controller');
+require('controllers/main/admin/highAvailability/nameNode/step4_controller');
+require('controllers/main/admin/highAvailability/nameNode/step5_controller');
+require('controllers/main/admin/highAvailability/nameNode/step6_controller');
+require('controllers/main/admin/highAvailability/nameNode/step7_controller');
+require('controllers/main/admin/highAvailability/nameNode/step8_controller');
+require('controllers/main/admin/highAvailability/nameNode/step9_controller');
+require('controllers/main/admin/highAvailability/nameNode/rollbackHA/step1_controller');
+require('controllers/main/admin/highAvailability/nameNode/rollbackHA/step2_controller');
+require('controllers/main/admin/highAvailability/nameNode/rollbackHA/step3_controller');
+require('controllers/main/admin/highAvailability/nameNode/rollbackHA/rollback_wizard_controller');
+require('controllers/main/admin/highAvailability/resourceManager/wizard_controller');
+require('controllers/main/admin/highAvailability/resourceManager/step1_controller');
+require('controllers/main/admin/highAvailability/resourceManager/step2_controller');
+require('controllers/main/admin/highAvailability/resourceManager/step3_controller');
+require('controllers/main/admin/highAvailability/resourceManager/step4_controller');
 require('controllers/main/admin/cluster');
 require('controllers/main/admin/stack_upgrade_controller');
 require('controllers/main/admin/user');

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/rollback_wizard_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/rollback_wizard_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/rollback_wizard_controller.js
new file mode 100644
index 0000000..78c95b4
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/rollback_wizard_controller.js
@@ -0,0 +1,159 @@
+/**
+ * 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.RollbackHighAvailabilityWizardController = App.WizardController.extend({
+
+  name: 'rollbackHighAvailabilityWizardController',
+
+  totalSteps: 3,
+
+  /**
+   * Used for hiding back button in wizard
+   */
+  hideBackButton: true,
+
+  content: Em.Object.create({
+    controllerName: 'RollbackHighAvailabilityWizardController',
+    cluster: null,
+    masterComponentHosts: null,
+    serviceName: 'MISC',
+    hdfsUser:"hdfs",
+    nameServiceId: '',
+    selectedAddNNHost : null,
+    selectedSNNHost : null,
+    activeNNHost: null
+  }),
+
+  setCurrentStep: function (currentStep, completed) {
+    this._super(currentStep, completed);
+    App.clusterStatus.setClusterStatus({
+      clusterName: this.get('content.cluster.name'),
+      clusterState: 'ROLLBACK_HIGH_AVAILABILITY',
+      wizardControllerName: 'rollbackHighAvailabilityWizardController',
+      localdb: App.db.data
+    });
+  },
+
+  /**
+   * return new object extended from clusterStatusTemplate
+   * @return Object
+   */
+  getCluster: function(){
+    return jQuery.extend({}, this.get('clusterStatusTemplate'), {name: App.router.getClusterName()});
+  },
+
+  /**
+   * save status of the cluster.
+   * @param clusterStatus object with status,requestId fields.
+   */
+  saveClusterStatus: function (clusterStatus) {
+    var oldStatus = this.toObject(this.get('content.cluster'));
+    clusterStatus = jQuery.extend(oldStatus, clusterStatus);
+    if (clusterStatus.requestId) {
+      clusterStatus.requestId.forEach(function (requestId) {
+        if (clusterStatus.oldRequestsId.indexOf(requestId) === -1) {
+          clusterStatus.oldRequestsId.push(requestId)
+        }
+      }, this);
+    }
+    this.set('content.cluster', clusterStatus);
+    this.save('cluster');
+  },
+
+  saveTasksStatuses: function(statuses){
+    App.db.setRollbackHighAvailabilityWizardTasksStatuses(statuses);
+    this.set('content.tasksStatuses', statuses);
+  },
+
+  saveRequestIds: function(requestIds){
+    App.db.setRollbackHighAvailabilityWizardRequestIds(requestIds);
+    this.set('content.requestIds', requestIds);
+  },
+
+  saveSelectedSNN: function(addNN){
+    App.db.setRollBackHighAvailabilityWizardSelectedSNN(addNN);
+    this.set('content.selectedAddNN', addNN);
+  },
+
+  saveSelectedAddNN: function(sNN){
+    App.db.setRollBackHighAvailabilityWizardSelectedAddNN(sNN);
+    this.set('content.selectedSNN', sNN);
+  },
+
+  loadAddNNHost: function () {
+    var addNNHost = App.db.getRollBackHighAvailabilityWizardAddNNHost();
+    this.set('content.addNNHost', addNNHost);
+  },
+
+  loadSNNHost: function () {
+    var sNNHost = App.db.getRollBackHighAvailabilityWizardSNNHost();
+    this.set('content.sNNHost', sNNHost);
+  },
+
+  loadTasksStatuses: function(){
+    var sNNHost = App.db.getRollbackHighAvailabilityWizardTasksStatuses();
+    this.set('content.tasksStatuses', sNNHost);
+  },
+
+  loadRequestIds: function(){
+    var requestIds = App.db.getRollbackHighAvailabilityWizardRequestIds();
+    this.set('content.requestIds', requestIds);
+  },
+
+  /**
+   * Load data for all steps until <code>current step</code>
+   */
+  loadAllPriorSteps: function () {
+    var step = this.get('currentStep');
+    switch (step) {
+      case '3':
+      case '2':
+      case '1':
+        this.loadSNNHost();
+        this.loadAddNNHost();
+        this.load('cluster');
+    }
+  },
+
+  /**
+   * Remove all loaded data.
+   * Created as copy for App.router.clearAllSteps
+   */
+  clearAllSteps: function () {
+    this.clearInstallOptions();
+    // clear temporary information stored during the install
+    this.set('content.cluster', this.getCluster());
+  },
+
+  clearTasksData: function () {
+    this.saveTasksStatuses(undefined);
+    this.saveRequestIds(undefined);
+  },
+
+  /**
+   * Clear all temporary data
+   */
+  finish: function () {
+    this.setCurrentStep('1');
+    this.clearAllSteps();
+    App.router.get('updateController').updateAll();
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/step1_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/step1_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/step1_controller.js
new file mode 100644
index 0000000..60545f6
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/step1_controller.js
@@ -0,0 +1,26 @@
+/**
+ * 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.RollbackHighAvailabilityWizardStep1Controller = Em.Controller.extend({
+
+  name:"rollbackHighAvailabilityWizardStep1Controller"
+
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/step2_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/step2_controller.js
new file mode 100644
index 0000000..6aa8274
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/step2_controller.js
@@ -0,0 +1,36 @@
+/**
+ * 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.RollbackHighAvailabilityWizardStep2Controller = App.HighAvailabilityWizardStep4Controller.extend({
+  name:"rollbackHighAvailabilityWizardStep2Controller",
+
+  pullCheckPointStatus: function () {
+    var hostName = this.get('content.activeNNHost');
+    App.ajax.send({
+      name: 'admin.high_availability.getNnCheckPointStatus',
+      sender: this,
+      data: {
+        hostName: hostName
+      },
+      success: 'checkNnCheckPointStatus'
+    });
+  }
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/step3_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/step3_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/step3_controller.js
new file mode 100644
index 0000000..cca0a4c
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollbackHA/step3_controller.js
@@ -0,0 +1,23 @@
+/**
+ * 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.RollbackHighAvailabilityWizardStep3Controller = Em.Controller.extend({
+  name:"rollbackHighAvailabilityWizardStep3Controller"
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollback_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollback_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollback_controller.js
new file mode 100644
index 0000000..f6af166
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/rollback_controller.js
@@ -0,0 +1,492 @@
+/**
+ * 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('controllers/main/admin/highAvailability/progress_controller');
+
+App.HighAvailabilityRollbackController = App.HighAvailabilityProgressPageController.extend({
+
+  name: "highAvailabilityRollbackController",
+
+  failedTask: null,
+  configsSaved: false,
+  deletedHdfsClients: 0,
+  numOfDelOperations: 0,
+  isRollback: true,
+  hostsToPerformDel: [],
+
+  commands: [
+    'stopAllServices',
+    'restoreHBaseConfigs',
+    'stopFailoverControllers',
+    'deleteFailoverControllers',
+    'stopStandbyNameNode',
+    'stopNameNode',
+    'restoreHDFSConfigs',
+    'enableSecondaryNameNode',
+    'stopJournalNodes',
+    'deleteJournalNodes',
+    'deleteAdditionalNameNode',
+    'startAllServices'
+  ],
+
+  loadStep: function () {
+    console.warn('func: loadStep');
+    this.initData();
+    this.clearStep();
+    this.loadTasks();
+    this.addObserver('tasks.@each.status', this, 'onTaskStatusChange');
+    this.onTaskStatusChange();
+  },
+
+  initData: function () {
+    console.warn('func: initData');
+    this.loadMasterComponentHosts();
+    this.loadFailedTask();
+    this.loadHdfsClientHosts();
+  },
+
+  setCommandsAndTasks: function(tmpTasks) {
+    console.warn('func: setCommandsAndTasks');
+    var fTask = this.get('failedTask');
+    var index = [
+      'deleteSNameNode',
+      'startAllServices',
+      'reconfigureHBase',
+      'startZKFC',
+      'installZKFC',
+      'startSecondNameNode',
+      'startNameNode',
+      'startZooKeeperServers',
+      'reconfigureHDFS',
+      'disableSNameNode',
+      'startJournalNodes',
+      'installJournalNodes',
+      'installNameNode',
+      'stopAllServices'
+    ].indexOf(fTask.command);
+
+    if(index > 6){
+      --index;
+    }
+    var newCommands = this.get('commands').splice(index);
+    this.set('commands', newCommands);
+    var newTasks = tmpTasks.splice(index);
+    for (var i = 0; i < newTasks.length; i++) {
+      newTasks[i].id = i;
+    }
+    this.set('tasks', newTasks);
+    var hbaseTask = this.get('tasks').findProperty('command', 'restoreHBaseConfigs');
+    if (!App.Service.find().someProperty('serviceName', 'HBASE') && hbaseTask) {
+      this.get('tasks').splice(hbaseTask.get('id'), 1);
+    }
+  },
+
+  clearStep: function () {
+    console.warn('func: clearStep');
+    this.set('isSubmitDisabled', true);
+    this.set('tasks', []);
+    this.set('logs', []);
+    this.set('currentRequestIds', []);
+    var commands = this.get('commands');
+    var tmpTasks = [];
+    for (var i = 0; i < commands.length; i++) {
+      tmpTasks.pushObject(Ember.Object.create({
+        title: Em.I18n.t('admin.highAvailability.rollback.task' + i + '.title'),
+        status: 'PENDING',
+        id: i,
+        command: commands[i],
+        showRetry: false,
+        showRollback: false,
+        showSkip: false,
+        name: Em.I18n.t('admin.highAvailability.rollback.task' + i + '.title'),
+        displayName: Em.I18n.t('admin.highAvailability.rollback.task' + i + '.title'),
+        progress: 0,
+        isRunning: false,
+        hosts: []
+      }));
+    }
+    this.setCommandsAndTasks(tmpTasks);
+  },
+
+  onTaskStatusChange: function () {
+    console.warn('func: onTaskStatusChange');
+    if (!this.get('tasks').someProperty('status', 'IN_PROGRESS') && !this.get('tasks').someProperty('status', 'QUEUED') && !this.get('tasks').someProperty('status', 'FAILED')) {
+      var nextTask = this.get('tasks').findProperty('status', 'PENDING');
+      if (nextTask) {
+        console.warn('func: onTaskStatusChange1');
+        this.set('status', 'IN_PROGRESS');
+        this.setTaskStatus(nextTask.get('id'), 'QUEUED');
+        this.set('currentTaskId', nextTask.get('id'));
+        this.runTask(nextTask.get('id'));
+      } else {
+        console.warn('func: onTaskStatusChange2');
+        this.set('status', 'COMPLETED');
+        this.set('isSubmitDisabled', false);
+      }
+    } else if (this.get('tasks').someProperty('status', 'FAILED')) {
+      console.warn('func: onTaskStatusChange3');
+      this.set('status', 'FAILED');
+      this.get('tasks').findProperty('status', 'FAILED').set('showRetry', true);
+      this.get('tasks').findProperty('status', 'FAILED').set('showSkip', true);
+    }
+    this.get('tasks').filterProperty('status','COMPLETED').setEach('showRetry', false);
+    this.get('tasks').filterProperty('status','COMPLETED').setEach('showSkip', false);
+
+    var statuses = this.get('tasks').mapProperty('status');
+    var logs = this.get('tasks').mapProperty('hosts');
+    var requestIds = this.get('currentRequestIds');
+    console.warn('func: onTaskStatusChange4',statuses,logs,requestIds);
+    this.saveTasksStatuses(statuses);
+    this.saveRequestIds(requestIds);
+    this.saveLogs(logs);
+    App.clusterStatus.setClusterStatus({
+      clusterName: this.get('content.cluster.name'),
+      clusterState: 'HIGH_AVAILABILITY_ROLLBACK',
+      wizardControllerName: 'highAvailabilityRollbackController',
+      localdb: App.db.data
+    });
+  },
+
+  skipTask: function () {
+    console.warn('func: skipTask');
+    var task = this.get('tasks').findProperty('status', 'FAILED');
+    task.set('showRetry', false);
+    task.set('showSkip', false);
+    task.set('status', 'COMPLETED');
+  },
+
+  retryTask: function () {
+    console.warn('func: retryTask');
+    var task = this.get('tasks').findProperty('status', 'FAILED');
+    task.set('showRetry', false);
+    task.set('showSkip', false);
+    task.set('status', 'PENDING');
+  },
+
+  onTaskCompleted: function () {
+    console.warn('func: onTaskCompleted');
+    var curTaskStatus = this.getTaskStatus(this.get('currentTaskId'));
+    if (curTaskStatus != 'FAILED' && curTaskStatus != 'TIMEDOUT' && curTaskStatus != 'ABORTED') {
+      this.setTaskStatus(this.get('currentTaskId'), 'COMPLETED');
+    }
+  },
+
+  getTaskStatus: function (taskId) {
+    console.warn('func: getTaskStatus');
+    return this.get('tasks').findProperty('id', taskId).get('status');
+  },
+
+  loadFailedTask: function(){
+    console.warn('func: loadFailedTask');
+    var failedTask = App.db.getHighAvailabilityWizardFailedTask();
+    this.set('failedTask', failedTask);
+  },
+
+  done: function () {
+    if (!this.get('isSubmitDisabled')) {
+      this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
+      this.popup.proceedOnClose();
+    }
+  },
+
+  stopAllServices: function(){
+    console.warn('func: stopAllServices');
+    App.ajax.send({
+      name: 'common.services.update',
+      data: {
+        context: "Stop all services",
+        "ServiceInfo": {
+          "state": "INSTALLED"
+        }
+      },
+      sender: this,
+      success: 'startPolling',
+      error: 'onTaskError'
+    });
+  },
+  restoreHBaseConfigs: function(){
+    console.warn('func: restoreHBaseConfigs');
+    this.loadConfigTag("hbaseSiteTag");
+    var hbaseSiteTag = this.get("content.hbaseSiteTag");
+    App.ajax.send({
+      name: 'admin.high_availability.load_hbase_configs',
+      sender: this,
+      data: {
+        hbaseSiteTag: hbaseSiteTag
+      },
+      success: 'onLoadHbaseConfigs',
+      error: 'onTaskError'
+    });
+  },
+
+  stopFailoverControllers: function(){
+    console.warn('func: stopFailoverControllers');
+    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'NAMENODE').mapProperty('hostName');
+    this.updateComponent('ZKFC', hostNames, "HDFS", "Stop");
+  },
+  deleteFailoverControllers: function(){
+    console.warn('func: deleteFailoverControllers');
+    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'NAMENODE').mapProperty('hostName');
+    this.checkBeforeDelete('ZKFC', hostNames);
+  },
+  stopStandbyNameNode: function(){
+    console.warn('func: stopStandbyNameNode');
+    var hostName = this.get('content.masterComponentHosts').findProperty('isAddNameNode', true).hostName;
+    this.updateComponent('NAMENODE', hostName, "HDFS", "Stop");
+  },
+  stopNameNode: function(){
+    console.warn('func: stopNameNode');
+    var hostName = this.get('content.masterComponentHosts').findProperty('isCurNameNode').hostName;
+    this.updateComponent('NAMENODE', hostName, "HDFS", "Stop");
+  },
+  restoreHDFSConfigs: function(){
+    console.warn('func: restoreHDFSConfigs');
+    this.unInstallHDFSClients();
+  },
+  enableSecondaryNameNode: function(){
+    console.warn('func: enableSecondaryNameNode');
+    var hostName = this.get('content.masterComponentHosts').findProperty('component', 'SECONDARY_NAMENODE').hostName;
+    this.updateComponent('SECONDARY_NAMENODE', hostName, "HDFS", "Install", hostName.length);
+  },
+  stopJournalNodes: function(){
+    console.warn('func: stopJournalNodes');
+    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE').mapProperty('hostName');
+    this.updateComponent('JOURNALNODE', hostNames, "HDFS", "Stop");
+  },
+  deleteJournalNodes: function(){
+    console.warn('func: deleteJournalNodes');
+    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE').mapProperty('hostName');
+    this.unInstallComponent('JOURNALNODE', hostNames);
+  },
+  deleteAdditionalNameNode: function(){
+    console.warn('func: deleteAdditionalNameNode');
+    var hostNames = this.get('content.masterComponentHosts').filterProperty('isAddNameNode', true).mapProperty('hostName');
+    this.unInstallComponent('NAMENODE', hostNames);
+  },
+  startAllServices: function(){
+    console.warn('func: startAllServices');
+    App.ajax.send({
+      name: 'common.services.update',
+      data: {
+        context: "Start all services",
+        "ServiceInfo": {
+          "state": "STARTED"
+        }
+      },
+      sender: this,
+      success: 'startPolling',
+      error: 'onTaskError'
+    });
+  },
+
+  onLoadHbaseConfigs: function (data) {
+    console.warn('func: onLoadHbaseConfigs');
+    var hbaseSiteProperties = data.items.findProperty('type', 'hbase-site').properties;
+    App.ajax.send({
+      name: 'admin.high_availability.save_configs',
+      sender: this,
+      data: {
+        siteName: 'hbase-site',
+        properties: hbaseSiteProperties
+      },
+      success: 'onTaskCompleted',
+      error: 'onTaskError'
+    });
+  },
+
+  onDeletedHDFSClient: function () {
+    console.warn('func: onDeletedHDFSClient');
+    var deletedHdfsClients = this.get('deletedHdfsClients');
+    var hostName = this.get("content.hdfsClientHostNames");
+    var notDeletedHdfsClients = hostName.length - deletedHdfsClients;
+    if (notDeletedHdfsClients > 1 && hostName.length != 1 ) {
+      this.set('deletedHdfsClients', deletedHdfsClients+1);
+      return;
+    }
+    this.loadConfigTag("hdfsSiteTag");
+    this.loadConfigTag("coreSiteTag");
+    var hdfsSiteTag = this.get("content.hdfsSiteTag");
+    var coreSiteTag = this.get("content.coreSiteTag");
+    App.ajax.send({
+      name: 'admin.high_availability.load_configs',
+      sender: this,
+      data: {
+        hdfsSiteTag: hdfsSiteTag,
+        coreSiteTag: coreSiteTag
+      },
+      success: 'onLoadConfigs',
+      error: 'onTaskError'
+    });
+  },
+
+  onLoadConfigs: function (data) {
+    console.warn('func: onLoadConfigs');
+    this.set('configsSaved', false);
+    App.ajax.send({
+      name: 'admin.high_availability.save_configs',
+      sender: this,
+      data: {
+        siteName: 'hdfs-site',
+        properties: data.items.findProperty('type', 'hdfs-site').properties
+      },
+      success: 'onHdfsConfigsSaved',
+      error: 'onTaskError'
+    });
+    App.ajax.send({
+      name: 'admin.high_availability.save_configs',
+      sender: this,
+      data: {
+        siteName: 'core-site',
+        properties: data.items.findProperty('type', 'core-site').properties
+      },
+      success: 'onHdfsConfigsSaved',
+      error: 'onTaskError'
+    });
+  },
+
+  onHdfsConfigsSaved: function () {
+    console.warn('func: onHdfsConfigsSaved');
+    if (!this.get('configsSaved')) {
+      this.set('configsSaved', true);
+      return;
+    }
+    this.onTaskCompleted();
+  },
+
+  unInstallHDFSClients: function () {
+    console.warn('func: unInstallHDFSClients');
+    var hostName = this.get("content.hdfsClientHostNames");
+    for (var i = 0; i < hostName.length; i++) {
+      App.ajax.send({
+        name: 'common.delete.host_component',
+        sender: this,
+        data: {
+          componentName: 'HDFS_CLIENT',
+          hostName: hostName[i]
+        },
+        success: 'onDeletedHDFSClient',
+        error: 'onTaskError'
+      });
+    }
+  },
+
+  unInstallComponent: function (componentName, hostName) {
+    console.warn('func: unInstallComponent');
+    if (!(hostName instanceof Array)) {
+      hostName = [hostName];
+    }
+    for (var i = 0; i < hostName.length; i++) {
+      App.ajax.send({
+        name: 'common.host.host_component.passive',
+        sender: this,
+        data: {
+          hostName: hostName[i],
+          componentName: componentName,
+          passive_state: "ON",
+          taskNum: hostName.length,
+          callback: 'checkBeforeDelete'
+        },
+        success: 'checkResult',
+        error: 'checkResult'
+      });
+    }
+  },
+
+  checkBeforeDelete: function (componentName, hostName){
+    console.warn('func: checkBeforeDelete');
+    this.set('hostsToPerformDel', []);
+    if (!(hostName instanceof Array)) {
+      hostName = [hostName];
+    }
+    for (var i = 0; i < hostName.length; i++) {
+      App.ajax.send({
+        name: 'admin.high_availability.getHostComponent',
+        sender: this,
+        data: {
+          componentName: componentName,
+          hostName: hostName[i],
+          taskNum: hostName.length,
+          callback: 'deleteComponent'
+        },
+        success: 'checkResult',
+        error: 'checkResult'
+      });
+    }
+  },
+
+  checkResult: function () {
+    console.warn('func: checkResult');
+    var callback = arguments[2].callback;
+    var hostName = arguments[2].hostName;
+    var componentName = arguments[2].componentName;
+    var taskNum = arguments[2].taskNum;
+    var hostsToPerformDel = this.get('hostsToPerformDel');
+    if(arguments[1] != 'error'){
+      hostsToPerformDel.push({
+        hostName: hostName,
+        isOnHost: true
+      });
+    }else{
+      hostsToPerformDel.push({
+        hostName: 'error',
+        isOnHost: false
+      });
+    }
+    if(hostsToPerformDel.length == taskNum){
+      var hostsForDel = hostsToPerformDel.filterProperty('isOnHost', true).mapProperty('hostName');
+      this.set('hostsToPerformDel', []);
+      if(hostsForDel.length == 0){
+        this.onTaskCompleted();
+        return;
+      }
+      this[callback](componentName, hostsForDel);
+    }
+  },
+
+  deleteComponent: function (componentName, hostName) {
+    console.warn('func: deleteComponent');
+    if (!(hostName instanceof Array)) {
+      hostName = [hostName];
+    }
+    this.set('numOfDelOperations', hostName.length);
+    for (var i = 0; i < hostName.length; i++) {
+      App.ajax.send({
+        name: 'common.delete.host_component',
+        sender: this,
+        data: {
+          componentName: componentName,
+          hostName: hostName[i]
+        },
+        success: 'onDeleteComplete',
+        error: 'onTaskError'
+      });
+    }
+  },
+
+  onDeleteComplete: function () {
+    console.warn('func: onDeleteComplete');
+    var leftOp = this.get('numOfDelOperations');
+    if(leftOp > 1){
+      this.set('numOfDelOperations', leftOp-1);
+      return;
+    }
+    this.onTaskCompleted();
+  }
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step1_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step1_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step1_controller.js
new file mode 100644
index 0000000..d3c1da4
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step1_controller.js
@@ -0,0 +1,37 @@
+/**
+ * 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('controllers/main/admin/misc_controller');
+
+App.HighAvailabilityWizardStep1Controller = Em.Controller.extend({
+  name: "highAvailabilityWizardStep1Controller",
+
+  isNameServiceIdValid: function () {
+    return /^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])$/.test(this.get('content.nameServiceId'));
+  }.property('content.nameServiceId'),
+
+  next: function () {
+    if (this.get('isNameServiceIdValid')) {
+      App.router.send('next');
+    }
+  }
+
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step2_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step2_controller.js
new file mode 100644
index 0000000..e7e77bb
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step2_controller.js
@@ -0,0 +1,140 @@
+/**
+ * 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('controllers/wizard/step5_controller');
+
+App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({
+
+  name:"highAvailabilityWizardStep2Controller",
+
+  /**
+   * master components which could be assigned to multiple hosts in HA wizard
+   */
+  multipleComponentsHaWizard: ['NAMENODE', 'JOURNALNODE'],
+
+  /**
+   * master components supported by Ambari
+   */
+
+  multipleComponents: ['NAMENODE', 'JOURNALNODE','ZOOKEEPER_SERVER','HBASE_MASTER'],
+
+  /**
+   * overrides method in wizardStep5Controller
+   * it must be empty as it shouldn't be run
+   */
+  masterHostMappingObserver: function() {},
+
+  /**
+   * Load services info to appropriate variable and return masterComponentHosts
+   * @return Array
+   */
+  masterHostMapping:function () {
+    var mapping = [], mappingObject, self = this, mappedHosts, hostObj, hostInfo;
+    //get the unique assigned hosts and find the master services assigned to them
+
+
+    mappedHosts = this.get("selectedServicesMasters").mapProperty("selectedHost").uniq();
+
+    mappedHosts.forEach(function (item) {
+
+      hostObj = self.get("hosts").findProperty("host_name", item);
+      console.log("Name of the host is: " + hostObj.host_name);
+
+      var masterServices = self.get("selectedServicesMasters").filterProperty("selectedHost", item);
+      masterServices.forEach(function(item){
+        if(this.get('multipleComponentsHaWizard').contains(item.component_name)){
+          item.set('color','green');
+        }else{
+          item.set('color','grey');
+        }
+      }, this);
+
+      mappingObject = Ember.Object.create({
+        host_name:item,
+        hostInfo:hostObj.host_info,
+        masterServices:masterServices
+      });
+
+      mapping.pushObject(mappingObject);
+    }, this);
+
+    return mapping.sortProperty('host_name');
+  }.property("selectedServicesMasters.@each.selectedHost"),
+
+  /**
+   * Put master components to <code>selectedServicesMasters</code>, which will be automatically rendered in template
+   * @param masterComponents
+   */
+  renderComponents:function (masterComponents) {
+    var services = this.get('content.services').filterProperty('isInstalled', true).mapProperty('serviceName'); //list of shown services
+
+    var result = [];
+
+    var curNameNode = masterComponents.findProperty('component_name',"NAMENODE");
+    curNameNode.isCurNameNode = true;
+    curNameNode.serviceComponentId = 0;
+
+    //Create JOURNALNODE
+    for (var index = 0; index < 3; index++) {
+      masterComponents.push(
+        {
+          component_name: "JOURNALNODE",
+          display_name: "JournalNode",
+          isServiceCoHost: false,
+          isInstalled: false,
+          selectedHost: this.get("hosts")[index].get("host_name"),
+          serviceId: "HDFS",
+          serviceComponentId: index
+        }
+      )
+    }
+    //Create Additional NameNode
+    masterComponents.push(
+      {
+        component_name: "NAMENODE",
+        display_name: "NameNode",
+        isServiceCoHost: false,
+        isInstalled: false,
+        selectedHost: this.get("hosts").mapProperty('host_name').without(curNameNode.selectedHost)[0],
+        serviceId: "HDFS",
+        isAddNameNode: true,
+        serviceComponentId: 1
+      }
+    );
+
+    masterComponents.forEach(function (item) {
+      var componentObj = Ember.Object.create(item);
+      result.push(componentObj);
+    }, this);
+
+    this.set("selectedServicesMasters", result);
+
+    var components = result.filterProperty('component_name',"NAMENODE");
+    components.push.apply(components, result.filterProperty('component_name',"JOURNALNODE"));
+
+    this.set('servicesMasters', components);
+    this.set('componentToRebalance', "NAMENODE");
+    this.incrementProperty('rebalanceComponentHostsCounter');
+    this.set('componentToRebalance', "JOURNALNODE");
+    this.incrementProperty('rebalanceComponentHostsCounter');
+  }
+
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step3_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step3_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step3_controller.js
new file mode 100644
index 0000000..c222047
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step3_controller.js
@@ -0,0 +1,171 @@
+/**
+ * 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.HighAvailabilityWizardStep3Controller = Em.Controller.extend({
+  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/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step4_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step4_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step4_controller.js
new file mode 100644
index 0000000..cc243a1
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step4_controller.js
@@ -0,0 +1,65 @@
+/**
+ * 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('controllers/main/admin/misc_controller');
+
+App.HighAvailabilityWizardStep4Controller = Em.Controller.extend({
+
+  name:"highAvailabilityWizardStep4Controller",
+
+  POLL_INTERVAL: 1000,
+
+  isNextEnabled: false,
+
+  pullCheckPointStatus: function () {
+    var hostName = this.get('content.masterComponentHosts').findProperty('isCurNameNode', true).hostName;
+    App.ajax.send({
+      name: 'admin.high_availability.getNnCheckPointStatus',
+      sender: this,
+      data: {
+        hostName: hostName
+      },
+      success: 'checkNnCheckPointStatus'
+    });
+  },
+
+  checkNnCheckPointStatus: function (data) {
+    var self = this;
+    var journalTransactionInfo =  $.parseJSON(data.metrics.dfs.namenode.JournalTransactionInfo);
+    var isInSafeMode = (data.metrics.dfs.namenode.Safemode != "");
+    journalTransactionInfo = parseInt(journalTransactionInfo.LastAppliedOrWrittenTxId) - parseInt(journalTransactionInfo.MostRecentCheckpointTxId);
+    if(journalTransactionInfo <= 1 && isInSafeMode){
+      this.set("isNextEnabled", true);
+      return;
+    }
+
+    window.setTimeout(function () {
+      self.pullCheckPointStatus()
+    }, self.POLL_INTERVAL);
+  },
+
+  done: function () {
+    if (this.get('isNextEnabled')) {
+      App.router.send('next');
+    }
+  }
+
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step5_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step5_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step5_controller.js
new file mode 100644
index 0000000..f5e93a5
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step5_controller.js
@@ -0,0 +1,127 @@
+/**
+ * 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.HighAvailabilityWizardStep5Controller = App.HighAvailabilityProgressPageController.extend({
+
+  name:"highAvailabilityWizardStep5Controller",
+
+  isHA: true,
+
+  commands: ['stopAllServices', 'installNameNode', 'installJournalNodes', 'reconfigureHDFS', 'startJournalNodes', 'disableSNameNode'],
+
+  hdfsSiteTag : "",
+  coreSiteTag : "",
+
+  stopAllServices: function () {
+    App.ajax.send({
+      name: 'common.services.update',
+      data: {
+        context: "Stop all services",
+        "ServiceInfo": {
+          "state": "INSTALLED"
+        }
+      },
+      sender: this,
+      success: 'startPolling',
+      error: 'onTaskError'
+    });
+  },
+
+  installNameNode: function () {
+    var hostName = this.get('content.masterComponentHosts').findProperty('isAddNameNode').hostName;
+    this.createComponent('NAMENODE', hostName, "HDFS");
+  },
+
+  installJournalNodes: function () {
+    App.ajax.send({
+      name: 'admin.high_availability.create_journalnode',
+      sender: this,
+      success: 'onJournalNodeCreate',
+      error: 'onJournalNodeCreate'
+    });
+  },
+
+  onJournalNodeCreate: function () {
+    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE').mapProperty('hostName');
+    this.createComponent('JOURNALNODE', hostNames, "HDFS");
+  },
+
+  startJournalNodes: function () {
+    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE').mapProperty('hostName');
+    this.updateComponent('JOURNALNODE', hostNames, "HDFS", "Start");
+  },
+
+  disableSNameNode: function () {
+    var hostName = this.get('content.masterComponentHosts').findProperty('component', 'SECONDARY_NAMENODE').hostName;
+    App.ajax.send({
+      name: 'common.host.host_component.passive',
+      sender: this,
+      data: {
+        hostName: hostName,
+        passive_state: "ON",
+        componentName: 'SECONDARY_NAMENODE'
+      },
+      success: 'onTaskCompleted',
+      error: 'onTaskError'
+    });
+  },
+
+  reconfigureHDFS: function () {
+    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 self = this;
+    App.ajax.send({
+      name: 'admin.high_availability.save_configs',
+      sender: this,
+      data: {
+        siteName: 'hdfs-site',
+        properties: hdfsSiteProperties
+      },
+      error: 'onTaskError'
+    }).done(function() {
+      App.ajax.send({
+        name: 'admin.high_availability.save_configs',
+        sender: self,
+        data: {
+          siteName: 'core-site',
+          properties: coreSiteProperties
+        },
+        error: 'onTaskError',
+        success: 'installHDFSClients'
+      });
+    });
+  },
+
+  installHDFSClients: function () {
+    var nnHostNames = this.get('content.masterComponentHosts').filterProperty('component', 'NAMENODE').mapProperty('hostName');
+    var jnHostNames = this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE').mapProperty('hostName');
+    var hostNames = nnHostNames.concat(jnHostNames).uniq();
+    this.createComponent('HDFS_CLIENT', hostNames);
+    App.router.get(this.get('content.controllerName')).saveHdfsClientHosts(hostNames);
+    App.clusterStatus.setClusterStatus({
+      clusterName: this.get('content.cluster.name'),
+      clusterState: 'HIGH_AVAILABILITY_DEPLOY',
+      wizardControllerName: this.get('content.controllerName'),
+      localdb: App.db.data
+    });
+  }
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step6_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step6_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step6_controller.js
new file mode 100644
index 0000000..a44f5e0
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step6_controller.js
@@ -0,0 +1,76 @@
+/**
+ * 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.HighAvailabilityWizardStep6Controller = Em.Controller.extend({
+
+  name:"highAvailabilityWizardStep6Controller",
+
+  POLL_INTERVAL: 1000,
+
+  isNextEnabled: function(){
+    //only 3 JournalNodes could be installed
+    return (this.get('initJnCounter') === 3);
+  }.property('initJnCounter'),
+
+  initJnCounter: 0,
+
+  pullCheckPointStatus: function () {
+    this.set('initJnCounter', 0);
+    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', "JOURNALNODE").mapProperty('hostName');
+    hostNames.forEach(function (hostName) {
+      this.pullEachJnStatus(hostName);
+    }, this);
+  },
+
+  pullEachJnStatus: function(hostName){
+    App.ajax.send({
+      name: 'admin.high_availability.getJnCheckPointStatus',
+      sender: this,
+      data: {
+        hostName: hostName
+      },
+      success: 'checkJnCheckPointStatus'
+    });
+  },
+
+  checkJnCheckPointStatus: function (data) {
+    var self = this;
+    var journalStatusInfo;
+    if (data.metrics && data.metrics.dfs) {
+      journalStatusInfo = $.parseJSON(data.metrics.dfs.journalnode.journalsStatus);
+      if (journalStatusInfo[this.get('content.nameServiceId')] && journalStatusInfo[this.get('content.nameServiceId')].Formatted === "true") {
+        this.set("initJnCounter", (this.get('initJnCounter') + 1));
+        return;
+      }
+    }
+
+    window.setTimeout(function () {
+      self.pullEachJnStatus(data.HostRoles.host_name);
+    }, self.POLL_INTERVAL);
+  },
+
+  done: function () {
+    if (this.get('isNextEnabled')) {
+      App.router.send('next');
+    }
+  }
+
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step7_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step7_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step7_controller.js
new file mode 100644
index 0000000..429ab3e
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step7_controller.js
@@ -0,0 +1,39 @@
+/**
+ * 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.HighAvailabilityWizardStep7Controller = App.HighAvailabilityProgressPageController.extend({
+
+  name:"highAvailabilityWizardStep7Controller",
+
+  isHA: true,
+
+  commands: ['startZooKeeperServers', 'startNameNode'],
+
+  startZooKeeperServers: function () {
+    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName');
+    this.updateComponent('ZOOKEEPER_SERVER', hostNames, "ZOOKEEPER", "Start");
+  },
+
+  startNameNode: function () {
+    var hostName = this.get('content.masterComponentHosts').findProperty('isCurNameNode').hostName;
+    this.updateComponent('NAMENODE', hostName, "HDFS", "Start");
+  }
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step8_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step8_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step8_controller.js
new file mode 100644
index 0000000..5220591
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step8_controller.js
@@ -0,0 +1,26 @@
+/**
+ * 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.HighAvailabilityWizardStep8Controller = Em.Controller.extend({
+
+  name:"highAvailabilityWizardStep8Controller"
+
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step9_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step9_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step9_controller.js
new file mode 100644
index 0000000..26ca0c7
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/step9_controller.js
@@ -0,0 +1,118 @@
+/**
+ * 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.HighAvailabilityWizardStep9Controller = App.HighAvailabilityProgressPageController.extend({
+
+  name:"highAvailabilityWizardStep9Controller",
+
+  isHA: true,
+
+  commands: ['startSecondNameNode', 'installZKFC', 'startZKFC', 'reconfigureHBase', 'deleteSNameNode', 'startAllServices'],
+
+  hbaseSiteTag: "",
+
+  initializeTasks: function () {
+    this._super();
+    if (!App.Service.find().someProperty('serviceName', 'HBASE')) {
+      this.get('tasks').splice(this.get('tasks').findProperty('command', 'reconfigureHBase').get('id'), 1);
+    }
+  },
+
+  startSecondNameNode: function () {
+    var hostName = this.get('content.masterComponentHosts').findProperty('isAddNameNode', true).hostName;
+    this.updateComponent('NAMENODE', hostName, "HDFS", "Start");
+  },
+
+  installZKFC: function () {
+    App.ajax.send({
+      name: 'admin.high_availability.create_zkfc',
+      sender: this,
+      success: 'onZKFCCreate',
+      error: 'onZKFCCreate'
+    });
+  },
+
+  onZKFCCreate: function () {
+    var hostName = this.get('content.masterComponentHosts').filterProperty('component', 'NAMENODE').mapProperty('hostName');
+    this.createComponent('ZKFC', hostName, "HDFS");
+  },
+
+  startZKFC: function () {
+    var hostName = this.get('content.masterComponentHosts').filterProperty('component', 'NAMENODE').mapProperty('hostName');
+    this.updateComponent('ZKFC', hostName, "HDFS", "Start");
+  },
+
+  reconfigureHBase: function () {
+    var data = this.get('content.serviceConfigProperties');
+    var hbaseSiteProperties = data.items.findProperty('type', 'hbase-site').properties;
+
+    App.ajax.send({
+      name: 'admin.high_availability.save_configs',
+      sender: this,
+      data: {
+        siteName: 'hbase-site',
+        properties: hbaseSiteProperties
+      },
+      success: 'saveConfigTag',
+      error: 'onTaskError'
+    });
+  },
+
+  saveConfigTag: function () {
+    App.clusterStatus.setClusterStatus({
+      clusterName: this.get('content.cluster.name'),
+      clusterState: 'HIGH_AVAILABILITY_DEPLOY',
+      wizardControllerName: this.get('content.controllerName'),
+      localdb: App.db.data
+    });
+    this.onTaskCompleted();
+  },
+
+  startAllServices: function () {
+    App.ajax.send({
+      name: 'common.services.update',
+      data: {
+        context: "Start all services",
+        "ServiceInfo": {
+          "state": "STARTED"
+        }
+      },
+      sender: this,
+      success: 'startPolling',
+      error: 'onTaskError'
+    });
+  },
+
+  deleteSNameNode: function () {
+    var hostName = this.get('content.masterComponentHosts').findProperty('component', 'SECONDARY_NAMENODE').hostName;
+    App.ajax.send({
+      name: 'common.delete.host_component',
+      sender: this,
+      data: {
+        componentName: 'SECONDARY_NAMENODE',
+        hostName: hostName
+      },
+      success: 'onTaskCompleted',
+      error: 'onTaskError'
+    });
+  }
+
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/nameNode/wizard_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/nameNode/wizard_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/wizard_controller.js
new file mode 100644
index 0000000..22791bf
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/nameNode/wizard_controller.js
@@ -0,0 +1,300 @@
+/**
+ * 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.HighAvailabilityWizardController = App.WizardController.extend({
+
+  name: 'highAvailabilityWizardController',
+
+  totalSteps: 9,
+
+  /**
+   * Used for hiding back button in wizard
+   */
+  hideBackButton: true,
+
+  content: Em.Object.create({
+    controllerName: 'highAvailabilityWizardController',
+    cluster: null,
+    hosts: null,
+    services: null,
+    slaveComponentHosts: null,
+    masterComponentHosts: null,
+    serviceConfigProperties: [],
+    serviceName: 'MISC',
+    hdfsUser:"hdfs",
+    nameServiceId: '',
+    failedTask : null
+  }),
+
+  setCurrentStep: function (currentStep, completed) {
+    this._super(currentStep, completed);
+    App.clusterStatus.setClusterStatus({
+      clusterName: this.get('content.cluster.name'),
+      clusterState: 'HIGH_AVAILABILITY_DEPLOY',
+      wizardControllerName: 'highAvailabilityWizardController',
+      localdb: App.db.data
+    });
+  },
+
+  /**
+   * return new object extended from clusterStatusTemplate
+   * @return Object
+   */
+  getCluster: function(){
+    return jQuery.extend({}, this.get('clusterStatusTemplate'), {name: App.router.getClusterName()});
+  },
+
+  /**
+   * Load services data from server.
+   */
+  loadServicesFromServer: function() {
+    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());
+  },
+
+  /**
+   * Load confirmed hosts.
+   * Will be used at <code>Assign Masters(step5)</code> step
+   */
+  loadConfirmedHosts: function () {
+    var hosts = App.db.getHosts();
+
+    if (hosts) {
+      this.set('content.hosts', hosts);
+      console.log('ReassignMasterController.loadConfirmedHosts: loaded hosts', hosts);
+    }
+  },
+  /**
+   * save status of the cluster.
+   * @param clusterStatus object with status,requestId fields.
+   */
+  saveClusterStatus: function (clusterStatus) {
+    var oldStatus = this.toObject(this.get('content.cluster'));
+    clusterStatus = jQuery.extend(oldStatus, clusterStatus);
+    if (clusterStatus.requestId) {
+      clusterStatus.requestId.forEach(function (requestId) {
+        if (clusterStatus.oldRequestsId.indexOf(requestId) === -1) {
+          clusterStatus.oldRequestsId.push(requestId)
+        }
+      }, this);
+    }
+    this.set('content.cluster', clusterStatus);
+    this.save('cluster');
+  },
+
+  /**
+   * Save Master Component Hosts data to Main Controller
+   * @param stepController App.WizardStep5Controller
+   */
+  saveMasterComponentHosts: function (stepController) {
+    var obj = stepController.get('selectedServicesMasters');
+    var masterComponentHosts = [];
+    obj.forEach(function (_component) {
+      masterComponentHosts.push({
+        display_name: _component.get('display_name'),
+        component: _component.get('component_name'),
+        hostName: _component.get('selectedHost'),
+        serviceId: _component.get('serviceId'),
+        isCurNameNode: _component.get('isCurNameNode'),
+        isAddNameNode: _component.get('isAddNameNode'),
+        isInstalled: true
+      });
+    });
+    this.setDBProperty('masterComponentHosts', masterComponentHosts);
+    this.set('content.masterComponentHosts', masterComponentHosts);
+  },
+
+  saveHdfsUser: function () {
+    App.db.setHighAvailabilityWizardHdfsUser(this.get('content.hdfsUser'));
+  },
+
+  saveTasksStatuses: function(statuses){
+    App.db.setHighAvailabilityWizardTasksStatuses(statuses);
+    this.set('content.tasksStatuses', statuses);
+  },
+
+  saveConfigTag: function(tag){
+    App.db.setHighAvailabilityWizardConfigTag(tag);
+    this.set('content.'+[tag.name], tag.value);
+  },
+
+  saveHdfsClientHosts: function(hostNames){
+    App.db.setHighAvailabilityWizardHdfsClientHosts(hostNames);
+    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)) {
+      hostNames = [hostNames];
+    }
+    this.set('content.hdfsClientHostNames', hostNames);
+  },
+
+  loadConfigTag: function(tag){
+    var tagVal = App.db.getHighAvailabilityWizardConfigTag(tag);
+    this.set('content.'+tag, tagVal);
+  },
+
+
+  loadHdfsUser: function(){
+    var hdfsUser = App.db.getHighAvailabilityWizardHdfsUser();
+    this.set('content.hdfsUser', hdfsUser);
+  },
+
+  loadTasksStatuses: function(){
+    var statuses = App.db.getHighAvailabilityWizardTasksStatuses();
+    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);
+  },
+
+  loadRequestIds: function(){
+    var requestIds = App.db.getHighAvailabilityWizardRequestIds();
+    this.set('content.requestIds', requestIds);
+  },
+
+  saveNameServiceId: function(nameServiceId){
+    App.db.setHighAvailabilityWizardNameServiceId(nameServiceId);
+    this.set('content.nameServiceId', nameServiceId);
+  },
+
+  loadNameServiceId: function(){
+    var nameServiceId = App.db.getHighAvailabilityWizardNameServiceId();
+    this.set('content.nameServiceId', nameServiceId);
+  },
+
+  saveTasksRequestIds: function (requestIds) {
+    App.db.setHighAvailabilityWizardTasksRequestIds(requestIds);
+    this.set('content.tasksRequestIds', requestIds);
+  },
+
+  loadTasksRequestIds: function () {
+    var requestIds = App.db.getHighAvailabilityWizardTasksRequestIds();
+    this.set('content.tasksRequestIds', requestIds);
+  },
+
+  /**
+   * Load data for all steps until <code>current step</code>
+   */
+  loadAllPriorSteps: function () {
+    var step = this.get('currentStep');
+    switch (step) {
+      case '9':
+      case '8':
+      case '7':
+      case '6':
+      case '5':
+        this.loadTasksStatuses();
+        this.loadTasksRequestIds();
+        this.loadRequestIds();
+      case '4':
+      case '3':
+        this.loadNameServiceId();
+        this.loadServiceConfigProperties();
+      case '2':
+        this.loadServicesFromServer();
+        this.loadMasterComponentHosts();
+        this.loadConfirmedHosts();
+        this.loadHdfsUser();
+      case '1':
+        this.load('cluster');
+    }
+  },
+
+  /**
+   * Remove all loaded data.
+   * Created as copy for App.router.clearAllSteps
+   */
+  clearAllSteps: function () {
+    this.clearInstallOptions();
+    // clear temporary information stored during the install
+    this.set('content.cluster', this.getCluster());
+  },
+
+  clearTasksData: function () {
+    this.saveTasksStatuses(undefined);
+    this.saveRequestIds(undefined);
+    this.saveTasksRequestIds(undefined);
+  },
+
+  /**
+   * Clear all temporary data
+   */
+  finish: function () {
+    App.db.data.HighAvailabilityWizard = {};
+    App.db.data.Installer = {};
+    App.router.get('updateController').updateAll();
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step1_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step1_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step1_controller.js
new file mode 100644
index 0000000..b8de0d8
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step1_controller.js
@@ -0,0 +1,24 @@
+/**
+ * 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.RMHighAvailabilityWizardStep1Controller = Em.Controller.extend({
+  name: "rMHighAvailabilityWizardStep1Controller"
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step2_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step2_controller.js
new file mode 100644
index 0000000..e2a6546
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step2_controller.js
@@ -0,0 +1,24 @@
+/**
+ * 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.RMHighAvailabilityWizardStep2Controller = Em.Controller.extend({
+  name:"rMHighAvailabilityWizardStep2Controller"
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/b8643394/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js
new file mode 100644
index 0000000..286ea80
--- /dev/null
+++ b/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js
@@ -0,0 +1,24 @@
+/**
+ * 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.RMHighAvailabilityWizardStep3Controller = Em.Controller.extend({
+  name: "rMHighAvailabilityWizardStep3Controller"
+});
+