Pārlūkot izejas kodu

[AMBARI-24834] UI: Configure Rolling Restart Batch Options for service rolling restart.

Ishan Bhatt 7 gadi atpakaļ
vecāks
revīzija
99e14e98ec

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

@@ -970,7 +970,7 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow
     batchUtils.showServiceRestartPopup(this.get('content.serviceName'), this.getMastersForRestart.bind(this), this.getSlavesForRestart.bind(this));
   },
   restartServiceMastersOnly: function () {
-    batchUtils.showServiceRestartPopup(this.get('content.serviceName'), this.getMastersForRestart.bind(this));
+    batchUtils.showServiceRestartPopup(this.get('content.serviceName'), this.getMastersForRestart.bind(this), null);
   },
 
   restartServiceSlavesOnly: function () {
@@ -1058,7 +1058,7 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow
       if (sNameNode) hostCompOrdered.push(sNameNode);
 
       //Add NameNode
-      const namenode = hdfsService.get('namenode') || App.HostComponent.find().findProperty('componentName', 'SECONDARY_NAMENODE');
+      const namenode = hdfsService.get('namenode') || App.HostComponent.find().findProperty('componentName', 'NAMENODE');
       if (namenode) hostCompOrdered.push(namenode);
     }
     return hostCompOrdered;

+ 92 - 31
ambari-web/app/utils/batch_scheduled_requests.js

