This is an automated email from the ASF dual-hosted git repository. ishanbha pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push: new 99e14e9 [AMBARI-24834] UI: Configure Rolling Restart Batch Options for service rolling restart. 99e14e9 is described below commit 99e14e98ec5d3744f6ea8dba6a4ba2a9f7d26d63 Author: Ishan Bhatt <ishanbhatt.1...@gmail.com> AuthorDate: Fri Oct 26 06:40:58 2018 -0700 [AMBARI-24834] UI: Configure Rolling Restart Batch Options for service rolling restart. --- ambari-web/app/controllers/main/service/item.js | 4 +- ambari-web/app/utils/batch_scheduled_requests.js | 123 +++++++++++++++------ .../app/views/common/service_restart_view.js | 21 +++- 3 files changed, 109 insertions(+), 39 deletions(-) diff --git a/ambari-web/app/controllers/main/service/item.js b/ambari-web/app/controllers/main/service/item.js index a900edb..dec779d 100644 --- a/ambari-web/app/controllers/main/service/item.js +++ b/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; diff --git a/ambari-web/app/utils/batch_scheduled_requests.js b/ambari-web/app/utils/batch_scheduled_requests.js index f9948eb..a9ffaa9 100644 --- a/ambari-web/app/utils/batch_scheduled_requests.js +++ b/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) { diff --git a/ambari-web/app/views/common/service_restart_view.js b/ambari-web/app/views/common/service_restart_view.js index e9beb82..6e97792 100644 --- a/ambari-web/app/views/common/service_restart_view.js +++ b/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'),