Browse Source

AMBARI-6722. FE: Provide App.supports flag for recommendation and validation functionality (srimanth)

Srimanth Gunturi 10 năm trước cách đây
mục cha
commit
5ca07247bb

+ 2 - 1
ambari-web/app/config.js

@@ -80,7 +80,8 @@ App.supports = {
   views: false,
   flume: true,
   databaseConnection: true,
-  configHistory: false
+  configHistory: false,
+  serverRecommendValidate: false
 };
 
 if (App.enableExperimental) {

+ 162 - 2
ambari-web/app/controllers/wizard/step5_controller.js

@@ -20,6 +20,7 @@ var App = require('app');
 var numberUtils = require('utils/number_utils');
 
 App.WizardStep5Controller = Em.Controller.extend({
+
   name: "wizardStep5Controller",
 
   /**
@@ -214,7 +215,11 @@ App.WizardStep5Controller = Em.Controller.extend({
     console.log("WizardStep5Controller: Loading step5: Assign Masters");
     this.clearStep();
     this.renderHostInfo();
-    this.loadComponentRecommendations(this.loadStepCallback);
+    if (App.supports.serverRecommendValidate ) {
+      this.loadComponentRecommendationsFromServer(this.loadStepCallback);
+    } else {
+      this.loadComponentsRecommendationsLocally(this.loadStepCallback);
+    }
   },
 
   /**
@@ -300,7 +305,7 @@ App.WizardStep5Controller = Em.Controller.extend({
    * Get recommendations info from API
    * @return {undefined}
    */
-  loadComponentRecommendations: function(callback) {
+  loadComponentRecommendationsFromServer: function(callback) {
     var self = this;
 
     if (App.router.get('installerController.recommendations') !== undefined) {
@@ -437,6 +442,84 @@ App.WizardStep5Controller = Em.Controller.extend({
     App.router.set('installerController.recommendations', data.resources[0].recommendations);
   },
 
+  /**
+   * Load services info to appropriate variable and return masterComponentHosts
+   * @return {Object[]}
+   */
+  loadComponentsRecommendationsLocally: function (callback) {
+    var selectedServices = App.StackService.find().filterProperty('isSelected').mapProperty('serviceName');
+    var installedServices = App.StackService.find().filterProperty('isInstalled').mapProperty('serviceName');
+    var services = installedServices.concat(selectedServices).uniq();
+    var selectedNotInstalledServices = this.get('content.services').filterProperty('isSelected').filterProperty('isInstalled', false).mapProperty('serviceName');
+
+    var masterComponents = [];
+    //get full list from mock data
+    if (this.get('isAddServiceWizard')) {
+      masterComponents = App.StackServiceComponent.find().filterProperty('isShownOnAddServiceAssignMasterPage');
+    } else {
+      masterComponents = App.StackServiceComponent.find().filterProperty('isShownOnInstallerAssignMasterPage');
+    }
+    var masterHosts = this.get('content.masterComponentHosts'); //saved to local storage info
+
+    var resultComponents = [];
+
+    for (var index = 0; index < services.length; index++) {
+      var componentInfo = masterComponents.filterProperty('serviceName', services[index]);
+      // If service is already installed and not being added as a new service then render on UI only those master components
+      // that have already installed hostComponents.
+      // NOTE: On upgrade there might be a prior installed service with non-installed newly introduced serviceComponent
+      var isNotSelectedService = !selectedNotInstalledServices.contains(services[index]);
+      if (isNotSelectedService) {
+        componentInfo = componentInfo.filter(function (_component) {
+          return App.HostComponent.find().someProperty('componentName',_component.get('componentName'));
+        });
+      }
+
+      componentInfo.forEach(function (_componentInfo) {
+        if (this.get('multipleComponents').contains(_componentInfo.get('componentName'))) {
+          var savedComponents = masterHosts.filterProperty('component', _componentInfo.get('componentName'));
+          if (savedComponents.length) {
+            savedComponents.forEach(function (item) {
+              var multipleMasterHost = {};
+              multipleMasterHost.component_name = _componentInfo.get('componentName');
+              multipleMasterHost.display_name = _componentInfo.get('displayName');
+              multipleMasterHost.selectedHost = item.hostName;
+              multipleMasterHost.serviceId = services[index];
+              multipleMasterHost.isInstalled = item.isInstalled;
+              multipleMasterHost.isServiceCoHost = false;
+              resultComponents.push(multipleMasterHost);
+            })
+          } else {
+            var multipleMasterHosts = this.selectHostLocally(_componentInfo.get('componentName'));
+            multipleMasterHosts.forEach(function (_host) {
+              var multipleMasterHost = {};
+              multipleMasterHost.component_name = _componentInfo.get('componentName');
+              multipleMasterHost.display_name = _componentInfo.get('displayName');
+              multipleMasterHost.selectedHost = _host;
+              multipleMasterHost.serviceId = services[index];
+              multipleMasterHost.isInstalled = false;
+              multipleMasterHost.isServiceCoHost = false;
+              resultComponents.push(multipleMasterHost);
+            });
+
+          }
+        } else {
+          var savedComponent = masterHosts.findProperty('component', _componentInfo.get('componentName'));
+          var componentObj = {};
+          componentObj.component_name = _componentInfo.get('componentName');
+          componentObj.display_name = _componentInfo.get('displayName');
+          componentObj.selectedHost = savedComponent ? savedComponent.hostName : this.selectHostLocally(_componentInfo.get('componentName'));   // call the method that plays selectNode algorithm or fetches from server
+          componentObj.isInstalled = savedComponent ? savedComponent.isInstalled : false;
+          componentObj.serviceId = services[index];
+          componentObj.isServiceCoHost = App.StackServiceComponent.find().findProperty('componentName', _componentInfo.get('componentName')).get('isCoHostedComponent') && !this.get('isReassignWizard');
+          resultComponents.push(componentObj);
+        }
+      }, this);
+    }
+
+    callback(resultComponents, this);
+  },
+
   /**
    * @param {string} componentName
    * @returns {bool}
@@ -500,6 +583,83 @@ App.WizardStep5Controller = Em.Controller.extend({
     }, this);
   }.observes('selectedServicesMasters.@each.selectedHost'),
 
+  /**
+   * select and return host for component by scheme
+   * Scheme is an object that has keys which compared to number of hosts,
+   * if key more that number of hosts, then return value of that key.
+   * Value is index of host in hosts array.
+   *
+   * @param {object} componentName
+   * @param {object} hosts
+   * @return {string}
+   * @method getHostForComponent
+   */
+  getHostForComponent: function (componentName, hosts) {
+    var component = App.StackServiceComponent.find().findProperty('componentName', componentName);
+    if (component) {
+      var selectionScheme = App.StackServiceComponent.find().findProperty('componentName', componentName).get('selectionSchemeForMasterComponent');
+    } else {
+      return hosts[0];
+    }
+
+    if (hosts.length === 1 || $.isEmptyObject(selectionScheme)) {
+      return hosts[0];
+    } else {
+      for (var i in selectionScheme) {
+        if (window.isFinite(i)) {
+          if (hosts.length < window.parseInt(i)) {
+            return hosts[selectionScheme[i]];
+          }
+        }
+      }
+      return hosts[selectionScheme['else']]
+    }
+  },
+
+  /**
+   * Get list of host names for master component with multiple instances
+   * @param {Object} component
+   * @param {Object} hosts
+   * @returns {string[]}
+   * @method getHostsForComponent
+   */
+  getHostsForComponent: function (component, hosts) {
+    var defaultNoOfMasterHosts = component.get('defaultNoOfMasterHosts');
+    var masterHosts = [];
+    if (hosts.length < defaultNoOfMasterHosts) {
+      defaultNoOfMasterHosts = hosts.length;
+    }
+    for (var index = 0; index < defaultNoOfMasterHosts; index++) {
+      masterHosts.push(hosts[index]);
+    }
+    return masterHosts;
+  },
+
+  /**
+   * Return hostName of masterNode for specified service
+   * @param componentName
+   * @return {string|string[]}
+   * @method selectHostLocally
+   */
+  selectHostLocally: function (componentName) {
+    var component = App.StackServiceComponent.find().findProperty('componentName', componentName);
+    var hostNames = this.get('hosts').mapProperty('host_name');
+    if (hostNames.length > 1 && App.StackServiceComponent.find().filterProperty('isNotPreferableOnAmbariServerHost').mapProperty('componentName').contains(componentName)) {
+      hostNames = this.get('hosts').mapProperty('host_name').filter(function (item) {
+        return item !== location.hostname;
+      }, this);
+    }
+    if (this.get('multipleComponents').contains(componentName)) {
+      if (component.get('defaultNoOfMasterHosts') > 1) {
+        return this.getHostsForComponent(component, hostNames);
+      } else {
+        return [this.getHostForComponent(componentName, hostNames)];
+      }
+    } else {
+      return this.getHostForComponent(componentName, hostNames);
+    }
+  },
+
   /**
    * On change callback for inputs
    * @param {string} componentName

+ 49 - 22
ambari-web/app/controllers/wizard/step6_controller.js

@@ -345,36 +345,63 @@ App.WizardStep6Controller = Em.Controller.extend({
     var headers = this.get('headers');
     var slaveComponents = this.get('content.slaveComponentHosts');
     if (!slaveComponents) { // we are at this page for the first time
-      var recommendations = App.router.get('installerController.recommendations');
-      // Get all host-component pairs from recommendations
-      var componentHostPairs = recommendations.blueprint.host_groups.map(function(group) {
-        return group.components.map(function(component) {
-          return recommendations.blueprint_cluster_binding.host_groups.findProperty('name', group.name).hosts.map(function(host) {
-            return { component: component.name, host: host.fqdn};
+      if (!App.supports.serverRecommendValidate) {
+        var client_is_set = false;
+        hostsObj.forEach(function (host) {
+          var checkboxes = host.get('checkboxes');
+          checkboxes.setEach('checked', !host.hasMaster);
+          checkboxes.setEach('isInstalled', false);
+          checkboxes.findProperty('title', headers.findProperty('name', 'CLIENT').get('label')).set('checked', false);
+          // First not Master should have Client (only first!)
+          if (!client_is_set) {
+            var dfs = App.StackService.find().findProperty('isPrimaryDFS');
+            if (dfs.get('isSelected') || dfs.get('isInstalled')) {
+              var checkboxServiceComponent = checkboxes.findProperty('title', headers.findProperty('name', dfs.get('serviceComponents').
+                findProperty('isShownOnInstallerSlaveClientPage').get('componentName')).get('label'));
+              if (checkboxServiceComponent && checkboxServiceComponent.get('checked')) {
+                checkboxes.findProperty('title', headers.findProperty('name', 'CLIENT').get('label')).set('checked', true);
+                client_is_set = true;
+              }
+            }
+          }
+        });
+
+        if (this.get('isInstallerWizard') && hostsObj.everyProperty('hasMaster', true)) {
+          var lastHost = hostsObj[hostsObj.length - 1];
+          lastHost.get('checkboxes').setEach('checked', true);
+        }
+      } else {
+        var recommendations = App.router.get('installerController.recommendations');
+        // Get all host-component pairs from recommendations
+        var componentHostPairs = recommendations.blueprint.host_groups.map(function(group) {
+          return group.components.map(function(component) {
+            return recommendations.blueprint_cluster_binding.host_groups.findProperty('name', group.name).hosts.map(function(host) {
+              return { component: component.name, host: host.fqdn};
+            });
           });
         });
-      });
 
-      // Flatten results twice because of two map() call before
-      componentHostPairs = [].concat.apply([], componentHostPairs);
-      componentHostPairs = [].concat.apply([], componentHostPairs);
+        // Flatten results twice because of two map() call before
+        componentHostPairs = [].concat.apply([], componentHostPairs);
+        componentHostPairs = [].concat.apply([], componentHostPairs);
 
-      var clientComponents = App.get('components.clients');
+        var clientComponents = App.get('components.clients');
 
 
-      hostsObj.forEach(function (host) {
-        var checkboxes = host.get('checkboxes');
-        checkboxes.forEach(function(checkbox) {
-          var recommended = componentHostPairs.some(function(pair) {
-            var componentMatch = pair.component === checkbox.component;
-            if (checkbox.component === 'CLIENT' && !componentMatch) {
-              componentMatch = clientComponents.contains(pair.component);
-            }
-            return pair.host === host.hostName && componentMatch;
+        hostsObj.forEach(function (host) {
+          var checkboxes = host.get('checkboxes');
+          checkboxes.forEach(function(checkbox) {
+            var recommended = componentHostPairs.some(function(pair) {
+              var componentMatch = pair.component === checkbox.component;
+              if (checkbox.component === 'CLIENT' && !componentMatch) {
+                componentMatch = clientComponents.contains(pair.component);
+              }
+              return pair.host === host.hostName && componentMatch;
+            });
+            checkbox.checked = recommended;
           });
-          checkbox.checked = recommended;
         });
-      });
+      }
     } else {
       this.get('headers').forEach(function (header) {
         var nodes = slaveComponents.findProperty('componentName', header.get('name'));

+ 29 - 0
ambari-web/app/models/stack_service_component.js

@@ -193,6 +193,10 @@ App.StackServiceComponent = DS.Model.extend({
      }
   }.property('componentName'),
 
+  selectionSchemeForMasterComponent: function() {
+    return App.StackServiceComponent.selectionScheme(this.get('componentName'));
+  }.property('componentName'),
+
   /** @property {Boolean} coHostedComponents - components that are co-hosted with this component **/
   coHostedComponents: function() {
     var componentName = this.get('componentName');
@@ -220,6 +224,31 @@ App.StackServiceComponent = DS.Model.extend({
 
 App.StackServiceComponent.FIXTURES = [];
 
+App.StackServiceComponent.selectionScheme = function (componentName){
+  switch (componentName) {
+    case 'NAMENODE' :
+      return {"else": 0};
+    case 'SECONDARY_NAMENODE' :
+      return {"else": 1};
+    case 'HBASE_MASTER':
+      return {"6": 0, "31": 2, "else": 3};
+    case 'JOBTRACKER':
+    case 'HISTORYSERVER':
+    case 'RESOURCEMANAGER':
+    case 'APP_TIMELINE_SERVER':
+      return {"31": 1, "else": 2};
+    case 'OOZIE_SERVER':
+    case 'FALCON_SERVER' :
+      return {"6": 1, "31": 2, "else": 3};
+    case 'HIVE_SERVER' :
+    case 'HIVE_METASTORE' :
+    case 'WEBHCAT_SERVER' :
+      return {"6": 1, "31": 2, "else": 4};
+    default:
+      return {"else": 0};
+  }
+};
+
 App.StackServiceComponent.coHost = {
   'HIVE_METASTORE': 'HIVE_SERVER',
   'WEBHCAT_SERVER': 'HIVE_SERVER'