You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2014/01/16 15:47:56 UTC

git commit: AMBARI-4318. Service Restart All action cleanup. (onechiporenko)

Updated Branches:
  refs/heads/trunk 287c51fa9 -> 5b03e2bb8


AMBARI-4318. Service Restart All action cleanup. (onechiporenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5b03e2bb
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5b03e2bb
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5b03e2bb

Branch: refs/heads/trunk
Commit: 5b03e2bb85d3495645629cd185449b4d77194350
Parents: 287c51f
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Thu Jan 16 16:38:46 2014 +0200
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Thu Jan 16 16:47:49 2014 +0200

----------------------------------------------------------------------
 ambari-web/app/controllers/main/service/item.js |   4 +-
 ambari-web/app/utils/ajax.js                    |  34 +--
 .../app/utils/batch_scheduled_requests.js       | 253 +++++++++++--------
 3 files changed, 149 insertions(+), 142 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/5b03e2bb/ambari-web/app/controllers/main/service/item.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/item.js b/ambari-web/app/controllers/main/service/item.js
index 2efd2c1..91e353c 100644
--- a/ambari-web/app/controllers/main/service/item.js
+++ b/ambari-web/app/controllers/main/service/item.js
@@ -188,7 +188,9 @@ App.MainServiceItemController = Em.Controller.extend({
   },
 
   restartAllHostComponents : function(serviceName) {
-    batchUtils.restartAllServiceHostComponents(serviceName, false);
+    App.showConfirmationPopup(function() {
+      batchUtils.restartAllServiceHostComponents(serviceName, false);
+    });
   },
 
   rollingRestart: function(hostComponentName) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/5b03e2bb/ambari-web/app/utils/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax.js b/ambari-web/app/utils/ajax.js
index 38663d7..fce0c09 100644
--- a/ambari-web/app/utils/ajax.js
+++ b/ambari-web/app/utils/ajax.js
@@ -1282,44 +1282,12 @@ var urls = {
     'real': '/clusters/{clusterName}/request_schedules',
     'mock': '',
     'format' : function(data) {
-      var hostIndex = 0;
-      var batchSize = data.batchSize;
-      var hostComponents = data.restartHostComponents;
-      var length = hostComponents.length;
-      var batches = [];
-      var batchCount = Math.ceil(length / batchSize);
-      var sampleHostComponent = hostComponents.objectAt(0);
-      var componentName = sampleHostComponent.get('componentName');
-      var componentDisplayName = App.format.role(componentName);
-      var serviceName = sampleHostComponent.get('service.serviceName');
-      for ( var count = 0; count < batchCount; count++) {
-        var hostNames = [];
-        for ( var hc = 0; hc < batchSize && hostIndex < length; hc++) {
-          hostNames.push(hostComponents.objectAt(hostIndex++).get('host.hostName'));
-        }
-        if (hostNames.length > 0) {
-          batches.push({
-            "order_id" : count + 1,
-            "type" : "POST",
-            "uri" : App.apiPrefix + "/clusters/" + data.clusterName + "/requests",
-            "RequestBodyInfo" : {
-              "RequestInfo" : {
-                "context" : Em.I18n.t('rollingrestart.rest.context').format(componentDisplayName, (count + 1), batchCount),
-                "command" : "RESTART",
-                "service_name" : serviceName,
-                "component_name" : componentName,
-                "hosts" : hostNames.join(",")
-              }
-            }
-          });
-        }
-      }
       return {
         type : 'POST',
         data : JSON.stringify([ {
           "RequestSchedule" : {
             "batch" : [ {
-              "requests" : batches
+              "requests" : data.batches
             }, {
               "batch_settings" : {
                 "batch_separation_in_seconds" : data.intervalTimeSeconds,

http://git-wip-us.apache.org/repos/asf/ambari/blob/5b03e2bb/ambari-web/app/utils/batch_scheduled_requests.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/batch_scheduled_requests.js b/ambari-web/app/utils/batch_scheduled_requests.js
index 4212f86..ce3bf24 100644
--- a/ambari-web/app/utils/batch_scheduled_requests.js
+++ b/ambari-web/app/utils/batch_scheduled_requests.js
@@ -15,6 +15,31 @@
  * the License.
  */
 
+var App = require('app');
+
+/**
+ * Default success callback for ajax-requests in this module
+ * @type {Function}
+ */
+var defaultSuccessCallback = function() {
+  App.router.get('applicationController').dataLoading().done(function(initValue) {
+    if (initValue) {
+      App.router.get('backgroundOperationsController').showPopup();
+    }
+  });
+};
+/**
+ * Default error callback for ajax-requests in this module
+ * @param {Object} xhr
+ * @param {String} textStatus
+ * @param {String} error
+ * @param {Object} opt
+ * @type {Function}
+ */
+var defaultErrorCallback = function(xhr, textStatus, error, opt) {
+  App.ajax.defaultErrorHandler(xhr, opt.url, 'POST', xhr.status);
+};
+
 /**
  * Contains helpful utilities for handling batch and scheduled requests.
  */
@@ -24,35 +49,28 @@ module.exports = {
    * Some services have components which have a need for rolling restarts. This
    * method returns the name of the host-component which supports rolling
    * restarts for a service.
+   * @param {String} serviceName
    */
-  getRollingRestartComponentName : function(serviceName) {
-    var rollingRestartComponent = null;
-    switch (serviceName) {
-    case 'HDFS':
-      rollingRestartComponent = 'DATANODE';
-      break;
-    case 'YARN':
-      rollingRestartComponent = 'NODEMANAGER';
-      break;
-    case 'MAPREDUCE':
-      rollingRestartComponent = 'TASKTRACKER';
-      break;
-    case 'HBASE':
-      rollingRestartComponent = 'HBASE_REGIONSERVER';
-      break;
-    case 'STORM':
-      rollingRestartComponent = 'SUPERVISOR';
-      break;
-    default:
-      break;
-    }
-    return rollingRestartComponent;
+  getRollingRestartComponentName: function(serviceName) {
+    var rollingRestartComponents = {
+      HDFS: 'DATANODE',
+      YARN: 'NODEMANAGER',
+      MAPREDUCE: 'TASKTRACKER',
+      HBASE: 'HBASE_REGIONSERVER',
+      STORM: 'SUPERVISOR'
+    };
+    return rollingRestartComponents[serviceName] ? rollingRestartComponents[serviceName] : null;
   },
 
-  restartAllServiceHostComponents : function(serviceName, staleConfigsOnly) {
+  /**
+   * Facade-function for restarting host components of specific service
+   * @param {String} serviceName for which service hostComponents should be restarted
+   * @param {Boolean} staleConfigsOnly restart only hostComponents with <code>staleConfig</code> true
+   */
+  restartAllServiceHostComponents: function(serviceName, staleConfigsOnly) {
     var service = App.Service.find(serviceName);
     if (service) {
-      var hostComponents = service.get('hostComponents')
+      var hostComponents = service.get('hostComponents').filterProperty('isClient', false);
       if (staleConfigsOnly) {
         hostComponents = hostComponents.filterProperty('staleConfigs', true);
       }
@@ -60,42 +78,42 @@ module.exports = {
     }
   },
 
-  restartHostComponents : function(hostComponentsList) {
+  /**
+   * Restart list of host components
+   * @param {Array} hostComponentsList list of host components should be restarted
+   */
+  restartHostComponents: function(hostComponentsList) {
+    /**
+     * Format: {
+     *  'DATANODE': ['host1', 'host2'],
+     *  'NAMENODE': ['host1', 'host3']
+     *  ...
+     * }
+     * @type {Object}
+     */
     var componentToHostsMap = {};
-    var componentToServiceMap = {};
+    var componentServiceMap = App.QuickDataMapper.componentServiceMap();
     hostComponentsList.forEach(function(hc) {
       var componentName = hc.get('componentName');
       if (!componentToHostsMap[componentName]) {
         componentToHostsMap[componentName] = [];
       }
       componentToHostsMap[componentName].push(hc.get('host.hostName'));
-      componentToServiceMap[componentName] = hc.get('service.serviceName');
     });
-    for ( var componentName in componentToHostsMap) {
-      var hosts = componentToHostsMap[componentName].join(",");
-      var data = {
-        serviceName : componentToServiceMap[componentName],
-        componentName : componentName,
-        hosts : hosts
-      }
-      var sender = {
-        successFunction : function() {
-          App.router.get('applicationController').dataLoading().done(function(initValue) {
-            if (initValue) {
-              App.router.get('backgroundOperationsController').showPopup();
-            }
-          });
-        },
-        errorFunction : function(xhr, textStatus, error, opt) {
-          App.ajax.defaultErrorHandler(xhr, opt.url, 'POST', xhr.status);
-        }
-      }
+    for (var componentName in componentToHostsMap) {
       App.ajax.send({
-        name : 'restart.service.hostComponents',
-        sender : sender,
-        data : data,
-        success : 'successFunction',
-        error : 'errorFunction'
+        name: 'restart.service.hostComponents',
+        sender: {
+          successCallback: defaultSuccessCallback,
+          errorCallback: defaultErrorCallback
+        },
+        data: {
+          serviceName:  componentServiceMap[componentName],
+          componentName: componentName,
+          hosts: componentToHostsMap[componentName].join(",")
+        },
+        success: 'successCallback',
+        error: 'errorCallback'
       });
     }
   },
@@ -103,61 +121,95 @@ module.exports = {
   /**
    * Makes a REST call to the server requesting the rolling restart of the
    * provided host components.
+   * @param {Array} restartHostComponents list of host components should be restarted
+   * @param {Number} batchSize size of each batch
+   * @param {Number} intervalTimeSeconds delay between two batches
+   * @param {Number} tolerateSize task failure tolerance
+   * @param {Function} successCallback
+   * @param {Function} errorCallback
    */
-  _doPostBatchRollingRestartRequest : function(restartHostComponents, batchSize, intervalTimeSeconds, tolerateSize, successCallback, errorCallback) {
-    var clusterName = App.get('clusterName');
-    var data = {
-      restartHostComponents : restartHostComponents,
-      batchSize : batchSize,
-      intervalTimeSeconds : intervalTimeSeconds,
-      tolerateSize : tolerateSize,
-      clusterName : clusterName
+  _doPostBatchRollingRestartRequest: function(restartHostComponents, batchSize, intervalTimeSeconds, tolerateSize, successCallback, errorCallback) {
+    errorCallback = errorCallback ? errorCallback : defaultErrorCallback;
+    if (!restartHostComponents.length) {
+      console.log('No batch rolling restart if restartHostComponents is empty!');
+      return;
     }
-    var sender = {
-      successFunction : function() {
-        successCallback();
+    App.ajax.send({
+      name: 'rolling_restart.post',
+      sender: {
+        successCallback: successCallback,
+        errorCallback: errorCallback
       },
-      errorFunction : function(xhr, textStatus, error, opt) {
-        errorCallback(xhr, textStatus, error, opt);
+      data: {
+        intervalTimeSeconds: intervalTimeSeconds,
+        tolerateSize: tolerateSize,
+        batches: this.getBatchesForRollingRestartRequest(restartHostComponents, batchSize)
+      },
+      success: 'successCallback',
+      error: 'errorCallback'
+    });
+  },
+  /**
+   * Create list of batches for rolling restart request
+   * @param {Array} restartHostComponents list host components should be restarted
+   * @param {Number} batchSize size of each batch
+   * @returns {Array} list of batches
+   */
+  getBatchesForRollingRestartRequest: function(restartHostComponents, batchSize) {
+    var hostIndex = 0,
+        batches = [],
+        batchCount = Math.ceil(restartHostComponents.length / batchSize),
+        sampleHostComponent = restartHostComponents.objectAt(0),
+        componentName = sampleHostComponent.get('componentName'),
+        componentDisplayName = App.format.role(componentName),
+        serviceName = sampleHostComponent.get('service.serviceName');
+
+    for ( var count = 0; count < batchCount; count++) {
+      var hostNames = [];
+      for ( var hc = 0; hc < batchSize && hostIndex < restartHostComponents.length; hc++) {
+        hostNames.push(restartHostComponents.objectAt(hostIndex++).get('host.hostName'));
+      }
+      if (hostNames.length > 0) {
+        batches.push({
+          "order_id" : count + 1,
+          "type" : "POST",
+          "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
+          "RequestBodyInfo" : {
+            "RequestInfo" : {
+              "context" : Em.I18n.t('rollingrestart.rest.context').format(componentDisplayName, (count + 1), batchCount),
+              "command" : "RESTART",
+              "service_name" : serviceName,
+              "component_name" : componentName,
+              "hosts" : hostNames.join(",")
+            }
+          }
+        });
       }
     }
-    App.ajax.send({
-      name : 'rolling_restart.post',
-      sender : sender,
-      data : data,
-      success : 'successFunction',
-      error : 'errorFunction'
-    });
+    return batches;
   },
 
   /**
    * Launches dialog to handle rolling restarts of host components.
    *
-   * Rolling restart is supported for the following host components only
-   * <ul>
-   * <li>Data Nodes (HDFS)
-   * <li>Task Trackers (MapReduce)
-   * <li>Node Managers (YARN)
-   * <li>Region Servers (HBase)
-   * <li>Supervisors (Storm)
-   * </ul>
-   *
-   * @param {String}
-   *          hostComponentName Type of host-component to restart across cluster
+   * Rolling restart is supported only for components listed in <code>getRollingRestartComponentName</code>
+   * @see getRollingRestartComponentName
+   * @param {String} hostComponentName
+   *           Type of host-component to restart across cluster
    *          (ex: DATANODE)
-   * @param {Boolean}
-   *          staleConfigsOnly Pre-select host-components which have stale
+   * @param {Boolean} staleConfigsOnly
+   *           Pre-select host-components which have stale
    *          configurations
    */
-  launchHostComponentRollingRestart : function(hostComponentName, staleConfigsOnly) {
+  launchHostComponentRollingRestart: function(hostComponentName, staleConfigsOnly) {
     var componentDisplayName = App.format.role(hostComponentName);
     if (!componentDisplayName) {
       componentDisplayName = hostComponentName;
     }
     var self = this;
-    var title = Em.I18n.t('rollingrestart.dialog.title').format(componentDisplayName)
-    if (hostComponentName == "DATANODE" || hostComponentName == "TASKTRACKER" || hostComponentName == "NODEMANAGER"
-        || hostComponentName == "HBASE_REGIONSERVER" || hostComponentName == "SUPERVISOR") {
+    var title = Em.I18n.t('rollingrestart.dialog.title').format(componentDisplayName);
+    var allowedHostComponents = ["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER", "SUPERVISOR"];
+    if (allowedHostComponents.contains(hostComponentName)) {
       App.ModalPopup.show({
         header : title,
         hostComponentName : hostComponentName,
@@ -173,11 +225,10 @@ module.exports = {
         }),
         classNames : [ 'rolling-restart-popup' ],
         primary : Em.I18n.t('rollingrestart.dialog.primary'),
-        secondary : Em.I18n.t('common.cancel'),
         onPrimary : function() {
           var dialog = this;
           if (!dialog.get('enablePrimary')) {
-            return false;
+            return;
           }
           var restartComponents = this.get('innerView.restartHostComponents');
           var batchSize = this.get('innerView.batchSize');
@@ -185,26 +236,13 @@ module.exports = {
           var tolerateSize = this.get('innerView.tolerateSize');
           self._doPostBatchRollingRestartRequest(restartComponents, batchSize, waitTime, tolerateSize, function() {
             dialog.hide();
-            App.router.get('applicationController').dataLoading().done(function(initValue) {
-              if (initValue) {
-                App.router.get('backgroundOperationsController').showPopup();
-              }
-            });
-          }, function(xhr, textStatus, error, opt) {
-            App.ajax.defaultErrorHandler(xhr, opt.url, 'POST', xhr.status);
+            defaultSuccessCallback();
           });
-          return;
-        },
-        onSecondary : function() {
-          this.hide();
-        },
-        onClose : function() {
-          this.hide();
         },
         updateButtons : function() {
           var errors = this.get('innerView.errors');
           this.set('enablePrimary', !(errors != null && errors.length > 0))
-        }.observes('innerView.errors'),
+        }.observes('innerView.errors')
       });
     } else {
       var msg = Em.I18n.t('rollingrestart.notsupported.hostComponent').format(componentDisplayName);
@@ -214,10 +252,9 @@ module.exports = {
         secondary : false,
         msg : msg,
         bodyClass : Ember.View.extend({
-          template : Ember.Handlebars.compile('<div class="alert alert-warning">{{msg}}</div>'),
-          msg : msg
+          template : Ember.Handlebars.compile('<div class="alert alert-warning">{{msg}}</div>')
         })
       });
     }
   }
-}
\ No newline at end of file
+};
\ No newline at end of file