Repository: ambari Updated Branches: refs/heads/trunk 09c575a22 -> 4da141ec6
AMBARI-6795. Expose ability to cancel requests in the UI (alexantonenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4da141ec Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4da141ec Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4da141ec Branch: refs/heads/trunk Commit: 4da141ec696f5cba7a6bb8abba0648bafa630630 Parents: 09c575a Author: Alex Antonenko <[email protected]> Authored: Fri Aug 8 20:58:30 2014 +0300 Committer: Alex Antonenko <[email protected]> Committed: Fri Aug 8 20:58:30 2014 +0300 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 3 +- ambari-web/app/config.js | 3 +- ambari-web/app/messages.js | 5 ++ ambari-web/app/styles/application.less | 5 ++ .../templates/common/host_progress_popup.hbs | 5 +- ambari-web/app/utils/ajax/ajax.js | 15 +++++ ambari-web/app/utils/host_progress_popup.js | 50 ++++++++++++++++ .../test/utils/host_progress_popup_test.js | 60 +++++++++++++++++++- 8 files changed, 142 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/4da141ec/ambari-web/app/assets/test/tests.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js index f82b32b..dc19b75 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -117,6 +117,7 @@ var files = ['test/init_model_test', 'test/utils/date_test', 'test/utils/config_test', 'test/utils/form_field_test', + 'test/utils/host_progress_popup_test', 'test/utils/misc_test', 'test/utils/number_utils_test', 'test/utils/validator_test', @@ -213,4 +214,4 @@ describe('Ambari Web Unit tests', function() { } -}); +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/4da141ec/ambari-web/app/config.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/config.js b/ambari-web/app/config.js index 7262fb9..999feda 100644 --- a/ambari-web/app/config.js +++ b/ambari-web/app/config.js @@ -82,7 +82,8 @@ App.supports = { databaseConnection: true, configHistory: false, serverRecommendValidate: false, - downloadClientConfigs: false + downloadClientConfigs: false, + abortRequests: false }; if (App.enableExperimental) { http://git-wip-us.apache.org/repos/asf/ambari/blob/4da141ec/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index 6e0c472..628b097 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -254,6 +254,11 @@ Em.I18n.translations = { 'hostPopup.status.category.timedout':'Timedout ({0})', 'hostPopup.header.postFix':' Background Operations Running', 'hostPopup.serviceInfo.showMore':'Show more...', + 'hostPopup.bgop.abortRequest.title': 'Abort request', + 'hostPopup.bgop.abortRequest.confirmation.body': 'Are you sure you want to abort \'{0}\' operation?', + 'hostPopup.bgop.abortRequest.reason': 'Aborted by user', + 'hostPopup.bgop.abortRequest.modal.header': 'Abort request sent', + 'hostPopup.bgop.abortRequest.modal.body': 'The request to abort \'{0}\' operation is sent to server. Note that some tasks that are already running may have enough time to finish as completed or failed ones before abort request is applied.', 'hostPopup.bgop.sourceRequestSchedule.running': 'Future operations of this batch request can be aborted', 'hostPopup.bgop.sourceRequestSchedule.aborted': 'Future operations of this batch request have been aborted', 'hostPopup.bgop.abort.rollingRestart': 'Abort Rolling Restart', http://git-wip-us.apache.org/repos/asf/ambari/blob/4da141ec/ambari-web/app/styles/application.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less index cfc3e66..b10c772 100644 --- a/ambari-web/app/styles/application.less +++ b/ambari-web/app/styles/application.less @@ -1928,6 +1928,11 @@ width:100%; .modal-body, .modal-footer, .modal-header { min-width: 600px; } + #service-info { + .log-list-wrap:hover { + background-color: #e6e6e6; + } + } } .host-component-popup-wrap { .task-top-wrap { http://git-wip-us.apache.org/repos/asf/ambari/blob/4da141ec/ambari-web/app/templates/common/host_progress_popup.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/host_progress_popup.hbs b/ambari-web/app/templates/common/host_progress_popup.hbs index 6b36344..939177a 100644 --- a/ambari-web/app/templates/common/host_progress_popup.hbs +++ b/ambari-web/app/templates/common/host_progress_popup.hbs @@ -44,7 +44,10 @@ <div {{bindAttr class="servicesInfo.isVisible::hidden :log-list-wrap"}}> <div {{action gotoHosts servicesInfo}} class="task-list-line-cursor"> <div class="operation-name-icon-wrap"> - <i {{bindAttr class="servicesInfo.status servicesInfo.icon"}}></i> + <i {{bindAttr class=":service-status servicesInfo.status servicesInfo.icon"}}></i> + {{#if App.supports.abortRequests}} + <i {{action abortRequest servicesInfo}} {{translateAttr title="hostPopup.bgop.abortRequest.title"}} class="abort-icon icon-remove-circle hidden"></i> + {{/if}} <a href="#"> {{servicesInfo.name}} </a> http://git-wip-us.apache.org/repos/asf/ambari/blob/4da141ec/ambari-web/app/utils/ajax/ajax.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js index c5f2252..b76e40d 100644 --- a/ambari-web/app/utils/ajax/ajax.js +++ b/ambari-web/app/utils/ajax/ajax.js @@ -286,6 +286,21 @@ var urls = { 'mock': '/data/background_operations/list_on_start.json', 'testInProduction': true }, + 'background_operations.abort_request': { + 'real': '/clusters/{clusterName}/requests/{requestId}', + 'mock': '', + 'format': function () { + return { + type: 'PUT', + data: JSON.stringify({ + "Requests": { + "request_status": "ABORTED", + "abort_reason": Em.I18n.t('hostPopup.bgop.abortRequest.reason') + } + }) + }; + } + }, 'service.item.smoke': { 'real': '/clusters/{clusterName}/requests', 'mock': '/data/wizard/deploy/poll_1.json', http://git-wip-us.apache.org/repos/asf/ambari/blob/4da141ec/ambari-web/app/utils/host_progress_popup.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/host_progress_popup.js b/ambari-web/app/utils/host_progress_popup.js index d258a12..857f1a2 100644 --- a/ambari-web/app/utils/host_progress_popup.js +++ b/ambari-web/app/utils/host_progress_popup.js @@ -479,6 +479,21 @@ App.HostPopup = Em.Object.create({ isOpen: false, didInsertElement: function(){ + if (App.get('supports.abortRequests')) { + $(document).on({ + mouseenter: function () { + if ($(this).find('.service-status').hasClass(App.format.taskStatus('IN_PROGRESS')) || $(this).find('.service-status').hasClass(App.format.taskStatus('PENDING'))) { + App.tooltip($('.abort-icon')); + $(this).find('.service-status').addClass('hidden'); + $(this).find('.abort-icon').removeClass('hidden'); + } + }, + mouseleave: function () { + $(this).find('.abort-icon').addClass('hidden'); + $(this).find('.service-status').removeClass('hidden'); + } + }, '#service-info .log-list-wrap'); + } this._super(); this.set('isOpen', true); }, @@ -997,6 +1012,41 @@ App.HostPopup = Em.Object.create({ }, /** + * Send request to abort operation + */ + abortRequest: function (event) { + var requestName = event.context.get('name'); + var self = this; + App.showConfirmationPopup(function () { + App.ajax.send({ + name: 'background_operations.abort_request', + sender: self, + data: { + requestId: event.context.get('id'), + requestName: requestName + }, + success: 'abortRequestSuccessCallback', + error: 'abortRequestErrorCallback' + }); + }, Em.I18n.t('hostPopup.bgop.abortRequest.confirmation.body').format(requestName)); + return false; + }, + + /** + * Method called on successful sending request to abort operation + */ + abortRequestSuccessCallback: function (response, request, data) { + App.showAlertPopup(Em.I18n.t('hostPopup.bgop.abortRequest.modal.header'), Em.I18n.t('hostPopup.bgop.abortRequest.modal.body').format(data.requestName)); + }, + + /** + * Method called on unsuccessful sending request to abort operation + */ + abortRequestErrorCallback: function (xhr, textStatus, error, opt) { + App.ajax.defaultErrorHandler(xhr, opt.url, 'PUT', xhr.status); + }, + + /** * Onclick event for copy to clipboard button */ textTrigger: function () { http://git-wip-us.apache.org/repos/asf/ambari/blob/4da141ec/ambari-web/test/utils/host_progress_popup_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/utils/host_progress_popup_test.js b/ambari-web/test/utils/host_progress_popup_test.js index 60d884a..b7656a6 100644 --- a/ambari-web/test/utils/host_progress_popup_test.js +++ b/ambari-web/test/utils/host_progress_popup_test.js @@ -165,7 +165,7 @@ describe('App.HostPopup', function () { } ], m: 'One ABORTED', - r: 'CANCELLED', + r: 'ABORTED', p: 100, ids: [1,2] }, @@ -334,4 +334,62 @@ describe('App.HostPopup', function () { }); }); + describe('#abortRequest', function () { + beforeEach(function () { + sinon.stub(App.ajax, 'send', Em.K); + sinon.spy(App, 'showConfirmationPopup'); + App.HostPopup.createPopup(); + }); + afterEach(function () { + App.HostPopup.get('isPopup').hide(); + App.ajax.send.restore(); + App.showConfirmationPopup.restore(); + }); + it('should show confirmation popup', function () { + App.HostPopup.get('isPopup.bodyClass').create().abortRequest({ + context: Em.Object.create({ + name: 'name' + }) + }); + expect(App.showConfirmationPopup.calledOnce).to.be.true; + }); + }); + + describe('#abortRequestSuccessCallback', function () { + beforeEach(function () { + App.HostPopup.createPopup(); + sinon.spy(App.ModalPopup, 'show'); + }); + afterEach(function () { + App.HostPopup.get('isPopup').hide(); + App.ModalPopup.show.restore(); + }); + it('should open popup', function () { + App.HostPopup.get('isPopup.bodyClass').create().abortRequestSuccessCallback(null, null, { + requestName: 'name' + }); + expect(App.ModalPopup.show.calledOnce).to.be.true; + }); + }); + + describe('#abortRequestErrorCallback', function () { + beforeEach(function () { + App.HostPopup.createPopup(); + sinon.spy(App.ModalPopup, 'show'); + }); + afterEach(function () { + App.HostPopup.get('isPopup').hide(); + App.ModalPopup.show.restore(); + }); + it('should open popup', function () { + App.HostPopup.get('isPopup.bodyClass').create().abortRequestErrorCallback({ + responseText: { + message: 'message' + }, + status: 404 + }, 'url', 'PUT', 404); + expect(App.ModalPopup.show.calledOnce).to.be.true; + }); + }); + });
