Sfoglia il codice sorgente

AMBARI-18767 - E2E Integration for Manage JournalNode Wizard (rzang)

Richard Zang 8 anni fa
parent
commit
e1d4a44b02
22 ha cambiato i file con 426 aggiunte e 102 eliminazioni
  1. 2 0
      ambari-web/app/controllers.js
  2. 33 18
      ambari-web/app/controllers/main/admin/highAvailability/journalNode/step1_controller.js
  3. 1 18
      ambari-web/app/controllers/main/admin/highAvailability/journalNode/step2_controller.js
  4. 24 4
      ambari-web/app/controllers/main/admin/highAvailability/journalNode/step4_controller.js
  5. 11 1
      ambari-web/app/controllers/main/admin/highAvailability/journalNode/step6_controller.js
  6. 30 0
      ambari-web/app/controllers/main/admin/highAvailability/journalNode/step7_controller.js
  7. 35 0
      ambari-web/app/controllers/main/admin/highAvailability/journalNode/step8_controller.js
  8. 50 14
      ambari-web/app/controllers/main/admin/highAvailability/journalNode/wizard_controller.js
  9. 36 8
      ambari-web/app/messages.js
  10. 53 2
      ambari-web/app/routes/manage_journalnode_routes.js
  11. 2 2
      ambari-web/app/styles/application.less
  12. 28 5
      ambari-web/app/templates/main/admin/highAvailability/journalNode/step2.hbs
  13. 24 0
      ambari-web/app/templates/main/admin/highAvailability/journalNode/step7.hbs
  14. 18 0
      ambari-web/app/templates/main/admin/highAvailability/journalNode/step8.hbs
  15. 2 0
      ambari-web/app/templates/main/admin/highAvailability/journalNode/wizard.hbs
  16. 2 0
      ambari-web/app/views.js
  17. 9 3
      ambari-web/app/views/main/admin/highAvailability/journalNode/step2_view.js
  18. 2 2
      ambari-web/app/views/main/admin/highAvailability/journalNode/step3_view.js
  19. 2 3
      ambari-web/app/views/main/admin/highAvailability/journalNode/step5_view.js
  20. 31 0
      ambari-web/app/views/main/admin/highAvailability/journalNode/step7_view.js
  21. 29 0
      ambari-web/app/views/main/admin/highAvailability/journalNode/step8_view.js
  22. 2 22
      ambari-web/app/views/main/admin/highAvailability/journalNode/wizard_view.js

+ 2 - 0
ambari-web/app/controllers.js

@@ -82,6 +82,8 @@ require('controllers/main/admin/highAvailability/journalNode/step3_controller');
 require('controllers/main/admin/highAvailability/journalNode/step4_controller');
 require('controllers/main/admin/highAvailability/journalNode/step4_controller');
 require('controllers/main/admin/highAvailability/journalNode/step5_controller');
 require('controllers/main/admin/highAvailability/journalNode/step5_controller');
 require('controllers/main/admin/highAvailability/journalNode/step6_controller');
 require('controllers/main/admin/highAvailability/journalNode/step6_controller');
+require('controllers/main/admin/highAvailability/journalNode/step7_controller');
+require('controllers/main/admin/highAvailability/journalNode/step8_controller');
 require('controllers/main/admin/stack_and_upgrade_controller');
 require('controllers/main/admin/stack_and_upgrade_controller');
 require('controllers/main/admin/serviceAccounts_controller');
 require('controllers/main/admin/serviceAccounts_controller');
 require('utils/polling');
 require('utils/polling');

+ 33 - 18
ambari-web/app/controllers/main/admin/highAvailability/journalNode/step1_controller.js

@@ -34,27 +34,27 @@ App.ManageJournalNodeWizardStep1Controller = Em.Controller.extend(App.BlueprintM
 
 
   JOURNALNODES_COUNT_MINIMUM: 3, // TODO get this from stack
   JOURNALNODES_COUNT_MINIMUM: 3, // TODO get this from stack
 
 
+  /**
+   * On initial rendering, load equivalent number of existing JournalNodes to masterToShow
+   * @param masterComponents
+   */
   renderComponents: function(masterComponents) {
   renderComponents: function(masterComponents) {
     var jns = App.HostComponent.find().filterProperty('componentName', 'JOURNALNODE');
     var jns = App.HostComponent.find().filterProperty('componentName', 'JOURNALNODE');
     var count = jns.get('length');
     var count = jns.get('length');
-    for (var i = 0; i < count; i++) {
-      this.get('mastersToAdd').push('JOURNALNODE');
+    this.set('mastersToAdd', []);
+    if (masterComponents.filterProperty('component_name', 'JOURNALNODE').length == 0) {
+      for (var i = 0; i < count; i++) {
+        this.get('mastersToAdd').push('JOURNALNODE');
+      }
     }
     }
     this._super(masterComponents);
     this._super(masterComponents);
     this.updateJournalNodeInfo();
     this.updateJournalNodeInfo();
     this.showHideJournalNodesAddRemoveControl();
     this.showHideJournalNodesAddRemoveControl();
   },
   },
 
 
-  addComponent: function(componentName) {
-    this._super(componentName);
-    this.showHideJournalNodesAddRemoveControl();
-  },
-
-  removeComponent: function(componentName, serviceComponentId) {
-    this._super(componentName, serviceComponentId);
-    this.showHideJournalNodesAddRemoveControl()
-  },
-
+  /**
+   * Enable/Disable show/hide operation for each JournalNode
+   */
   showHideJournalNodesAddRemoveControl: function() {
   showHideJournalNodesAddRemoveControl: function() {
     var masterComponents = this.get('selectedServicesMasters');
     var masterComponents = this.get('selectedServicesMasters');
     var jns = masterComponents.filterProperty('component_name', 'JOURNALNODE');
     var jns = masterComponents.filterProperty('component_name', 'JOURNALNODE');
@@ -66,16 +66,22 @@ App.ManageJournalNodeWizardStep1Controller = Em.Controller.extend(App.BlueprintM
       item.set('showRemoveControl', showRemoveControl);
       item.set('showRemoveControl', showRemoveControl);
     });
     });
     jns.set('lastObject.showAddControl', showAddControl);
     jns.set('lastObject.showAddControl', showAddControl);
