Repository: ambari Updated Branches: refs/heads/trunk bea418b75 -> 20a9ba189
AMBARI-11825. Failure to add or install component defined with cardinality ALL. (Shantanu Mundkur via Jaimin) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/20a9ba18 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/20a9ba18 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/20a9ba18 Branch: refs/heads/trunk Commit: 20a9ba1890d4bede13f2971d9e39cbeb0c743086 Parents: bea418b Author: Jaimin Jetly <[email protected]> Authored: Sat Nov 28 12:42:19 2015 -0800 Committer: Jaimin Jetly <[email protected]> Committed: Sat Nov 28 12:42:19 2015 -0800 ---------------------------------------------------------------------- .../app/controllers/wizard/step8_controller.js | 82 +++++++- .../test/controllers/wizard/step8_test.js | 195 +++++++++++++++++++ 2 files changed, 271 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/20a9ba18/ambari-web/app/controllers/wizard/step8_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step8_controller.js b/ambari-web/app/controllers/wizard/step8_controller.js index fa0adaa..bbe40bd 100644 --- a/ambari-web/app/controllers/wizard/step8_controller.js +++ b/ambari-web/app/controllers/wizard/step8_controller.js @@ -1054,13 +1054,37 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz * @method createMasterHostComponents */ createMasterHostComponents: function () { + var masterOnAllHosts = []; + + this.get('content.services').filterProperty('isSelected').forEach(function (service) { + service.get('serviceComponents').filterProperty('isRequiredOnAllHosts').forEach(function (component) { + if (component.get('isMaster')) { + masterOnAllHosts.push(component.get('componentName')); + } + }, this); + }, this); + // create master components for only selected services. var selectedMasterComponents = this.get('content.masterComponentHosts').filter(function (_component) { return this.get('selectedServices').mapProperty('serviceName').contains(_component.serviceId) }, this); selectedMasterComponents.mapProperty('component').uniq().forEach(function (component) { - var hostNames = selectedMasterComponents.filterProperty('component', component).filterProperty('isInstalled', false).mapProperty('hostName'); - this.registerHostsToComponent(hostNames, component); + if (masterOnAllHosts.length > 0) { + var compOnAllHosts = false; + for (var i=0; i < masterOnAllHosts.length; i++) { + if (component.component_name == masterOnAllHosts[i]) { + compOnAllHosts = true; + break; + } + } + if (!compOnAllHosts) { + var hostNames = selectedMasterComponents.filterProperty('component', component).filterProperty('isInstalled', false).mapProperty('hostName'); + this.registerHostsToComponent(hostNames, component); + } + } else { + var hostNames = selectedMasterComponents.filterProperty('component', component).filterProperty('isInstalled', false).mapProperty('hostName'); + this.registerHostsToComponent(hostNames, component); + } }, this); }, @@ -1077,6 +1101,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz }); return clientsMap; }, + /** * Register slave components and clients * @uses registerHostsToComponent @@ -1086,6 +1111,18 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz var masterHosts = this.get('content.masterComponentHosts'); var slaveHosts = this.get('content.slaveComponentHosts'); var clients = this.get('content.clients').filterProperty('isInstalled', false); + var slaveOnAllHosts = []; + var clientOnAllHosts = []; + + this.get('content.services').filterProperty('isSelected').forEach(function (service) { + service.get('serviceComponents').filterProperty('isRequiredOnAllHosts').forEach(function (component) { + if (component.get('isClient')) { + clientOnAllHosts.push(component.get('componentName')); + } else if (component.get('isSlave')) { + slaveOnAllHosts.push(component.get('componentName')); + } + }, this); + }, this); /** * Determines on which hosts client should be installed (based on availability of master components on hosts) @@ -1103,8 +1140,24 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz slaveHosts.forEach(function (_slave) { if (_slave.componentName !== 'CLIENT') { - var hostNames = _slave.hosts.filterProperty('isInstalled', false).mapProperty('hostName'); - this.registerHostsToComponent(hostNames, _slave.componentName); + if (slaveOnAllHosts.length > 0) { + var compOnAllHosts = false; + for (var i=0; i < slaveOnAllHosts.length; i++) { + if (_slave.component_name == slaveOnAllHosts[i]) { + // component with ALL cardinality should not + // registerHostsToComponent in createSlaveAndClientsHostComponents + compOnAllHosts = true; + break; + } + } + if (!compOnAllHosts) { + var hostNames = _slave.hosts.filterProperty('isInstalled', false).mapProperty('hostName'); + this.registerHostsToComponent(hostNames, _slave.componentName); + } + } else { + var hostNames = _slave.hosts.filterProperty('isInstalled', false).mapProperty('hostName'); + this.registerHostsToComponent(hostNames, _slave.componentName); + } } else { clients.forEach(function (_client) { @@ -1120,8 +1173,24 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz }); } } - hostNames = hostNames.uniq(); - this.registerHostsToComponent(hostNames, _client.component_name); + if (clientOnAllHosts.length > 0) { + var compOnAllHosts = false; + for (var i=0; i < clientOnAllHosts.length; i++) { + if (_client.component_name == clientOnAllHosts[i]) { + // component with ALL cardinality should not + // registerHostsToComponent in createSlaveAndClientsHostComponents + compOnAllHosts = true; + break; + } + } + if (!compOnAllHosts) { + hostNames = hostNames.uniq(); + this.registerHostsToComponent(hostNames, _client.component_name); + } + } else { + hostNames = hostNames.uniq(); + this.registerHostsToComponent(hostNames, _client.component_name); + } }, this); } }, this); @@ -1220,6 +1289,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz var masterHosts = this.get('content.masterComponentHosts'); // add all components with cardinality == ALL of selected services + var registeredHosts = this.getRegisteredHosts(); var notInstalledHosts = registeredHosts.filterProperty('isInstalled', false); this.get('content.services').filterProperty('isSelected').forEach(function (service) { http://git-wip-us.apache.org/repos/asf/ambari/blob/20a9ba18/ambari-web/test/controllers/wizard/step8_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step8_test.js b/ambari-web/test/controllers/wizard/step8_test.js index 100f781..71d1e48 100644 --- a/ambari-web/test/controllers/wizard/step8_test.js +++ b/ambari-web/test/controllers/wizard/step8_test.js @@ -1632,6 +1632,201 @@ describe('App.WizardStep8Controller', function () { }); + describe('#createAdditionalHostComponentsOnAllHosts', function () { + + beforeEach(function() { + sinon.stub(installerStep8Controller, 'registerHostsToComponent', Em.K); + }); + + afterEach(function() { + installerStep8Controller.registerHostsToComponent.restore(); + }); + + it('should add components with isRequiredOnAllHosts == true (1)', function() { + installerStep8Controller.reopen({ + getRegisteredHosts: function() { + return [{hostName: 'h1'}, {hostName: 'h2'}]; + }, + content: { + services: Em.A([ + Em.Object.create({ + serviceName: 'ANYSERVICE', isSelected: true, isInstalled: false, serviceComponents: [ + // set isRequiredOnAllHosts = true for slave and client + Em.Object.create({ + componentName: 'ANYSERVICE_MASTER', + isMaster: true, + isRequiredOnAllHosts: false + }), + Em.Object.create({ + componentName: 'ANYSERVICE_SLAVE', + isSlave: true, + isRequiredOnAllHosts: true + }), + Em.Object.create({ + componentName: 'ANYSERVICE_SLAVE2', + isSlave: true, + isRequiredOnAllHosts: true + }), + Em.Object.create({ + componentName: 'ANYSERVICE_CLIENT', + isClient: true, + isRequiredOnAllHosts: true + }) + ] + }) + ]), + masterComponentHosts: Em.A([ + Em.Object.create({ + componentName: 'ANYSERVICE_MASTER', + component: 'ANYSERVICE_MASTER', + hosts: Em.A([ + Em.Object.create({hostName: 'h1', isInstalled: true}) + ]) + }) + ]), + slaveComponentHosts: Em.A([ + Em.Object.create({ + componentName: 'ANYSERVICE_SLAVE', + hosts: Em.A([ + Em.Object.create({hostName: 'h1', isInstalled: false}), + Em.Object.create({hostName: 'h2', isInstalled: false}) + ]) + }), + Em.Object.create({ + componentName: 'ANYSERVICE_SLAVE2', + hosts: Em.A([ + Em.Object.create({hostName: 'h1', isInstalled: false}), + Em.Object.create({hostName: 'h2', isInstalled: false}) + ]), + }), + Em.Object.create({ + componentName: 'CLIENT', + hosts: Em.A([ + Em.Object.create({hostName: 'h1', isInstalled: false}), + Em.Object.create({hostName: 'h2', isInstalled: false}) + ]) + }) + ]), + clients: Em.A([ + Em.Object.create({ + component_name: 'ANYSERVICE_CLIENT', + isInstalled: false, + hosts: Em.A([ + Em.Object.create({hostName: 'h1', isInstalled: false}), + Em.Object.create({hostName: 'h2', isInstalled: false}) + ]) + }) + ]) + } + }); + + installerStep8Controller.set('ajaxRequestsQueue', App.ajaxQueue.create()); + installerStep8Controller.get('ajaxRequestsQueue').clear(); + installerStep8Controller.createAdditionalHostComponents(); + // Any component with isRequiredOnAllHosts = true implies that + // registerHostsToComponent would be done via + // createAdditionalHostComponents() BUT NOT + // createMasterHostComponents() or createSlaveAndClientsHostComponents() + // or createAdditionalClientComponents() + expect(installerStep8Controller.registerHostsToComponent.args[0][0]).to.eql(['h1', 'h2']); + expect(installerStep8Controller.registerHostsToComponent.args[0][1]).to.equal('ANYSERVICE_SLAVE'); + expect(installerStep8Controller.registerHostsToComponent.args[1][0]).to.eql(['h1', 'h2']); + expect(installerStep8Controller.registerHostsToComponent.args[1][1]).to.equal('ANYSERVICE_SLAVE2'); + expect(installerStep8Controller.registerHostsToComponent.args[2][0]).to.eql(['h1', 'h2']); + expect(installerStep8Controller.registerHostsToComponent.args[2][1]).to.equal('ANYSERVICE_CLIENT'); + }); + + it('should not add components with isRequiredOnAllHosts == false (2)', function() { + installerStep8Controller.reopen({ + getRegisteredHosts: function() { + return [{hostName: 'h1'}, {hostName: 'h2'}]; + }, + content: { + services: Em.A([ + Em.Object.create({ + serviceName: 'ANYSERVICE', isSelected: true, isInstalled: false, serviceComponents: [ + // set isRequiredOnAllHosts = false for all components + Em.Object.create({ + componentName: 'ANYSERVICE_MASTER', + isMaster: true, + isRequiredOnAllHosts: false + }), + Em.Object.create({ + componentName: 'ANYSERVICE_SLAVE', + isSlave: true, + isRequiredOnAllHosts: false + }), + Em.Object.create({ + componentName: 'ANYSERVICE_SLAVE2', + isSlave: true, + isRequiredOnAllHosts: false + }), + Em.Object.create({ + componentName: 'ANYSERVICE_CLIENT', + isClient: true, + isRequiredOnAllHosts: false + }) + ] + }) + ]), + masterComponentHosts: Em.A([ + Em.Object.create({ + componentName: 'ANYSERVICE_MASTER', + component: 'ANYSERVICE_MASTER', + hosts: Em.A([ + Em.Object.create({hostName: 'h1', isInstalled: true}) + ]) + }) + ]), + slaveComponentHosts: Em.A([ + Em.Object.create({ + componentName: 'ANYSERVICE_SLAVE', + hosts: Em.A([ + Em.Object.create({hostName: 'h1', isInstalled: false}), + Em.Object.create({hostName: 'h2', isInstalled: false}) + ]) + }), + Em.Object.create({ + componentName: 'ANYSERVICE_SLAVE2', + hosts: Em.A([ + Em.Object.create({hostName: 'h1', isInstalled: false}), + Em.Object.create({hostName: 'h2', isInstalled: false}) + ]), + }), + Em.Object.create({ + componentName: 'CLIENT', + hosts: Em.A([ + Em.Object.create({hostName: 'h1', isInstalled: false}), + Em.Object.create({hostName: 'h2', isInstalled: false}) + ]) + }) + ]), + clients: Em.A([ + Em.Object.create({ + component_name: 'ANYSERVICE_CLIENT', + isInstalled: false, + hosts: Em.A([ + Em.Object.create({hostName: 'h1', isInstalled: false}), + Em.Object.create({hostName: 'h2', isInstalled: false}) + ]) + }) + ]) + } + }); + + installerStep8Controller.set('ajaxRequestsQueue', App.ajaxQueue.create()); + installerStep8Controller.get('ajaxRequestsQueue').clear(); + installerStep8Controller.createAdditionalHostComponents(); + // isRequiredOnAllHosts = false for all components, implies that + // registerHostsToComponent would be done via + // createMasterHostComponents() or createSlaveAndClientsHostComponents() + // or createAdditionalClientComponents() + // BUT NOT createAdditionalHostComponents() + expect(installerStep8Controller.registerHostsToComponent.callCount).to.equal(0); + }); + + }); + describe('#createNotification', function () { beforeEach(function () {
