Repository: ambari Updated Branches: refs/heads/branch-2.4 2ec557bd0 -> 154a805da
AMBARI-16643 Ambari allows installing a component on more than one host even with cardinality as 0-1. (atkach) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/154a805d Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/154a805d Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/154a805d Branch: refs/heads/branch-2.4 Commit: 154a805da76814159ce861949cb77d20d2664ddd Parents: 2ec557b Author: Andrii Tkach <[email protected]> Authored: Thu May 12 21:28:48 2016 +0300 Committer: Andrii Tkach <[email protected]> Committed: Fri May 13 17:34:51 2016 +0300 ---------------------------------------------------------------------- ambari-web/app/controllers/main/host/details.js | 22 +++++++--- ambari-web/app/views/main/host/summary.js | 17 +++++++- ambari-web/test/views/main/host/summary_test.js | 45 ++++++++++++++++++++ 3 files changed, 76 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/154a805d/ambari-web/app/controllers/main/host/details.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js index 8664d8c..374b077 100644 --- a/ambari-web/app/controllers/main/host/details.js +++ b/ambari-web/app/controllers/main/host/details.js @@ -598,27 +598,37 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow } return returnFunc; }, + /** * Send command to server to install client on selected host - * @param component + * @param {App.HostComponent} component + * @param {boolean} isManualKerberos + * @returns {*} */ addClientComponent: function (component, isManualKerberos) { - var self = this; - var message = this.formatClientsMessage(component); + var self = this, + displayName = this.formatClientsMessage(component); - return this.showAddComponentPopup(message, isManualKerberos, function () { + return this.showAddComponentPopup(displayName, isManualKerberos, function () { self.installHostComponentCall(self.get('content.hostName'), component); }); }, - showAddComponentPopup: function (message, isManualKerberos, primary) { + /** + * + * @param {string} displayName + * @param {boolean} isManualKerberos + * @param {Function} primary + * @returns {*} + */ + showAddComponentPopup: function (displayName, isManualKerberos, primary) { isManualKerberos = isManualKerberos || false; return App.ModalPopup.show({ primary: Em.I18n.t('hosts.host.addComponent.popup.confirm'), header: Em.I18n.t('popup.confirmation.commonHeader'), - addComponentMsg: Em.I18n.t('hosts.host.addComponent.msg').format(message), + addComponentMsg: Em.I18n.t('hosts.host.addComponent.msg').format(displayName), manualKerberosWarning: isManualKerberos ? Em.I18n.t('hosts.host.manualKerberosWarning') : '', http://git-wip-us.apache.org/repos/asf/ambari/blob/154a805d/ambari-web/app/views/main/host/summary.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/host/summary.js b/ambari-web/app/views/main/host/summary.js index c92c526..ef666e9 100644 --- a/ambari-web/app/views/main/host/summary.js +++ b/ambari-web/app/views/main/host/summary.js @@ -265,7 +265,9 @@ App.MainHostSummaryView = Em.View.extend(App.TimeRangeMixin, { var installedServices = this.get('installedServices'); addableToHostComponents.forEach(function (addableComponent) { - if (installedServices.contains(addableComponent.get('serviceName')) && !installedComponents.contains(addableComponent.get('componentName'))) { + if (installedServices.contains(addableComponent.get('serviceName')) + && !installedComponents.contains(addableComponent.get('componentName')) + && !this.hasCardinalityConflict(addableComponent.get('componentName'))) { if ((addableComponent.get('componentName') === 'OOZIE_SERVER') && !App.router.get('mainHostDetailsController.isOozieServerAddable')) { return; } @@ -274,12 +276,23 @@ App.MainHostSummaryView = Em.View.extend(App.TimeRangeMixin, { 'serviceName': addableComponent.get('serviceName') })); } - }); + }, this); } return components; }.property('content.hostComponents.length', 'App.components.addableToHost.@each'), /** + * + * @param {string} componentName + * @returns {boolean} + */ + hasCardinalityConflict: function(componentName) { + var totalCount = App.SlaveComponent.find(componentName).get('totalCount'); + var maxToInstall = App.StackServiceComponent.find(componentName).get('maxToInstall'); + return !(totalCount < maxToInstall); + }, + + /** * Formatted with <code>$.timeago</code> value of host's last heartbeat * @type {String} */ http://git-wip-us.apache.org/repos/asf/ambari/blob/154a805d/ambari-web/test/views/main/host/summary_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/host/summary_test.js b/ambari-web/test/views/main/host/summary_test.js index 47dbf3d..14e92da 100644 --- a/ambari-web/test/views/main/host/summary_test.js +++ b/ambari-web/test/views/main/host/summary_test.js @@ -289,9 +289,11 @@ describe('App.MainHostSummaryView', function() { beforeEach(function() { this.mock = sinon.stub(App.StackServiceComponent, 'find'); + sinon.stub(mainHostSummaryView, 'hasCardinalityConflict').returns(false); }); afterEach(function() { App.StackServiceComponent.find.restore(); + mainHostSummaryView.hasCardinalityConflict.restore(); }); var tests = Em.A([ @@ -598,4 +600,47 @@ describe('App.MainHostSummaryView', function() { expect(mainHostSummaryView.get('installableClientComponents').mapProperty('componentName')).to.eql(['C1']); }); }); + + describe("#hasCardinalityConflict()", function () { + + beforeEach(function() { + this.mockSlave = sinon.stub(App.SlaveComponent, 'find'); + this.mockStack = sinon.stub(App.StackServiceComponent, 'find'); + }); + + afterEach(function() { + this.mockSlave.restore(); + this.mockStack.restore(); + }); + + it("totalCount equal to maxToInstall", function() { + this.mockSlave.returns(Em.Object.create({ + totalCount: 1 + })); + this.mockStack.returns(Em.Object.create({ + maxToInstall: 1 + })); + expect(mainHostSummaryView.hasCardinalityConflict('C1')).to.be.true; + }); + + it("totalCount more than maxToInstall", function() { + this.mockSlave.returns(Em.Object.create({ + totalCount: 2 + })); + this.mockStack.returns(Em.Object.create({ + maxToInstall: 1 + })); + expect(mainHostSummaryView.hasCardinalityConflict('C1')).to.be.true; + }); + + it("totalCount less than maxToInstall", function() { + this.mockSlave.returns(Em.Object.create({ + totalCount: 0 + })); + this.mockStack.returns(Em.Object.create({ + maxToInstall: 1 + })); + expect(mainHostSummaryView.hasCardinalityConflict('C1')).to.be.false; + }); + }); });