-  },
+  }.observes('hostNameCheckTrigger'),
 
 
+  /**
+   * Mark existing JournalNodes 'isInstalled' and 'showCurrentPrefix'
+   */
   updateJournalNodeInfo: function() {
   updateJournalNodeInfo: function() {
     var jns = this.get('selectedServicesMasters').filterProperty('component_name', 'JOURNALNODE');
     var jns = this.get('selectedServicesMasters').filterProperty('component_name', 'JOURNALNODE');
     var hosts = App.HostComponent.find().filterProperty('componentName', 'JOURNALNODE').mapProperty('hostName');
     var hosts = App.HostComponent.find().filterProperty('componentName', 'JOURNALNODE').mapProperty('hostName');
-    jns.forEach(function(item) {
-      item.set('selectedHost', hosts.pop());
-      item.set('isInstalled', true);
+    hosts.forEach(function(host) {
+      var jn = jns.findProperty('selectedHost', host);
+      if (jn) {
+        jn.set('isInstalled', true);
+        jn.set('showCurrentPrefix', true);
+      }
     });
     });
-  },
+  }.observes('hostNameCheckTrigger'),
 
 
   /**
   /**
    * Callback after load controller data (hosts, host components etc)
    * Callback after load controller data (hosts, host components etc)
@@ -88,7 +94,16 @@ App.ManageJournalNodeWizardStep1Controller = Em.Controller.extend(App.BlueprintM
       self.updateComponent(componentName);
       self.updateComponent(componentName);
     }, self);
     }, self);
     self.set('isLoaded', true);
     self.set('isLoaded', true);
-  }
+  },
+
+  /**
+   * Next button is disabled when there is any change to the original JournalNode hosts
+   */
+  nextButtonDisabled: function() {
+    var currentHosts = this.get('selectedServicesMasters').filterProperty('component_name', 'JOURNALNODE').mapProperty('selectedHost');
+    var originalHosts = App.HostComponent.find().filterProperty('componentName', 'JOURNALNODE').mapProperty('hostName');
+    return currentHosts.sort().join() == originalHosts.sort().join();
+  }.property('hostNameCheckTrigger')
 
 
 });
 });
 
 

+ 1 - 18
ambari-web/app/controllers/main/admin/highAvailability/journalNode/step2_controller.js

