Repository: ambari Updated Branches: refs/heads/trunk 9ef9bd501 -> 87d629b53
AMBARI-20211 UI asking user to "refresh yarn queue" on stopped yarn service, which results to infinite refresh time as yarn is stopped. (ababiichuk) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/87d629b5 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/87d629b5 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/87d629b5 Branch: refs/heads/trunk Commit: 87d629b5343d23890662ea6813c6be393d3c65fd Parents: 9ef9bd5 Author: ababiichuk <[email protected]> Authored: Mon Feb 27 17:00:31 2017 +0200 Committer: ababiichuk <[email protected]> Committed: Mon Feb 27 18:00:47 2017 +0200 ---------------------------------------------------------------------- .../configs/component_actions_by_configs.js | 44 +-- .../component_actions_by_configs_test.js | 301 +++++++++++++++++++ 2 files changed, 326 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/87d629b5/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js b/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js index f52d1af..6106f58 100644 --- a/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js +++ b/ambari-web/app/mixins/main/service/configs/component_actions_by_configs.js @@ -61,27 +61,33 @@ App.ComponentActionsByConfigs = Em.Mixin.create({ }); if (configs.length) { - if(config_action.get('fileName') === 'capacity-scheduler.xml' && !self.isYarnQueueRefreshed) { - var hsiInstance = App.HostComponent.find().filterProperty('componentName', "HIVE_SERVER_INTERACTIVE"); - if(self.get('content.serviceName') === 'HIVE') { - // Auto refresh yarn capacity scheduler if capacity-scheduler configs are changed from Hive configs page - self.popupPrimaryButtonCallback(config_action); - // Show a popup to restart HSI if HSI is enabled - if(hsiInstance.length > 0) { - self.showHsiRestartPopup(hsiInstance); - } - } else { - self.configAction = config_action; - var body = config_action.get('popupProperties').body; - if(config_action.get('popupProperties').hasOwnProperty('conditionalWarning') && config_action.get('popupProperties').conditionalWarning === true) { - // Check if Hive Server 2 Interactive is enabled and show a warning message if it is enabled - if(hsiInstance.length > 0) { - body += "<br/><br/>" + config_action.get('popupProperties').warningMessage; + var hostComponents = App.HostComponent.find(); + if (config_action.get('fileName') === 'capacity-scheduler.xml' && !self.isYarnQueueRefreshed) { + var isRMRunning = hostComponents.some(function (component) { + return component.get('componentName') === 'RESOURCEMANAGER' && component.get('isRunning'); + }); + if (isRMRunning) { + var hsiInstance = hostComponents.filterProperty('componentName', 'HIVE_SERVER_INTERACTIVE'); + if (self.get('content.serviceName') === 'HIVE') { + // Auto refresh yarn capacity scheduler if capacity-scheduler configs are changed from Hive configs page + self.popupPrimaryButtonCallback(config_action); + // Show a popup to restart HSI if HSI is enabled + if (hsiInstance.length > 0) { + self.showHsiRestartPopup(hsiInstance); } + } else { + self.configAction = config_action; + var body = config_action.get('popupProperties').body; + if (config_action.get('popupProperties').hasOwnProperty('conditionalWarning') && config_action.get('popupProperties').conditionalWarning === true) { + // Check if Hive Server 2 Interactive is enabled and show a warning message if it is enabled + if (hsiInstance.length > 0) { + body += "<br/><br/>" + config_action.get('popupProperties').warningMessage; + } + } + App.showConfirmationPopup(function () { + self.popupPrimaryButtonCallback(config_action); + }, body, null, Em.I18n.t('popup.confirmation.commonHeader'), config_action.get('popupProperties').primaryButton.label, false, 'refresh_yarn_queues') } - App.showConfirmationPopup(function () { - self.popupPrimaryButtonCallback(config_action); - }, body, null, Em.I18n.t('popup.confirmation.commonHeader'), config_action.get('popupProperties').primaryButton.label, false, 'refresh_yarn_queues') } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/87d629b5/ambari-web/test/mixins/main/service/configs/component_actions_by_configs_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/mixins/main/service/configs/component_actions_by_configs_test.js b/ambari-web/test/mixins/main/service/configs/component_actions_by_configs_test.js index 1a93a26..f987c52 100644 --- a/ambari-web/test/mixins/main/service/configs/component_actions_by_configs_test.js +++ b/ambari-web/test/mixins/main/service/configs/component_actions_by_configs_test.js @@ -519,4 +519,305 @@ describe('App.ComponentActionsByConfigs', function () { }); }); + describe('#showPopup', function () { + + var testCases = [ + { + configActions: [], + popupPrimaryButtonCallbackCallCount: 0, + showHsiRestartPopupCallCount: 0, + showConfirmationPopupCallCount: 0, + title: 'no config actions' + }, + { + configActions: [ + { + actionType: 'none' + }, + { + actionType: null + }, + {} + ], + popupPrimaryButtonCallbackCallCount: 0, + showHsiRestartPopupCallCount: 0, + showConfirmationPopupCallCount: 0, + title: 'no popup config actions' + }, + { + configActions: [ + Em.Object.create({ + actionType: 'showPopup', + fileName: 'f0' + }) + ], + mixinProperties: { + allConfigs: [ + Em.Object.create({ + filename: 'f1', + value: 0, + initialValue: 1 + }) + ] + }, + popupPrimaryButtonCallbackCallCount: 0, + showHsiRestartPopupCallCount: 0, + showConfirmationPopupCallCount: 0, + title: 'no associated configs' + }, + { + configActions: [ + Em.Object.create({ + actionType: 'showPopup', + fileName: 'f2' + }) + ], + mixinProperties: { + allConfigs: [ + Em.Object.create({ + filename: 'f2', + value: 0, + initialValue: 0 + }) + ] + }, + popupPrimaryButtonCallbackCallCount: 0, + showHsiRestartPopupCallCount: 0, + showConfirmationPopupCallCount: 0, + title: 'no changes in associated configs' + }, + { + configActions: [ + Em.Object.create({ + actionType: 'showPopup', + fileName: 'f3' + }) + ], + mixinProperties: { + allConfigs: [ + Em.Object.create({ + filename: 'f3', + value: 0, + initialValue: 1 + }) + ] + }, + popupPrimaryButtonCallbackCallCount: 0, + showHsiRestartPopupCallCount: 0, + showConfirmationPopupCallCount: 0, + title: 'no capacity-scheduler actions defined' + }, + { + configActions: [ + Em.Object.create({ + actionType: 'showPopup', + fileName: 'capacity-scheduler.xml' + }) + ], + mixinProperties: { + allConfigs: [ + Em.Object.create({ + filename: 'capacity-scheduler.xml', + value: 0, + initialValue: 1 + }) + ], + isYarnQueueRefreshed: true + }, + popupPrimaryButtonCallbackCallCount: 0, + showHsiRestartPopupCallCount: 0, + showConfirmationPopupCallCount: 0, + title: 'YARN queue refreshed' + }, + { + configActions: [ + Em.Object.create({ + actionType: 'showPopup', + fileName: 'capacity-scheduler.xml' + }) + ], + hostComponents: [ + Em.Object.create({ + componentName: 'RESOURCEMANAGER' + }), + Em.Object.create({ + componentName: 'RESOURCEMANAGER', + isRunning: false + }), + Em.Object.create({ + componentName: 'COMPONENT', + isRunning: true + }) + ], + mixinProperties: { + allConfigs: [ + Em.Object.create({ + filename: 'capacity-scheduler.xml', + value: 0, + initialValue: 1 + }) + ], + isYarnQueueRefreshed: false + }, + popupPrimaryButtonCallbackCallCount: 0, + showHsiRestartPopupCallCount: 0, + showConfirmationPopupCallCount: 0, + title: 'no ResourceManagers running' + }, + { + configActions: [ + Em.Object.create({ + actionType: 'showPopup', + fileName: 'capacity-scheduler.xml' + }) + ], + hostComponents: [ + Em.Object.create({ + componentName: 'RESOURCEMANAGER' + }), + Em.Object.create({ + componentName: 'RESOURCEMANAGER', + isRunning: false + }), + Em.Object.create({ + componentName: 'RESOURCEMANAGER', + isRunning: true + }), + Em.Object.create({ + componentName: 'HIVE_SERVER_INTERACTIVE' + }) + ], + mixinProperties: { + 'allConfigs': [ + Em.Object.create({ + filename: 'capacity-scheduler.xml', + value: 0, + initialValue: 1 + }) + ], + 'isYarnQueueRefreshed': false, + 'content.serviceName': 'HIVE' + }, + popupPrimaryButtonCallbackCallCount: 1, + showHsiRestartPopupCallCount: 1, + showConfirmationPopupCallCount: 0, + title: 'change from Hive page, Hive Server Interactive present' + }, + { + configActions: [ + Em.Object.create({ + actionType: 'showPopup', + fileName: 'capacity-scheduler.xml' + }) + ], + hostComponents: [ + Em.Object.create({ + componentName: 'RESOURCEMANAGER' + }), + Em.Object.create({ + componentName: 'RESOURCEMANAGER', + isRunning: false + }), + Em.Object.create({ + componentName: 'RESOURCEMANAGER', + isRunning: true + }) + ], + mixinProperties: { + 'allConfigs': [ + Em.Object.create({ + filename: 'capacity-scheduler.xml', + value: 0, + initialValue: 1 + }) + ], + 'isYarnQueueRefreshed': false, + 'content.serviceName': 'HIVE' + }, + popupPrimaryButtonCallbackCallCount: 1, + showHsiRestartPopupCallCount: 0, + showConfirmationPopupCallCount: 0, + title: 'change from Hive page, no Hive Server Interactive' + }, + { + configActions: [ + Em.Object.create({ + actionType: 'showPopup', + fileName: 'capacity-scheduler.xml', + popupProperties: { + primaryButton: {} + } + }) + ], + hostComponents: [ + Em.Object.create({ + componentName: 'RESOURCEMANAGER' + }), + Em.Object.create({ + componentName: 'RESOURCEMANAGER', + isRunning: false + }), + Em.Object.create({ + componentName: 'RESOURCEMANAGER', + isRunning: true + }) + ], + mixinProperties: { + 'allConfigs': [ + Em.Object.create({ + filename: 'capacity-scheduler.xml', + value: 0, + initialValue: 1 + }) + ], + 'isYarnQueueRefreshed': false, + 'content.serviceName': 'YARN' + }, + popupPrimaryButtonCallbackCallCount: 0, + showHsiRestartPopupCallCount: 0, + showConfirmationPopupCallCount: 1, + title: 'change from YARN page' + } + ]; + + testCases.forEach(function (test) { + + describe(test.title, function () { + + beforeEach(function () { + sinon.stub(App.ConfigAction, 'find').returns(test.configActions); + sinon.stub(App.HostComponent, 'find').returns(test.hostComponents || []); + sinon.stub(mixin, 'popupPrimaryButtonCallback', Em.K); + sinon.stub(mixin, 'showHsiRestartPopup', Em.K); + sinon.stub(App, 'showConfirmationPopup', Em.K); + mixin.setProperties(test.mixinProperties); + mixin.showPopup(); + }); + + afterEach(function () { + App.ConfigAction.find.restore(); + App.HostComponent.find.restore(); + mixin.popupPrimaryButtonCallback.restore(); + mixin.showHsiRestartPopup.restore(); + App.showConfirmationPopup.restore(); + }); + + it('popup callback', function () { + expect(mixin.popupPrimaryButtonCallback.callCount).to.eql(test.popupPrimaryButtonCallbackCallCount); + }); + + it('HSI restart popup', function () { + expect(mixin.showHsiRestartPopup.callCount).to.eql(test.showHsiRestartPopupCallCount); + }); + + it('confirmation popup', function () { + expect(App.showConfirmationPopup.callCount).to.eql(test.showConfirmationPopupCallCount); + }); + + }); + + }); + + }); + }); \ No newline at end of file