@@ -351,14 +351,14 @@ module.exports = {
    * @param {Number} batchSize size of each batch
    * @returns {Array} list of batches
    */
-  getBatchesForRollingRestartRequest: function(restartHostComponents, batchSize) {
+  getBatchesForRollingRestartRequest: function(restartHostComponents, batchSize, previousOrderId) {
     var hostIndex = 0,
         batches = [],
         batchCount = Math.ceil(restartHostComponents.length / batchSize),
         sampleHostComponent = restartHostComponents.objectAt(0),
         componentName = sampleHostComponent.get('componentName'),
-        serviceName = sampleHostComponent.get('serviceName');
-
+        serviceName = sampleHostComponent.get('serviceName') || sampleHostComponent.get('service.serviceName');
+        previousOrderId = previousOrderId || 0;
     for ( var count = 0; count < batchCount; count++) {
       var hostNames = [];
       for ( var hc = 0; hc < batchSize && hostIndex < restartHostComponents.length; hc++) {
@@ -366,7 +366,7 @@ module.exports = {
       }
       if (hostNames.length) {
         batches.push({
-          "order_id" : count + 1,
+          "order_id" : previousOrderId + count + 1,
           "type" : "POST",
           "uri" : "/clusters/" + App.get('clusterName') + "/requests",
           "RequestBodyInfo" : {
@@ -508,25 +508,75 @@ module.exports = {
   showServiceRestartPopup: function (serviceName, mastersForRestart, workersForRestart) {
 
     let self = this;
-    const isRestartAll = !!(mastersForRestart && workersForRestart);
-    const isMastersOnly = !!(mastersForRestart && !workersForRestart);
-    const isSlavesOnly = !!(!mastersForRestart && workersForRestart);
+
+    let viewExtend = {
+
+      masterComponents: undefined,
+
+      slaveComponents: undefined,
+
+      didInsertElement: function() {
+        this.set('parentView.innerView', this);
+        if (mastersForRestart) this.set('masterComponents', mastersForRestart(serviceName));
+        if (workersForRestart) {
+          this.set('slaveComponents', workersForRestart(serviceName));
+          this.set('componentHostRackInfoMap', this.componentHostRackInfo());
+        }
+        this.initDefaultConfigs();
+      },
+
+      componentHostRackInfo: function () {
+        const slaveComponents = this.get('slaveComponents');
+        const componentNames = slaveComponents.mapProperty('componentName').uniq();
+        const hostModel = App.Host.find();
+        let componentRackInfo = {};
+        componentNames.forEach((component) => {
+          let hostNames = slaveComponents.filterProperty('componentName', component).mapProperty('hostName');
+          let hostRackInfo = {};
+          hostNames.forEach((hostName) => {
+            hostRackInfo[hostName] = hostModel.findProperty('hostName', hostName).get('rack');
+          });
+          componentRackInfo[component] = hostRackInfo;
+        });
+        return componentRackInfo;
+      }
+    };
 
     App.ModalPopup.show({
       header: Em.I18n.t('common.configure.restart'),
-      bodyClass: App.ServiceRestartView.extend({
-        isRestartAll, isMastersOnly, isSlavesOnly
-      }),
+      bodyClass: App.ServiceRestartView.extend(viewExtend),
       primary: Em.I18n.t('common.restart'),
       primaryClass: 'btn-warning',
       classNames: ['common-modal-wrapper'],
       modalDialogClasses: ['modal-lg'],
+
       onPrimary: function () {
-        let isRollingRestart = this.get('innerView.useRolling');
+        const isRollingRestart = this.get('innerView.useRolling');
         if (isRollingRestart) {
-          //TODO introduce masters and workers logic
-          const masters = mastersForRestart(serviceName);
-          self.rollingRestartRequest(masters, serviceName);
+          //let rollingRestartConfigs = this.get('innerView').getRestartConfigs();
+          //restart configs will be applied when we have the BE capability to override them in individual batches.
+          const masterComps = this.get('innerView.masterComponents');
+          let masterBatch = [];
+          let orderId = 0;
+          if (!!masterComps) {
+            let batchesForRestart = self.rollingRestartMastersBatches(masterComps, serviceName);
+            masterBatch.push(...batchesForRestart);
+            orderId += batchesForRestart.length;
+          }
+
+          const slaveComps = this.get('innerView.slaveComponents');
+          let workersBatch = [];
+          if (!!slaveComps) {
+            const componentNames = slaveComps.mapProperty('componentName').uniq();
+            componentNames.forEach((component) => {
+              let restartComponent = slaveComps.filterProperty('componentName', component);
+              let batchSize = this.get('innerView').getNoOfHosts(component);
+              let batchesForRestart = self.getBatchesForRollingRestartRequest(restartComponent, batchSize, orderId);
+              workersBatch.push(...batchesForRestart);
+              orderId += batchesForRestart.length;
+            });
+          }
+          self.sendRollingRestartRequest(masterBatch, workersBatch);
         } else {
           const query = Em.Object.create({status: 'INIT'});
           const serviceDisplayName = App.Service.find().findProperty('serviceName', serviceName).get('displayName');
@@ -537,21 +587,21 @@ module.exports = {
     })
   },
 
+
   /**
-   * Creates batches and send rolling restart request.
-   * TODO modify this to include request to restart workers.
+   * Creates batches for masters to be used for rolling restart.
    * @param {App.hostComponent[]} [hostComponents] list of hostComponents that should be restarted
    * @param {String} serviceName: Name of the service to be restarted.
    */
 
-  rollingRestartRequest: function (hostComponents, serviceName) {
+  rollingRestartMastersBatches: function (hostComponents, serviceName) {
     let batches = [];
-    for (let i=0; i<hostComponents.length; i++) {
+    for (let i = 0; i < hostComponents.length; i++) {
       const hostName = hostComponents[i].get('hostName');
       const component = hostComponents[i].get('componentName');
       const context = "RESTART " + hostComponents[i].get('displayName');
       batches.push({
-        "order_id": i+1,
+        "order_id": i + 1,
         "type": 'POST',
         "uri": "/clusters/" + App.get('clusterName') + "/requests/",
         "RequestBodyInfo": {
@@ -567,21 +617,32 @@ module.exports = {
         }
       })
     }
-    App.ajax.send({
-      name: 'common.batch.request_schedules',
-      sender: this,
-      data: {
-        intervalTimeSeconds: 1,
-        tolerateSize: 0,
-        batches: batches
-      },
-      success: 'serviceRestartSuccess',
-      showLoadingPopup: true
-    });
+    return batches;
+  },
+
+  sendRollingRestartRequest: function (mastersBatch, workersBatch) {
+
+    let batches = [];
+    if (mastersBatch && mastersBatch.length > 0) batches.push(...mastersBatch);
+    if (workersBatch && workersBatch.length > 0) batches.push(...workersBatch);
+
+    if (batches.length > 0) {
+      App.ajax.send({
+        name: 'common.batch.request_schedules',
+        sender: this,
+        data: {
+          intervalTimeSeconds: 1,
+          tolerateSize: 0,
+          batches: batches
+        },
+        success: 'serviceRestartSuccess',
+        showLoadingPopup: true
+      });
+    }
   },
 
   /**
-   * Callback function for rollingRestartRequest that shows BG Modal if restart request sent successfully
+   * Callback function for restartMastersBatchRequest that shows BG Modal if restart request sent successfully
    * TODO replace it with a progress view that shows rolling restart tasks
    */
   serviceRestartSuccess: function (data) {

+ 15 - 6
ambari-web/app/views/common/service_restart_view.js

@@ -21,15 +21,10 @@ App.ServiceRestartView = Em.View.extend({
 
   templateName: require('templates/common/service_restart'),
 
-  didInsertElement: function() {
-    this.set('parentView.innerView', this);
-    this.initDefaultConfigs();
-  },
-
   initDefaultConfigs: function () {
     this.set('useRolling', true);
     this.set('showAdvancedOptions', false);
-    this.set('showBatchRackOptions', this.get('isRestartAll') || this.get('isSlavesOnly'));
+    this.set('showBatchRackOptions', !!this.get('slaveComponents'));
     this.set('batchesOfHosts', true);
     this.set('noOfHostsInBatch', 10);
     this.set('batchIntervalHosts', 120);
@@ -44,6 +39,20 @@ App.ServiceRestartView = Em.View.extend({
     this.set('pauseAfterFirst', false);
   },
 
+
+  getRestartConfigs: function() {
+    return Em.Object.create({
+      batchInterval: this.get('batchesOfHosts') ? this.get('batchIntervalHosts') : this.get('batchIntervalRacks'),
+      maxFailures: this.get('maxFailuresTolerated'),
+      maxFailuresPerBatch: this.get('maxFailuresTolerated'),
+    });
+  },
+
+  getNoOfHosts: function (component) {
+    if (this.get('batchesOfHosts')) return this.get('noOfHostsInBatch');
+    return Math.ceil(this.get('percentRackStarted')*100/(this.get('componentHostRackInfoMap')[component].size()));
+  },
+
   rollingRestartRadioButton: App.RadioButtonView.extend({
     labelTranslate: 'common.rolling',
     checked: Em.computed.alias('parentView.useRolling'),