Browse Source

AMBARI-11825. Failure to add or install component defined with cardinality ALL. (Shantanu Mundkur via Jaimin)

Jaimin Jetly 9 years ago
parent
commit
20a9ba1890

+ 76 - 6
ambari-web/app/controllers/wizard/step8_controller.js

@@ -1054,13 +1054,37 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
    * @method createMasterHostComponents
    * @method createMasterHostComponents
    */
    */
   createMasterHostComponents: function () {
   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.
     // create master components for only selected services.
     var selectedMasterComponents = this.get('content.masterComponentHosts').filter(function (_component) {
     var selectedMasterComponents = this.get('content.masterComponentHosts').filter(function (_component) {
       return this.get('selectedServices').mapProperty('serviceName').contains(_component.serviceId)
       return this.get('selectedServices').mapProperty('serviceName').contains(_component.serviceId)
     }, this);
     }, this);
     selectedMasterComponents.mapProperty('component').uniq().forEach(function (component) {
     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);
     }, this);
   },
   },
 
 
@@ -1077,6 +1101,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
     });
     });
     return clientsMap;
     return clientsMap;
   },
   },
+
   /**
   /**
    * Register slave components and clients
    * Register slave components and clients
    * @uses registerHostsToComponent
    * @uses registerHostsToComponent
@@ -1086,6 +1111,18 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
     var masterHosts = this.get('content.masterComponentHosts');
     var masterHosts = this.get('content.masterComponentHosts');
     var slaveHosts = this.get('content.slaveComponentHosts');
     var slaveHosts = this.get('content.slaveComponentHosts');
     var clients = this.get('content.clients').filterProperty('isInstalled', false);
     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)
      * 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) {
     slaveHosts.forEach(function (_slave) {
       if (_slave.componentName !== 'CLIENT') {
       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 {
       else {
         clients.forEach(function (_client) {
         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);
       }
       }
     }, this);
     }, this);
@@ -1220,6 +1289,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
     var masterHosts = this.get('content.masterComponentHosts');
     var masterHosts = this.get('content.masterComponentHosts');
 
 
     // add all components with cardinality == ALL of selected services
     // add all components with cardinality == ALL of selected services
+
     var registeredHosts = this.getRegisteredHosts();
     var registeredHosts = this.getRegisteredHosts();
     var notInstalledHosts = registeredHosts.filterProperty('isInstalled', false);
     var notInstalledHosts = registeredHosts.filterProperty('isInstalled', false);
     this.get('content.services').filterProperty('isSelected').forEach(function (service) {
     this.get('content.services').filterProperty('isSelected').forEach(function (service) {

+ 195 - 0
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 () {
     describe('#createNotification', function () {
 
 
       beforeEach(function () {
       beforeEach(function () {