Browse Source

AMBARI-11424. Exception when adding Phoenix Query server during add host wizard (akovalenko)

Aleksandr Kovalenko 10 years ago
parent
commit
858a52d18e

+ 89 - 56
ambari-web/app/controllers/global/cluster_controller.js

@@ -249,71 +249,74 @@ App.ClusterController = Em.Controller.extend({
 
     /**
      * Order of loading:
-     * 1. request for service components supported by stack
-     * 2. load stack components to model
-     * 3. request for services
-     * 4. put services in cache
-     * 5. request for hosts and host-components (single call)
-     * 6. request for service metrics
-     * 7. load host-components to model
-     * 8. load hosts to model
-     * 9. load services from cache with metrics to model
-     * 10. update stale_configs of host-components (depends on App.supports.hostOverrides)
-     * 11. load root service (Ambari)
-     * 12. load alert definitions to model
-     * 13. load unhealthy alert instances
-     * 14. load security status
+     * 1. load all created service components
+     * 2. request for service components supported by stack
+     * 3. load stack components to model
+     * 4. request for services
+     * 5. put services in cache
+     * 6. request for hosts and host-components (single call)
+     * 7. request for service metrics
+     * 8. load host-components to model
+     * 9. load hosts to model
+     * 10. load services from cache with metrics to model
+     * 11. update stale_configs of host-components (depends on App.supports.hostOverrides)
+     * 12. load root service (Ambari)
+     * 13. load alert definitions to model
+     * 14. load unhealthy alert instances
+     * 15. load security status
      */
-    self.loadStackServiceComponents(function (data) {
-      data.items.forEach(function (service) {
-        service.StackServices.is_selected = true;
-        service.StackServices.is_installed = false;
-      }, self);
-      App.stackServiceMapper.mapStackServices(data);
-      App.config.setPreDefinedServiceConfigs(true);
-      var updater = App.router.get('updateController');
-      self.updateLoadStatus('stackComponents');
-      updater.updateServices(function () {
-        self.updateLoadStatus('services');
-        //force clear filters  for hosts page to load all data
-        App.db.setFilterConditions('mainHostController', null);
-
-        updater.updateHost(function () {
-          self.updateLoadStatus('hosts');
-        });
+    self.loadServiceComponents(function () {
+      self.loadStackServiceComponents(function (data) {
+        data.items.forEach(function (service) {
+          service.StackServices.is_selected = true;
+          service.StackServices.is_installed = false;
+        }, self);
+        App.stackServiceMapper.mapStackServices(data);
+        App.config.setPreDefinedServiceConfigs(true);
+        var updater = App.router.get('updateController');
+        self.updateLoadStatus('stackComponents');
+        updater.updateServices(function () {
+          self.updateLoadStatus('services');
+          //force clear filters  for hosts page to load all data
+          App.db.setFilterConditions('mainHostController', null);
+
+          updater.updateHost(function () {
+            self.updateLoadStatus('hosts');
+          });
 
-        updater.updateServiceMetric(function () {
-          App.config.loadConfigsFromStack(App.Service.find().mapProperty('serviceName')).complete(function() {
-            updater.updateComponentConfig(function () {
-              self.updateLoadStatus('componentConfigs');
-            });
+          updater.updateServiceMetric(function () {
+            App.config.loadConfigsFromStack(App.Service.find().mapProperty('serviceName')).complete(function () {
+              updater.updateComponentConfig(function () {
+                self.updateLoadStatus('componentConfigs');
+              });
 
-            updater.updateComponentsState(function () {
-              self.updateLoadStatus('componentsState');
-            });
-            self.updateLoadStatus('serviceMetrics');
-
-            updater.updateAlertGroups(function () {
-              updater.updateAlertDefinitions(function() {
-                updater.updateAlertDefinitionSummary(function () {
-                  updater.updateUnhealthyAlertInstances(function () {
-                    self.updateLoadStatus('alertGroups');
-                    self.updateLoadStatus('alertDefinitions');
-                    self.updateLoadStatus('alertInstancesUnhealthy');
+              updater.updateComponentsState(function () {
+                self.updateLoadStatus('componentsState');
+              });
+              self.updateLoadStatus('serviceMetrics');
+
+              updater.updateAlertGroups(function () {
+                updater.updateAlertDefinitions(function () {
+                  updater.updateAlertDefinitionSummary(function () {
+                    updater.updateUnhealthyAlertInstances(function () {
+                      self.updateLoadStatus('alertGroups');
+                      self.updateLoadStatus('alertDefinitions');
+                      self.updateLoadStatus('alertInstancesUnhealthy');
+                    });
                   });
                 });
               });
             });
           });
         });
-      });
-      self.loadRootService().done(function (data) {
-        App.rootServiceMapper.map(data);
-        self.updateLoadStatus('rootService');
-      });
-      // load security status
-      App.router.get('mainAdminKerberosController').getSecurityStatus().always(function() {
-        self.updateLoadStatus('securityStatus');
+        self.loadRootService().done(function (data) {
+          App.rootServiceMapper.map(data);
+          self.updateLoadStatus('rootService');
+        });
+        // load security status
+        App.router.get('mainAdminKerberosController').getSecurityStatus().always(function () {
+          self.updateLoadStatus('securityStatus');
+        });
       });
     });
   },
@@ -361,6 +364,36 @@ App.ClusterController = Em.Controller.extend({
     }, callback)
   },
 
+  /**
+   * Load data about created service components
+   * @param callback
+   */
+  loadServiceComponents: function (callback) {
+    App.ajax.send({
+      name: 'service.components.load',
+      sender: this,
+      data: {
+        callback: callback
+      },
+      success: 'loadStackServiceComponentsSuccess'
+    });
+  },
+
+  /**
+   * Callback for load service components request
+   * @param data
+   * @param request
+   * @param params
+   */
+  loadStackServiceComponentsSuccess: function (data, request, params) {
+    var serviceComponents = [];
+    data.items.forEach(function (service) {
+      serviceComponents = serviceComponents.concat(service.components.mapProperty('ServiceComponentInfo.component_name'));
+    });
+    App.serviceComponents = serviceComponents;
+    params.callback();
+  },
+
   /**
    *
    * @param callback

+ 1 - 29
ambari-web/app/controllers/main/admin/highAvailability/nameNode/step5_controller.js

@@ -22,7 +22,7 @@ App.HighAvailabilityWizardStep5Controller = App.HighAvailabilityProgressPageCont
 
   name:"highAvailabilityWizardStep5Controller",
 
-  commands: ['stopServices', 'installNameNode', 'checkJournalNodes', 'reconfigureHDFS', 'startJournalNodes', 'disableSNameNode'],
+  commands: ['stopServices', 'installNameNode', 'installJournalNodes', 'reconfigureHDFS', 'startJournalNodes', 'disableSNameNode'],
 
   hdfsSiteTag : "",
   coreSiteTag : "",
@@ -32,35 +32,7 @@ App.HighAvailabilityWizardStep5Controller = App.HighAvailabilityProgressPageCont
     this.createComponent('NAMENODE', hostName, "HDFS");
   },
 
-  checkJournalNodes: function() {
-    App.ajax.send({
-      name: 'admin.high_availability.check_journalnode',
-      sender: this,
-      success: 'onJournalNodeCheck',
-      error: 'onJournalNodeCheck'
-    });
-  },
-
-  onJournalNodeCheck: function(data) {
-    if (!(Em.get(data, 'ServiceComponentInfo.state') === 'INSTALLED')) {
-      this.installJournalNodes();
-    }
-    else {
-      var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE').mapProperty('hostName');
-      this.createComponent('JOURNALNODE', hostNames, "HDFS");
-    }
-  },
-
   installJournalNodes: function () {
-    App.ajax.send({
-      name: 'admin.high_availability.create_journalnode',
-      sender: this,
-      success: 'onJournalNodeCreate',
-      error: 'onJournalNodeCreate'
-    });
-  },
-
-  onJournalNodeCreate: function () {
     var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'JOURNALNODE').mapProperty('hostName');
     this.createComponent('JOURNALNODE', hostNames, "HDFS");
   },

+ 0 - 9
ambari-web/app/controllers/main/admin/highAvailability/nameNode/step9_controller.js

@@ -45,15 +45,6 @@ App.HighAvailabilityWizardStep9Controller = App.HighAvailabilityProgressPageCont
   },
 
   installZKFC: function () {
-    App.ajax.send({
-      name: 'admin.high_availability.create_zkfc',
-      sender: this,
-      success: 'onZKFCCreate',
-      error: 'onZKFCCreate'
-    });
-  },
-
-  onZKFCCreate: function () {
     var hostName = this.get('content.masterComponentHosts').filterProperty('component', 'NAMENODE').mapProperty('hostName');
     this.createComponent('ZKFC', hostName, "HDFS");
   },

+ 2 - 12
ambari-web/app/controllers/main/admin/kerberos/step2_controller.js

@@ -17,6 +17,7 @@
  */
 
 var App = require('app');
+var componentsUtils = require('utils/components');
 require('controllers/wizard/step7_controller');
 
 App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend({
@@ -136,7 +137,7 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend({
   createKerberosResources: function () {
     var self = this;
     this.createKerberosService().done(function () {
-      self.createKerberosComponent().done(function () {
+      componentsUtils.createServiceComponent('KERBEROS_CLIENT').done(function () {
         self.createKerberosHostComponents().done(function () {
           self.createConfigurations().done(function () {
             self.createKerberosAdminSession().done(function () {
@@ -173,17 +174,6 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend({
     });
   },
 
-  createKerberosComponent: function () {
-    return App.ajax.send({
-      name: 'common.create_component',
-      sender: this,
-      data: {
-        serviceName: this.selectedServiceNames[0],
-        componentName: this.componentName
-      }
-    });
-  },
-
   createKerberosHostComponents: function () {
     var hostNames = this.get('hostNames');
     var queryStr = '';

+ 35 - 7
ambari-web/app/controllers/wizard/step8_controller.js

@@ -1069,14 +1069,42 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
 
       // Service must be specified in terms of a query for creating multiple components at the same time.
       // See AMBARI-1018.
-      this.addRequestToAjaxQueue({
-        name: 'wizard.step8.create_components',
-        data: {
-          data: JSON.stringify({"components": componentsData}),
-          serviceName: serviceName
-        }
-      });
+      this.addRequestToCreateComponent(componentsData, serviceName);
     }, this);
+
+    if (this.get('content.controllerName') === 'addHostController') {
+      this.get('content.slaveComponentHosts').forEach(function (component) {
+        if (component.componentName !== 'CLIENT' && !App.serviceComponents.contains(component.componentName)) {
+          this.addRequestToCreateComponent(
+              [{"ServiceComponentInfo": {"component_name": component.componentName}}],
+              App.StackServiceComponent.find().findProperty('componentName', component.componentName).get('serviceName')
+          );
+        }
+      }, this);
+      this.get('content.clients').forEach(function (component) {
+        if (!App.serviceComponents.contains(component.component_name)) {
+          this.addRequestToCreateComponent(
+              [{"ServiceComponentInfo": {"component_name": component.component_name}}],
+              App.StackServiceComponent.find().findProperty('componentName', component.component_name).get('serviceName')
+          );
+        }
+      }, this);
+    }
+  },
+
+  /**
+   * Add request to ajax queue to create service component
+   * @param componentsData
+   * @param serviceName
+   */
+  addRequestToCreateComponent: function (componentsData, serviceName) {
+    this.addRequestToAjaxQueue({
+      name: 'wizard.step8.create_components',
+      data: {
+        data: JSON.stringify({"components": componentsData}),
+        serviceName: serviceName
+      }
+    });
   },
 
   /**

+ 16 - 13
ambari-web/app/mixins/wizard/wizardProgressPageController.js

@@ -17,6 +17,7 @@
  */
 
 var App = require('app');
+var componentsUtils = require('utils/components');
 
 /**
  * Mixin for wizard controller for showing command progress on wizard pages
@@ -515,19 +516,21 @@ App.wizardProgressPageControllerMixin = Em.Mixin.create({
         }
       };
       if (!!hostsWithoutComponents.length) {
-        App.ajax.send({
-          name: 'wizard.step8.register_host_to_component',
-          sender: self,
-          data: {
-            data: JSON.stringify(requestData),
-            hostName: result.mapProperty('hostName'),
-            componentName: componentName,
-            serviceName: serviceName,
-            taskNum: taskNum,
-            cluster: App.get('clusterName')
-          },
-          success: 'onCreateComponent',
-          error: 'onCreateComponent'
+        componentsUtils.createServiceComponent(componentName).done(function () {
+          App.ajax.send({
+            name: 'wizard.step8.register_host_to_component',
+            sender: self,
+            data: {
+              data: JSON.stringify(requestData),
+              hostName: result.mapProperty('hostName'),
+              componentName: componentName,
+              serviceName: serviceName,
+              taskNum: taskNum,
+              cluster: App.get('clusterName')
+            },
+            success: 'onCreateComponent',
+            error: 'onCreateComponent'
+          });
         });
       } else {
         self.onCreateComponent(null, null, {

+ 5 - 59
ambari-web/app/utils/ajax/ajax.js

@@ -1254,47 +1254,6 @@ var urls = {
     'real': '/clusters/{clusterName}/hosts/{hostName}/host_components/{componentName}',
     'mock': ''
   },
-  'admin.high_availability.create_component': {
-    'real': '/clusters/{clusterName}/hosts?Hosts/host_name={hostName}',
-    'mock': '',
-    'type': 'POST',
-    'format': function (data) {
-      return {
-        data: JSON.stringify({
-          "host_components": [
-            {
-              "HostRoles": {
-                "component_name": data.componentName
-              }
-            }
-          ]
-        })
-      }
-    }
-  },
-  'admin.high_availability.create_journalnode': {
-    'real': '/clusters/{clusterName}/services?ServiceInfo/service_name=HDFS',
-    'mock': '',
-    'type': 'POST',
-    'format': function () {
-      return {
-        data: JSON.stringify({
-          "components": [
-            {
-              "ServiceComponentInfo": {
-                "component_name": "JOURNALNODE"
-              }
-            }
-          ]
-        })
-      }
-    }
-  },
-  'admin.high_availability.check_journalnode': {
-    'real': '/clusters/{clusterName}/services/HDFS/components/JOURNALNODE?fields=ServiceComponentInfo/state',
-    'mock': ''
-  },
-
   'common.create_component': {
     'real': '/clusters/{clusterName}/services?ServiceInfo/service_name={serviceName}',
     'mock': '',
@@ -1313,24 +1272,6 @@ var urls = {
       }
     }
   },
-  'admin.high_availability.create_zkfc': {
-    'real': '/clusters/{clusterName}/services?ServiceInfo/service_name=HDFS',
-    'mock': '',
-    'type': 'POST',
-    'format': function () {
-      return {
-        data: JSON.stringify({
-          "components": [
-            {
-              "ServiceComponentInfo": {
-                "component_name": "ZKFC"
-              }
-            }
-          ]
-        })
-      }
-    }
-  },
   'admin.high_availability.load_configs': {
     'real': '/clusters/{clusterName}/configurations?(type=core-site&tag={coreSiteTag})|(type=hdfs-site&tag={hdfsSiteTag})',
     'mock': ''
@@ -2580,6 +2521,11 @@ var urls = {
         data: JSON.stringify(data.data)
       };
     }
+  },
+
+  'service.components.load': {
+    real: '/clusters/{clusterName}/services?fields=components&minimal_response=true',
+    mock: ''
   }
 };
 /**

+ 52 - 26
ambari-web/app/utils/components.js

@@ -19,33 +19,34 @@ var App = require('app');
 
 module.exports = {
   installHostComponent: function(hostName, component) {
-    var
-      self = this,
-      componentName = component.get('componentName'),
-      displayName = component.get('displayName');
-    App.ajax.send({
-      name: 'host.host_component.add_new_component',
-      sender: self,
-      data: {
-        hostName: hostName,
-        component: component,
-        data: JSON.stringify({
-          RequestInfo: {
-            "context": Em.I18n.t('requestInfo.installHostComponent') + " " + displayName
-          },
-          Body: {
-            host_components: [
-              {
-                HostRoles: {
-                  component_name: componentName
+    var self = this,
+        componentName = component.get('componentName'),
+        displayName = component.get('displayName');
+    this.createServiceComponent(componentName).done(function () {
+      App.ajax.send({
+        name: 'host.host_component.add_new_component',
+        sender: self,
+        data: {
+          hostName: hostName,
+          component: component,
+          data: JSON.stringify({
+            RequestInfo: {
+              "context": Em.I18n.t('requestInfo.installHostComponent') + " " + displayName
+            },
+            Body: {
+              host_components: [
+                {
+                  HostRoles: {
+                    component_name: componentName
+                  }
                 }
-              }
-            ]
-          }
-        })
-      },
-      success: 'addNewComponentSuccessCallback',
-      error: 'ajaxErrorCallback'
+              ]
+            }
+          })
+        },
+        success: 'addNewComponentSuccessCallback',
+        error: 'ajaxErrorCallback'
+      });
     });
   },
 
@@ -170,6 +171,31 @@ module.exports = {
     return dependencies.filter(function(dependency) {
       return !installedComponents.contains(dependency.componentName);
     }).mapProperty('componentName');
+  },
+
+  /**
+   *
+   * @param componentName
+   * @returns {*}
+   */
+  createServiceComponent: function (componentName) {
+    var dfd = $.Deferred();
+    if (App.serviceComponents.contains(componentName)) {
+      dfd.resolve();
+    } else {
+      App.ajax.send({
+        name: 'common.create_component',
+        sender: this,
+        data: {
+          componentName: componentName,
+          serviceName: App.StackServiceComponent.find().findProperty('componentName', componentName).get('serviceName')
+        }
+      }).complete(function () {
+        dfd.resolve();
+        App.serviceComponents.push(componentName);
+      });
+    }
+    return dfd.promise();
   }
 
 };

+ 1 - 0
ambari-web/test/controllers/main/host/details_test.js

@@ -547,6 +547,7 @@ describe('App.MainHostDetailsController', function () {
         componentName: 'COMP1',
         displayName: 'comp1'
       });
+      App.serviceComponents = ['COMP1'];
       controller.primary(component);
       expect(App.ajax.send.calledOnce).to.be.true;
     });

+ 14 - 0
ambari-web/test/mixins/wizard/wizardProgressPageController_test.js

@@ -45,10 +45,24 @@ describe('App.wizardProgressPageControllerMixin', function() {
         def.resolve(data[componentName]);
         return def.promise();
       });
+      sinon.stub(App.StackServiceComponent, 'find', function(){
+        return [
+          Em.Object.create({
+          componentName: 'ZOOKEEPER_CLIENT',
+          serviceName: 'ZOOKEEPER'
+        }),
+          Em.Object.create({
+          componentName: 'ZOOKEEPER_SERVER',
+          serviceName: 'ZOOKEEPER'
+        })
+        ];
+      });
+      App.serviceComponents = ['ZOOKEEPER_SERVER', 'ZOOKEEPER_CLIENT'];
     });
     
     afterEach(function() {
       App.ajax.send.restore();
+      App.StackServiceComponent.find.restore();
       mixedObjectInstance.onCreateComponent.restore();
       mixedObjectInstance.updateComponent.restore();
       mixedObjectInstance.checkInstalledComponents.restore();