Repository: ambari Updated Branches: refs/heads/trunk 33c01273e -> 1734b5c7b
AMBARI-16038. Delete Service: After deleting Hive, ui keeps showing hive service for long time. (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/1734b5c7 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1734b5c7 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1734b5c7 Branch: refs/heads/trunk Commit: 1734b5c7ba965d9a4939d139463a1d2e6950d3da Parents: 33c0127 Author: Oleg Nechiporenko <[email protected]> Authored: Fri Apr 22 13:12:04 2016 +0300 Committer: Oleg Nechiporenko <[email protected]> Committed: Fri Apr 22 13:12:04 2016 +0300 ---------------------------------------------------------------------- ambari-web/app/controllers/main/service/item.js | 34 +++++++------------- ambari-web/app/models/service.js | 9 ++++++ .../service/info/confirm_delete_service.hbs | 23 +++++++++++++ .../service/info/dependent_services_warning.hbs | 24 ++++++++++++++ ambari-web/app/utils/handlebars_helpers.js | 8 ++++- ambari-web/app/views.js | 1 + .../views/common/helpers/format_role_view.js | 28 ++++++++++++++++ .../app/views/main/service/info/summary.js | 2 +- .../test/controllers/main/service/item_test.js | 18 +++++++++-- 9 files changed, 121 insertions(+), 26 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/1734b5c7/ambari-web/app/controllers/main/service/item.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/service/item.js b/ambari-web/app/controllers/main/service/item.js index 4c772a3..5707882 100644 --- a/ambari-web/app/controllers/main/service/item.js +++ b/ambari-web/app/controllers/main/service/item.js @@ -162,7 +162,7 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow sitesToLoad: function() { var services = this.get('dependentServiceNames'), configTypeList = []; if (services.length) { - var configTypeList = App.StackService.find().filter(function(s) { + configTypeList = App.StackService.find().filter(function(s) { return services.contains(s.get('serviceName')); }).mapProperty('configTypeList').reduce(function(p, v) { return p.concat(v); @@ -429,11 +429,8 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow var names = servicesAffectedDisplayNames.join(); if(names){ //only display this line with a non-empty dependency list - var dependenciesMsg = Em.I18n.t('services.service.stop.warningMsg.dependent.services').format(serviceDisplayName,names); - if(msg) - msg = msg + " " + dependenciesMsg; - else - msg = dependenciesMsg; + var dependenciesMsg = Em.I18n.t('services.service.stop.warningMsg.dependent.services').format(serviceDisplayName, names); + msg = msg ? msg + " " + dependenciesMsg : dependenciesMsg; } } @@ -1176,23 +1173,17 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow /** * warning that show dependent services which must be deleted prior to chosen service deletion * @param {string} origin - * @param {Array.<string>} dependent + * @param {string[]} dependent * @returns {App.ModalPopup} */ dependentServicesWarning: function(origin, dependent) { - var body = Em.I18n.t('services.service.delete.popup.dependentServices').format(App.format.role(origin, true)); - - body += '<ul>'; - dependent.forEach(function(serviceName) { - body += '<li>' + App.format.role(serviceName, true) + '</li>'; - }); - body += '</ul>'; - return App.ModalPopup.show({ secondary: null, header: Em.I18n.t('services.service.delete.popup.header'), + dependentMessage: Em.I18n.t('services.service.delete.popup.dependentServices').format(App.format.role(origin, true)), + dependentServices: dependent, bodyClass: Em.View.extend({ - template: Em.Handlebars.compile(body) + templateName: require('templates/main/service/info/dependent_services_warning') }) }); }, @@ -1248,20 +1239,18 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow */ disablePrimary: Em.computed.notEqual('confirmInput', confirmKey), + message: message, + /** * @type {Em.View} */ bodyClass: Em.View.extend({ confirmKey: confirmKey, typeMessage: Em.I18n.t('services.service.confirmDelete.popup.body.type').format(confirmKey), - template: Em.Handlebars.compile(message + - '<div class="form-inline align-center"></br>' + - '<label><b>{{view.typeMessage}}</b></label> ' + - '{{view Ember.TextField valueBinding="view.parentView.confirmInput" class="input-small"}}</br>' + - '</div>') + templateName: require('templates/main/service/info/confirm_delete_service') }), - enterKeyPressed: function(e) { + enterKeyPressed: function() { if (this.get('disablePrimary')) return; this.onPrimary(); } @@ -1373,6 +1362,7 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow if (serviceNames.length > 1) { var servicesToDeleteNext = serviceNames.slice(1); } + App.Service.find().findProperty('serviceName', serviceToDeleteNow).set('deleteInProgress', true); return App.ajax.send({ name : 'common.delete.service', sender: this, http://git-wip-us.apache.org/repos/asf/ambari/blob/1734b5c7/ambari-web/app/models/service.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/service.js b/ambari-web/app/models/service.js index 2818b9f..34abbd2 100644 --- a/ambari-web/app/models/service.js +++ b/ambari-web/app/models/service.js @@ -80,6 +80,15 @@ App.Service = DS.Model.extend({ isStarted: Em.computed.equal('workStatus', 'STARTED'), /** + * Indicates when service deleting is in progress + * Used to stop update service's data and topology + * + * @type {boolean} + * @default false + */ + deleteInProgress: false, + + /** * Service Tagging by their type. * @type {String[]} **/ http://git-wip-us.apache.org/repos/asf/ambari/blob/1734b5c7/ambari-web/app/templates/main/service/info/confirm_delete_service.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/service/info/confirm_delete_service.hbs b/ambari-web/app/templates/main/service/info/confirm_delete_service.hbs new file mode 100644 index 0000000..cbe1f40 --- /dev/null +++ b/ambari-web/app/templates/main/service/info/confirm_delete_service.hbs @@ -0,0 +1,23 @@ +{{! +* 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. +}} + +{{{view.parentView.message}}} +<div class="form-inline align-center"><br /> + <label><strong>{{view.typeMessage}}</strong></label> + {{view Ember.TextField valueBinding="view.parentView.confirmInput" class="input-small"}}<br /> +</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/1734b5c7/ambari-web/app/templates/main/service/info/dependent_services_warning.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/service/info/dependent_services_warning.hbs b/ambari-web/app/templates/main/service/info/dependent_services_warning.hbs new file mode 100644 index 0000000..e09639f --- /dev/null +++ b/ambari-web/app/templates/main/service/info/dependent_services_warning.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. +}} + +<p>{{{view.parentView.dependentMessage}}}</p> +<ul> + {{#each serviceName in view.parentView.dependentServices}} + <li>{{formatRole serviceName}}</li> + {{/each}} +</ul> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/1734b5c7/ambari-web/app/utils/handlebars_helpers.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/handlebars_helpers.js b/ambari-web/app/utils/handlebars_helpers.js index fe48b1e..eca816c 100644 --- a/ambari-web/app/utils/handlebars_helpers.js +++ b/ambari-web/app/utils/handlebars_helpers.js @@ -94,4 +94,10 @@ App.registerBoundHelper('formatWordBreak', App.FormatWordBreakView); * returns 'icon-cog' * */ -App.registerBoundHelper('statusIcon', App.StatusIconView); \ No newline at end of file +App.registerBoundHelper('statusIcon', App.StatusIconView); + +/** + * Return `span` with formatted service name + * @param {string} content - serviceName + */ +App.registerBoundHelper('formatRole', App.FormatRoleView); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/1734b5c7/ambari-web/app/views.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js index 16d9650..6bb2774 100644 --- a/ambari-web/app/views.js +++ b/ambari-web/app/views.js @@ -96,6 +96,7 @@ require('views/common/widget/heatmap_widget_view'); require('views/common/assign_master_components_view'); require('views/common/helpers/format_word_break_view'); require('views/common/helpers/format_null_view'); +require('views/common/helpers/format_role_view'); require('views/common/helpers/pluralize_view'); require('views/common/helpers/status_icon_view'); require('views/common/chosen_plugin'); http://git-wip-us.apache.org/repos/asf/ambari/blob/1734b5c7/ambari-web/app/views/common/helpers/format_role_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/helpers/format_role_view.js b/ambari-web/app/views/common/helpers/format_role_view.js new file mode 100644 index 0000000..04f9644 --- /dev/null +++ b/ambari-web/app/views/common/helpers/format_role_view.js @@ -0,0 +1,28 @@ +/** + * 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.FormatRoleView = Em.View.extend({ + + tagName: 'span', + template: Em.Handlebars.compile('{{view.result}}'), + + result: Em.computed.formatRole('content', true) + +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/1734b5c7/ambari-web/app/views/main/service/info/summary.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/service/info/summary.js b/ambari-web/app/views/main/service/info/summary.js index e730651..7e0d0bb 100644 --- a/ambari-web/app/views/main/service/info/summary.js +++ b/ambari-web/app/views/main/service/info/summary.js @@ -159,7 +159,7 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin componentsLengthDidChange: function() { var self = this; - if (!this.get('service')) return; + if (!this.get('service') || this.get('service.deleteInProgress')) return; Em.run.once(self, 'setComponentsContent'); }.observes('service.hostComponents.length', '[email protected]', '[email protected]'), http://git-wip-us.apache.org/repos/asf/ambari/blob/1734b5c7/ambari-web/test/controllers/main/service/item_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/service/item_test.js b/ambari-web/test/controllers/main/service/item_test.js index dbb4463..4bac784 100644 --- a/ambari-web/test/controllers/main/service/item_test.js +++ b/ambari-web/test/controllers/main/service/item_test.js @@ -1400,13 +1400,22 @@ describe('App.MainServiceItemController', function () { describe("#deleteServiceCall()", function() { var mainServiceItemController; + var service; beforeEach(function() { mainServiceItemController = App.MainServiceItemController.create({}); + service = Em.Object.create({serviceName: 'S1', deleteInProgress: false}); + sinon.stub( App.Service, 'find', function () { + return [service]; + }); + mainServiceItemController.deleteServiceCall(['S1', 'S2']); + }); + + afterEach(function () { + App.Service.find.restore(); }); it("App.ajax.send should be called", function() { - mainServiceItemController.deleteServiceCall(['S1', 'S2']); var args = testHelpers.findAjaxRequest('name', 'common.delete.service'); expect(args[0]).exists; expect(args[0].sender).to.be.eql(mainServiceItemController); @@ -1415,6 +1424,11 @@ describe('App.MainServiceItemController', function () { servicesToDeleteNext: ['S2'] }); }); + + it('service is marked as deleted', function () { + expect(service.get('deleteInProgress')).to.be.true; + }); + }); describe("#deleteServiceCallSuccessCallback()", function() { @@ -1423,7 +1437,7 @@ describe('App.MainServiceItemController', function () { beforeEach(function() { mainServiceItemController = App.MainServiceItemController.create({}); sinon.spy(mainServiceItemController, 'loadConfigRecommendations'); - sinon.spy(mainServiceItemController, 'deleteServiceCall'); + sinon.stub(mainServiceItemController, 'deleteServiceCall', Em.K); mainServiceItemController.reopen({ interDependentServices: [] })