@@ -80,6 +80,7 @@ App.ManageJournalNodeWizardStep2Controller = Em.Controller.extend({
 
 
   onLoadConfigs: function (data) {
   onLoadConfigs: function (data) {
     this.set('serverConfigData',data);
     this.set('serverConfigData',data);
+    this.set('content.nameServiceId', data.items[0].properties['dfs.nameservices']);
     this.tweakServiceConfigs(this.get('moveJNConfig.configs'));
     this.tweakServiceConfigs(this.get('moveJNConfig.configs'));
     this.renderServiceConfigs(this.get('moveJNConfig'));
     this.renderServiceConfigs(this.get('moveJNConfig'));
     this.set('isLoaded', true);
     this.set('isLoaded', true);
@@ -122,24 +123,6 @@ App.ManageJournalNodeWizardStep2Controller = Em.Controller.extend({
     return configs;
     return configs;
   },
   },
 
 
-  /**
-   * Find and remove config properties in <code>serverConfigData</code>
-   * @param configsToRemove - map of config sites and properties to remove
-   * @param configs - configuration object
-   * @returns {Object}
-   */
-  removeConfigs:function (configsToRemove, configs) {
-    Em.keys(configsToRemove).forEach(function(site){
-      var siteConfigs = configs.items.findProperty('type', site);
-      if (siteConfigs) {
-        configsToRemove[site].forEach(function (property) {
-          delete siteConfigs.properties[property];
-        });
-      }
-    });
-    return configs;
-  },
-
   renderServiceConfigs: function (_serviceConfig) {
   renderServiceConfigs: function (_serviceConfig) {
     var serviceConfig = App.ServiceConfig.create({
     var serviceConfig = App.ServiceConfig.create({
       serviceName: _serviceConfig.serviceName,
       serviceName: _serviceConfig.serviceName,

+ 24 - 4
ambari-web/app/controllers/main/admin/highAvailability/journalNode/step4_controller.js

@@ -23,14 +23,34 @@ App.ManageJournalNodeWizardStep4Controller = App.ManageJournalNodeProgressPageCo
   clusterDeployState: 'JOURNALNODE_MANAGEMENT',
   clusterDeployState: 'JOURNALNODE_MANAGEMENT',
   tasksMessagesPrefix: 'admin.manageJournalNode.wizard.step',
   tasksMessagesPrefix: 'admin.manageJournalNode.wizard.step',
 
 
-  commands: ['stopServices', 'installJournalNodes', 'startJournalNodes', 'reconfigureHDFS'],
+  commands: ['stopStandbyNameNode', 'stopServices', 'installJournalNodes', 'deleteJournalNodes', 'startJournalNodes', 'reconfigureHDFS'],
 
 
   hdfsSiteTag : "",
   hdfsSiteTag : "",
 
 
+  stopStandbyNameNode: function() {
+    // save who's active and who's standby at this point in time
+    var sbNN = this.get('content.standByNN');
+    this.updateComponent('NAMENODE', sbNN.host_name, 'HDFS',  'INSTALLED');
+  },
+
   installJournalNodes: function () {
   installJournalNodes: function () {
-    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE')
-      .filterProperty('isInstalled', false).mapProperty('hostName');
-    this.createInstallComponentTask('JOURNALNODE', hostNames, "HDFS");
+    var hostNames = App.router.get('manageJournalNodeWizardController').getJournalNodesToAdd();
+    if (hostNames && hostNames.length > 0) {
+      this.createInstallComponentTask('JOURNALNODE', hostNames, "HDFS");
+    } else {
+      this.onTaskCompleted();
+    }
+  },
+
+  deleteJournalNodes: function () {
+    var hosts = App.router.get('manageJournalNodeWizardController').getJournalNodesToDelete();
+    if (hosts && hosts.length > 0) {
+      hosts.forEach(function(host) {
+        this.deleteComponent('JOURNALNODE', host);
+      }, this);
+    } else {
+      this.onTaskCompleted();
+    }
   },
   },
 
 
   startJournalNodes: function () {
   startJournalNodes: function () {

+ 11 - 1
ambari-web/app/controllers/main/admin/highAvailability/journalNode/step6_controller.js

@@ -23,5 +23,15 @@ App.ManageJournalNodeWizardStep6Controller = App.ManageJournalNodeProgressPageCo
   clusterDeployState: 'JOURNALNODE_MANAGEMENT',
   clusterDeployState: 'JOURNALNODE_MANAGEMENT',
   tasksMessagesPrefix: 'admin.manageJournalNode.wizard.step',
   tasksMessagesPrefix: 'admin.manageJournalNode.wizard.step',
 
 
-  commands: ['startServices']
+  commands: ['startZooKeeperServers', 'startActiveNameNode'],
+
+  startZooKeeperServers: function () {
+    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName');
+    this.updateComponent('ZOOKEEPER_SERVER', hostNames, "ZOOKEEPER", "Start");
+  },
+
+  startActiveNameNode: function () {
+    var activeNN = this.get('content.activeNN');
+    this.updateComponent('NAMENODE', activeNN.host_name, "HDFS", "Start");
+  }
 });
 });

+ 30 - 0
ambari-web/app/controllers/main/admin/highAvailability/journalNode/step7_controller.js

@@ -0,0 +1,30 @@
+/**
+ * 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.ManageJournalNodeWizardStep7Controller = Em.Controller.extend({
+
+  name:"manageJournalNodeWizardStep7Controller",
+
+  done: function () {
+    App.router.send("next");
+  }
+
+});
+

+ 35 - 0
ambari-web/app/controllers/main/admin/highAvailability/journalNode/step8_controller.js

@@ -0,0 +1,35 @@
+/**
+ * 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.ManageJournalNodeWizardStep8Controller = App.ManageJournalNodeProgressPageController.extend({
+  name: 'manageJournalNodeWizardStep8Controller',
+  clusterDeployState: 'JOURNALNODE_MANAGEMENT',
+  tasksMessagesPrefix: 'admin.manageJournalNode.wizard.step',
+
+  commands: ['stopHDFS', 'startAllServices'],
+
+  stopHDFS: function () {
+    this.stopServices(["HDFS"], true);
+  },
+
+  startAllServices: function () {
+    this.startServices(false);
+  }
+});

+ 50 - 14
ambari-web/app/controllers/main/admin/highAvailability/journalNode/wizard_controller.js

@@ -23,7 +23,7 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({
 
 
   name: 'manageJournalNodeWizardController',
   name: 'manageJournalNodeWizardController',
 
 
-  totalSteps: 5,
+  totalSteps: 8,
 
 
   /**
   /**
    * Used for hiding back button in wizard
    * Used for hiding back button in wizard
@@ -77,6 +77,11 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({
                 self.loadServicesFromServer();
                 self.loadServicesFromServer();
                 self.loadMasterComponentHosts().done(function () {
                 self.loadMasterComponentHosts().done(function () {
                   self.load('hdfsUser');
                   self.load('hdfsUser');
+                  if (!self.getDBProperty('activeNN')) {
+                    self.saveNNs();
+                  } else {
+                    self.loadNNs();
+                  }
                   dfd.resolve();
                   dfd.resolve();
                 });
                 });
               });
               });
@@ -97,9 +102,7 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({
       {
       {
         type: 'sync',
         type: 'sync',
         callback: function () {
         callback: function () {
-          // TODO load nameservice id
-          this.set('content.nameServiceId', 'ns1');
-          this.setDBProperty('nameServiceId', 'ns1');
+          this.loadNameServiceId();
           this.loadServiceConfigProperties();
           this.loadServiceConfigProperties();
         }
         }
       }
       }
@@ -113,20 +116,26 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({
           this.loadRequestIds();
           this.loadRequestIds();
         }
         }
       }
       }
-    ],
-    '6': [
-      {
-        type: 'sync',
-        callback: function () {
-          this.loadTasksStatuses();
-          this.loadTasksRequestIds();
-          this.loadRequestIds();
-        }
-      }
     ]
     ]
+  },
 
 
+  getJournalNodesToAdd: function () {
+    return this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE')
+      .filterProperty('isInstalled', false).mapProperty('hostName');
   },
   },
 
 
+  getJournalNodesToDelete: function () {
+    var existingHosts = App.HostComponent.find().filterProperty('componentName', 'JOURNALNODE').mapProperty('hostName');
+    var currentJNs = this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE');
+    var removed = existingHosts.filter(function(host) {
+      return currentJNs.filterProperty('hostName', host).length == 0;
+    });
+    return removed;
+  },
+
+  isDeleteOnly: function () {
+    return this.getJournalNodesToAdd().length == 0 && this.getJournalNodesToDelete().length > 0;
+  },
 
 
   /**
   /**
    * Save config properties
    * Save config properties
@@ -156,6 +165,23 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({
   },
   },
 
 
 
 
+  saveNNs: function(activeNN, standByNN) {
+    var activeNN = App.HostComponent.find().findProperty('displayNameAdvanced', 'Active NameNode');
+    var standByNN = App.HostComponent.find().findProperty('displayNameAdvanced', 'Standby NameNode');
+    this.set('content.activeNN', activeNN);
+    this.set('content.standByNN', standByNN);
+    this.setDBProperty('activeNN', activeNN);
+    this.setDBProperty('standByNN', standByNN);
+  },
+
+  loadNNs: function() {
+    var activeNN = this.getDBProperty('activeNN');
+    var standByNN = this.getDBProperty('standByNN');
+    this.set('content.activeNN', activeNN);
+    this.set('content.standByNN', standByNN);
+  },
+
+
   saveConfigTag: function(tag){
   saveConfigTag: function(tag){
     App.db.setManageJournalNodeWizardConfigTag(tag);
     App.db.setManageJournalNodeWizardConfigTag(tag);
     this.set('content.'+[tag.name], tag.value);
     this.set('content.'+[tag.name], tag.value);
@@ -167,6 +193,16 @@ App.ManageJournalNodeWizardController = App.WizardController.extend({
     this.set('content.'+tag, tagVal);
     this.set('content.'+tag, tagVal);
   },
   },
 
 
+  saveNameServiceId: function(nameServiceId){
+    this.setDBProperty('nameServiceId', nameServiceId);
+    this.set('content.nameServiceId', nameServiceId);
+  },
+
+  loadNameServiceId: function(){
+    var nameServiceId = this.getDBProperty('nameServiceId');
+    this.set('content.nameServiceId', nameServiceId);
+  },
+
   /**
   /**
    * Remove all loaded data.
    * Remove all loaded data.
    * Created as copy for App.router.clearAllSteps
    * Created as copy for App.router.clearAllSteps

+ 36 - 8
ambari-web/app/messages.js

@@ -1261,7 +1261,9 @@ Em.I18n.translations = {
   'admin.manageJournalNode.wizard.step3.header': 'Save Namespace',
   'admin.manageJournalNode.wizard.step3.header': 'Save Namespace',
   'admin.manageJournalNode.wizard.step4.header': 'Add/Remove JournalNodes',
   'admin.manageJournalNode.wizard.step4.header': 'Add/Remove JournalNodes',
   'admin.manageJournalNode.wizard.step5.header': 'Format JournalNodes',
   'admin.manageJournalNode.wizard.step5.header': 'Format JournalNodes',
-  'admin.manageJournalNode.wizard.step6.header': 'Start Services',
+  'admin.manageJournalNode.wizard.step6.header': 'Start Active NameNode',
+  'admin.manageJournalNode.wizard.step7.header': 'BootStrap StandBy NameNode',
+  'admin.manageJournalNode.wizard.step8.header': 'Start All Services',
 
 
   'admin.manageJournalNode.wizard.step1.body': 'Assign hosts to JournalNodes',
   'admin.manageJournalNode.wizard.step1.body': 'Assign hosts to JournalNodes',
   'admin.manageJournalNode.wizard.step3.confirm.config.body':'<div class="alert alert-info">' +
   'admin.manageJournalNode.wizard.step3.confirm.config.body':'<div class="alert alert-info">' +
@@ -1269,20 +1271,30 @@ Em.I18n.translations = {
   'The following lists the configuration changes that will be made by the Wizard to manage JournalNode. This information is for <b> review only </b>.' +
   'The following lists the configuration changes that will be made by the Wizard to manage JournalNode. This information is for <b> review only </b>.' +
   '</div>',
   '</div>',
 
 
-  'admin.manageJournalNode.wizard.step4.task0.title': 'Stop Services',
-  'admin.manageJournalNode.wizard.step4.task1.title': 'Add JournalNodes',
-  'admin.manageJournalNode.wizard.step4.task2.title': 'Start JournalNodes',
-  'admin.manageJournalNode.wizard.step4.task3.title': 'Reconfigure HDFS',
-  'admin.manageJournalNode.wizard.step6.task0.title': 'Start All Services',
+  'admin.manageJournalNode.wizard.step4.task0.title' : 'Stop Standby NameNode',
+  'admin.manageJournalNode.wizard.step4.task1.title': 'Stop Services',
+  'admin.manageJournalNode.wizard.step4.task2.title': 'Add JournalNodes',
+  'admin.manageJournalNode.wizard.step4.task3.title': 'Delete JournalNodes',
+  'admin.manageJournalNode.wizard.step4.task4.title': 'Start JournalNodes',
+  'admin.manageJournalNode.wizard.step4.task5.title': 'Reconfigure HDFS',
+  'admin.manageJournalNode.wizard.step6.task0.title': 'Start Zookeeper Server',
+  'admin.manageJournalNode.wizard.step6.task1.title': 'Start Active NameNode',
+  'admin.manageJournalNode.wizard.step8.task0.title': 'Stop HDFS',
+  'admin.manageJournalNode.wizard.step8.task1.title': 'Start All Services',
+
 
 
   'admin.manageJournalNode.wizard.step5.bodyHeader': 'Manual Steps Required: Format JournalNodes',
   'admin.manageJournalNode.wizard.step5.bodyHeader': 'Manual Steps Required: Format JournalNodes',
+  'admin.manageJournalNode.wizard.step7.bodyHeader': 'Manual Steps Required: BootStrap Standby NameNode',
+
 
 
   'admin.manageJournalNode.step4.save.configuration.note' : 'This configuration is created by Manage JournalNode Wizard',
   'admin.manageJournalNode.step4.save.configuration.note' : 'This configuration is created by Manage JournalNode Wizard',
 
 
+  'admin.manageJournalNode.wizard.step8.notice.inProgress': 'Wait all services to be started',
   'admin.manageJournalNode.wizard.progressPage.notice.inProgress': 'Please wait JournalNodes being deployed',
   'admin.manageJournalNode.wizard.progressPage.notice.inProgress': 'Please wait JournalNodes being deployed',
-  'admin.manageJournalNode.wizard.step6.notice.inProgress': 'Please wait for all serviced to be started',
-
+  'admin.manageJournalNode.wizard.step6.notice.inProgress': 'Please wait for related services to be started',
   'admin.manageJournalNode.wizard.step4.notice.inProgress': 'Please wait JournalNodes being deployed',
   'admin.manageJournalNode.wizard.step4.notice.inProgress': 'Please wait JournalNodes being deployed',
+  'admin.manageJournalNode.wizard.step8.notice.completed':'JournalNodes has been processed successfully.',
+
   'admin.manageJournalNode.wizard.step3.body':
   'admin.manageJournalNode.wizard.step3.body':
   '<ol>' +
   '<ol>' +
   '<li>Login to the NameNode host <b>{1}</b>.</li>' +
   '<li>Login to the NameNode host <b>{1}</b>.</li>' +
@@ -1293,6 +1305,7 @@ 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>'+
   '<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: Save Namespace"</b> command, it means there is a recent Checkpoint already and you may proceed without running the <b>"Step 3: Save Namespace"</b> command.</div>' +
   '<div class="alert alert-warn">If the <b>Next</b> button is enabled before you run the <b>"Step 3: Save Namespace"</b> command, it means there is a recent Checkpoint already and you may proceed without running the <b>"Step 3: Save Namespace"</b> command.</div>' +
   '</ol>',
   '</ol>',
+
   'admin.manageJournalNode.wizard.step5.body':
   'admin.manageJournalNode.wizard.step5.body':
   '<ol>' +
   '<ol>' +
   '<li>Login to the NameNode host <b>{1}</b>.</li>' +
   '<li>Login to the NameNode host <b>{1}</b>.</li>' +
@@ -1301,6 +1314,21 @@ Em.I18n.translations = {
   '<li>You will be able to proceed once Ambari detects that the JournalNodes have been initialized successfully.</li>' +
   '<li>You will be able to proceed once Ambari detects that the JournalNodes have been initialized successfully.</li>' +
   '</ol>',
   '</ol>',
 
 
+  'admin.manageJournalNode.wizard.step7.body':
+  '<div class="alert alert-info">' +
+  '<ol start="3">' +
+  '<li>Login to the Additional NameNode host <b>{1}</b>.<br>' +
+  '<div class="alert alert-warn"><strong>Important!</strong> Be sure to login to the Additional NameNode host.<br>This is a different host from previous steps.</div>' +
+  '</li>' +
+  '<li>Initialize the metadata for the Additional NameNode by running:' +
+  '<div class="code-snippet">sudo su {0} -l -c \'hdfs namenode -bootstrapStandby\'</div></li>' +
+  '</ol>' +
+  '</div>' +
+  'Please proceed once you have completed the steps above.',
+
+
+
+
   'admin.highAvailability':' High Availability',
   'admin.highAvailability':' High Availability',
   'admin.highAvailability.button.enable':'Enable NameNode HA',
   'admin.highAvailability.button.enable':'Enable NameNode HA',
   'admin.highAvailability.button.disable':'Disable NameNode HA',
   'admin.highAvailability.button.disable':'Disable NameNode HA',

+ 53 - 2
ambari-web/app/routes/manage_journalnode_routes.js

@@ -115,8 +115,13 @@ module.exports = App.WizardRoute.extend({
       var stepController = router.get('manageJournalNodeWizardStep2Controller');
       var stepController = router.get('manageJournalNodeWizardStep2Controller');
       controller.saveServiceConfigProperties(stepController);
       controller.saveServiceConfigProperties(stepController);
       controller.saveConfigTag(stepController.get("hdfsSiteTag"));
       controller.saveConfigTag(stepController.get("hdfsSiteTag"));
+      controller.saveNameServiceId(stepController.get('content.nameServiceId'));
       App.set('router.nextBtnClickInProgress', false);
       App.set('router.nextBtnClickInProgress', false);
-      router.transitionTo('step3');
+      if (controller.isDeleteOnly()) {
+        router.transitionTo('step4');
+      } else {
+        router.transitionTo('step3');
+      }
     },
     },
     back: Em.Router.transitionTo('step1')
     back: Em.Router.transitionTo('step1')
   }),
   }),
@@ -161,7 +166,11 @@ module.exports = App.WizardRoute.extend({
     next: function (router) {
     next: function (router) {
       var controller = router.get('manageJournalNodeWizardController');
       var controller = router.get('manageJournalNodeWizardController');
       controller.clearTasksData();
       controller.clearTasksData();
-      router.transitionTo('step5');
+      if (controller.isDeleteOnly()) {
+        router.transitionTo('step8');
+      } else {
+        router.transitionTo('step5');
+      }
     }
     }
   }),
   }),
 
 
@@ -200,6 +209,48 @@ module.exports = App.WizardRoute.extend({
     unroutePath: function () {
     unroutePath: function () {
       return false;
       return false;
     },
     },
+    next: function (router) {
+      var controller = router.get('manageJournalNodeWizardController');
+      controller.clearTasksData();
+      router.transitionTo('step7');
+    }
+  }),
+
+  step7: Em.Route.extend({
+    route: '/step7',
+    connectOutlets: function (router) {
+      var controller = router.get('manageJournalNodeWizardController');
+      controller.dataLoading().done(function () {
+        controller.setCurrentStep('7');
+        controller.setLowerStepsDisable(7);
+        controller.loadAllPriorSteps().done(function () {
+          controller.connectOutlet('manageJournalNodeWizardStep7', controller.get('content'));
+        });
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    next: function (router) {
+      router.transitionTo('step8');
+    }
+  }),
+
+  step8: Em.Route.extend({
+    route: '/step8',
+    connectOutlets: function (router) {
+      var controller = router.get('manageJournalNodeWizardController');
+      controller.dataLoading().done(function () {
+        controller.setCurrentStep('8');
+        controller.setLowerStepsDisable(8);
+        controller.loadAllPriorSteps().done(function () {
+          controller.connectOutlet('manageJournalNodeWizardStep8', controller.get('content'));
+        });
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
     next: function (router) {
     next: function (router) {
       var controller = router.get('manageJournalNodeWizardController');
       var controller = router.get('manageJournalNodeWizardController');
       controller.clearTasksData();
       controller.clearTasksData();

+ 2 - 2
ambari-web/app/styles/application.less

@@ -1070,7 +1070,7 @@ h1 {
       margin-left: 0;
       margin-left: 0;
     }
     }
   }
   }
-  #ha-step1, #ha-step4, #ha-step8 {
+  #ha-step1, #ha-step4, #ha-step8, #mjn-step7 {
     .alert.alert-warn {
     .alert.alert-warn {
       margin-top: 10px;
       margin-top: 10px;
       margin-bottom: 10px;
       margin-bottom: 10px;
@@ -1080,7 +1080,7 @@ h1 {
     }
     }
   }
   }
 
 
-  #ha-step4 li, #ha-step6 li, #ha-step8 li {
+  #ha-step4 li, #ha-step6 li, #ha-step8 li, #mjn-step7 li {
     margin-top: 8px;
     margin-top: 8px;
   }
   }
 
 

+ 28 - 5
ambari-web/app/templates/main/admin/highAvailability/journalNode/step2.hbs

@@ -22,24 +22,47 @@
 <div id="manage-journal-node-step2-content" class="well pre-scrollable">
 <div id="manage-journal-node-step2-content" class="well pre-scrollable">
     <div id="step8-info">
     <div id="step8-info">
         <table id="manage-journal-node-step2-review-table">
         <table id="manage-journal-node-step2-review-table">
+            {{#if view.journalNodesToAdd.length}}
             <tr>
             <tr>
                 <td>{{t admin.highAvailability.wizard.step3.journalNode}}</td>
                 <td>{{t admin.highAvailability.wizard.step3.journalNode}}</td>
                 <td>
                 <td>
                     <ul>
                     <ul>
-                        {{#each item in view.journalNodes}}
-                            <li>{{item.hostName}}</li>
+                        {{#each item in view.journalNodesToAdd}}
+                            <li>{{item}}</li>
                         {{/each}}
                         {{/each}}
                     </ul>
                     </ul>
                 </td>
                 </td>
                 <td>
                 <td>
                     <ul>
                     <ul>
-                        {{#each item in view.journalNodes}}
-                            <li><span class="to-be-installed-green"><i
-                                    class="icon-plus"></i>&nbsp;{{t admin.highAvailability.wizard.step3.toBeInstalled}}</span></li>
+                        {{#each item in view.journalNodesToAdd}}
+                            <li><span class="to-be-installed-green"><i class="icon-plus"></i>
+                                &nbsp;{{t admin.highAvailability.wizard.step3.toBeInstalled}}</span></li>
                         {{/each}}
                         {{/each}}
                     </ul>
                     </ul>
                 </td>
                 </td>
             </tr>
             </tr>
+            {{/if}}
+
+            {{#if view.journalNodesToDelete.length}}
+            <tr>
+                <td>{{t admin.highAvailability.wizard.step3.journalNode}}</td>
+                <td>
+                    <ul>
+                        {{#each item in view.journalNodesToDelete}}
+                            <li>{{item}}</li>
+                        {{/each}}
+                    </ul>
+                </td>
+                <td>
+                    <ul>
+                        {{#each item in view.journalNodesToDelete}}
+                            <li><span class="to-be-disabled-red"><i class="icon-minus"></i>
+                                &nbsp;{{t admin.highAvailability.wizard.step3.toBeDeleted}}</span></li>
+                        {{/each}}
+                    </ul>
+                </td>
+            </tr>
+            {{/if}}
         </table>
         </table>
     </div>
     </div>
 </div>
 </div>

+ 24 - 0
ambari-web/app/templates/main/admin/highAvailability/journalNode/step7.hbs

@@ -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.
+}}
+<div id="mjn-step7">
+    <h2>{{t admin.manageJournalNode.wizard.step7.bodyHeader}}</h2>
+    {{{view.step7BodyText}}}
+    <div class="btn-area">
+        <a class="btn btn-success pull-right" {{action done target="controller"}}>{{t common.next}} &rarr;</a>
+    </div>
+</div>

+ 18 - 0
ambari-web/app/templates/main/admin/highAvailability/journalNode/step8.hbs

@@ -0,0 +1,18 @@
+{{!
+* 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.
+}}
+{{template "templates/common/progress"}}

+ 2 - 0
ambari-web/app/templates/main/admin/highAvailability/journalNode/wizard.hbs

@@ -31,6 +31,8 @@
                             <li {{bindAttr class="isStep4:active view.isStep4Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep4 target="controller"}}>{{t admin.manageJournalNode.wizard.step4.header}}</a></li>
                             <li {{bindAttr class="isStep4:active view.isStep4Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep4 target="controller"}}>{{t admin.manageJournalNode.wizard.step4.header}}</a></li>
                             <li {{bindAttr class="isStep5:active view.isStep5Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep5 target="controller"}}>{{t admin.manageJournalNode.wizard.step5.header}}</a></li>
                             <li {{bindAttr class="isStep5:active view.isStep5Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep5 target="controller"}}>{{t admin.manageJournalNode.wizard.step5.header}}</a></li>
                             <li {{bindAttr class="isStep6:active view.isStep6Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep6 target="controller"}}>{{t admin.manageJournalNode.wizard.step6.header}}</a></li>
                             <li {{bindAttr class="isStep6:active view.isStep6Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep6 target="controller"}}>{{t admin.manageJournalNode.wizard.step6.header}}</a></li>
+                            <li {{bindAttr class="isStep7:active view.isStep7Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep7 target="controller"}}>{{t admin.manageJournalNode.wizard.step7.header}}</a></li>
+                            <li {{bindAttr class="isStep8:active view.isStep8Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep8 target="controller"}}>{{t admin.manageJournalNode.wizard.step8.header}}</a></li>
                         </ul>
                         </ul>
                     </div>
                     </div>
                 </div>
                 </div>

+ 2 - 0
ambari-web/app/views.js

@@ -182,6 +182,8 @@ require('views/main/admin/highAvailability/journalNode/step3_view');
 require('views/main/admin/highAvailability/journalNode/step4_view');
 require('views/main/admin/highAvailability/journalNode/step4_view');
 require('views/main/admin/highAvailability/journalNode/step5_view');
 require('views/main/admin/highAvailability/journalNode/step5_view');
 require('views/main/admin/highAvailability/journalNode/step6_view');
 require('views/main/admin/highAvailability/journalNode/step6_view');
+require('views/main/admin/highAvailability/journalNode/step7_view');
+require('views/main/admin/highAvailability/journalNode/step8_view');
 require('views/main/admin/highAvailability/resourceManager/wizard_view');
 require('views/main/admin/highAvailability/resourceManager/wizard_view');
 require('views/main/admin/highAvailability/resourceManager/step1_view');
 require('views/main/admin/highAvailability/resourceManager/step1_view');
 require('views/main/admin/highAvailability/resourceManager/step2_view');
 require('views/main/admin/highAvailability/resourceManager/step2_view');

+ 9 - 3
ambari-web/app/views/main/admin/highAvailability/journalNode/step2_view.js

@@ -22,12 +22,18 @@ var App = require('app');
 App.ManageJournalNodeWizardStep2View = Em.View.extend({
 App.ManageJournalNodeWizardStep2View = Em.View.extend({
 
 
   templateName: require('templates/main/admin/highAvailability/journalNode/step2'),
   templateName: require('templates/main/admin/highAvailability/journalNode/step2'),
+  aaa: '',
   didInsertElement: function () {
   didInsertElement: function () {
     this.get('controller').loadStep();
     this.get('controller').loadStep();
   },
   },
-  journalNodes: function() {
-    return this.get('controller.content.masterComponentHosts').filterProperty('component', 'JOURNALNODE').filterProperty('isInstalled', false);
-  }.property('controller.content.masterComponentHosts@each'),
+
+  journalNodesToAdd: function () {
+    return App.router.get('manageJournalNodeWizardController').getJournalNodesToAdd();
+  }.property(),
+
+  journalNodesToDelete: function () {
+    return App.router.get('manageJournalNodeWizardController').getJournalNodesToDelete();
+  }.property(),
 
 
   isBackButtonVisible: false
   isBackButtonVisible: false
 });
 });

+ 2 - 2
ambari-web/app/views/main/admin/highAvailability/journalNode/step3_view.js

@@ -22,8 +22,8 @@ var App = require('app');
 App.ManageJournalNodeWizardStep3View = App.HighAvailabilityWizardStep4View.extend({
 App.ManageJournalNodeWizardStep3View = App.HighAvailabilityWizardStep4View.extend({
   templateName: require('templates/main/admin/highAvailability/journalNode/step3'),
   templateName: require('templates/main/admin/highAvailability/journalNode/step3'),
   step3BodyText: function () {
   step3BodyText: function () {
-    var nN = this.get('controller.content.masterComponentHosts').filterProperty('component', 'NAMENODE').findProperty('isInstalled', true);
-    return Em.I18n.t('admin.manageJournalNode.wizard.step3.body').format(this.get('controller.content.hdfsUser'), nN.hostName);
+    var nN = this.get('controller.content.activeNN');
+    return Em.I18n.t('admin.manageJournalNode.wizard.step3.body').format(this.get('controller.content.hdfsUser'), nN.host_name);
   }.property('controller.content.masterComponentHosts'),
   }.property('controller.content.masterComponentHosts'),
 
 
 });
 });

+ 2 - 3
ambari-web/app/views/main/admin/highAvailability/journalNode/step5_view.js

@@ -28,9 +28,8 @@ App.ManageJournalNodeWizardStep5View = Em.View.extend({
   },
   },
 
 
   step5BodyText: function () {
   step5BodyText: function () {
-    var nN = this.get('controller.content.masterComponentHosts').filterProperty('component', 'NAMENODE').findProperty('isInstalled', true);
-    var addNN = this.get('controller.content.masterComponentHosts').filterProperty('component', 'NAMENODE').findProperty('isInstalled', false);
-    return Em.I18n.t('admin.manageJournalNode.wizard.step5.body').format(this.get('controller.content.hdfsUser'), nN.hostName, addNN);
+    var activeNN = this.get('controller.content.activeNN');
+    return Em.I18n.t('admin.manageJournalNode.wizard.step5.body').format(this.get('controller.content.hdfsUser'), activeNN.host_name);
   }.property('controller.content.masterComponentHosts'),
   }.property('controller.content.masterComponentHosts'),
 
 
   jnCheckPointText: function () {
   jnCheckPointText: function () {

+ 31 - 0
ambari-web/app/views/main/admin/highAvailability/journalNode/step7_view.js

@@ -0,0 +1,31 @@
+/**
+ * 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.ManageJournalNodeWizardStep7View = Em.View.extend({
+
+  templateName: require('templates/main/admin/highAvailability/journalNode/step7'),
+
+  step7BodyText: function () {
+    var standByNN = this.get('controller.content.standByNN');
+    return Em.I18n.t('admin.manageJournalNode.wizard.step7.body').format(this.get('controller.content.hdfsUser'), standByNN.host_name);
+  }.property('controller.content.masterComponentHosts')
+
+});

+ 29 - 0
ambari-web/app/views/main/admin/highAvailability/journalNode/step8_view.js

@@ -0,0 +1,29 @@
+/**
+ * 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.ManageJournalNodeWizardStep8View = App.ManageJournalNodeProgressPageView.extend({
+
+  templateName: require('templates/main/admin/highAvailability/journalNode/step8'),
+
+  submitButtonText: Em.I18n.t('common.done'),
+
+  noticeCompleted: Em.I18n.t('admin.manageJournalNode.wizard.step8.notice.completed')
+});

+ 2 - 22
ambari-web/app/views/main/admin/highAvailability/journalNode/wizard_view.js

@@ -19,28 +19,8 @@
 
 
 var App = require('app');
 var App = require('app');
 
 
-App.ManageJournalNodeWizardView = Em.View.extend({
+App.ManageJournalNodeWizardView = Em.View.extend(App.WizardMenuMixin, {
 
 
-  templateName: require('templates/main/admin/highAvailability/journalNode/wizard'),
-
-  isStep1Disabled: function () {
-    return this.isStepDisabled(1);
-  }.property('controller.isStepDisabled.@each.value').cacheable(),
-
-  isStep2Disabled: function () {
-    return this.isStepDisabled(2);
-  }.property('controller.isStepDisabled.@each.value').cacheable(),
-
-  isStep3Disabled: function () {
-    return this.isStepDisabled(3);
-  }.property('controller.isStepDisabled.@each.value').cacheable(),
-
-  isStep4Disabled: function () {
-    return this.isStepDisabled(4);
-  }.property('controller.isStepDisabled.@each.value').cacheable(),
-
-  isStepDisabled: function (index) {
-    return this.get('controller.isStepDisabled').findProperty('step', index).get('value');
-  }
+  templateName: require('templates/main/admin/highAvailability/journalNode/wizard')
 
 
 });
 });