You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2014/01/25 04:37:08 UTC

git commit: AMBARI-4364. Add ability to decom/recom NodeManager from Host Details page. (xiwang via yusaku) AMBARI-4379. Add ability to decom/recom TaskTracker from Host Details page. (xiwang via yusaku)

Updated Branches:
  refs/heads/trunk f14dae7ef -> 930c8d909


AMBARI-4364. Add ability to decom/recom NodeManager from Host Details page. (xiwang via yusaku)
AMBARI-4379. Add ability to decom/recom TaskTracker from Host Details page. (xiwang via yusaku)


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

Branch: refs/heads/trunk
Commit: 930c8d909cde3c3ec87f09d75d7cc9d31ec9c51b
Parents: f14dae7
Author: Yusaku Sako <yu...@hortonworks.com>
Authored: Fri Jan 24 19:35:59 2014 -0800
Committer: Yusaku Sako <yu...@hortonworks.com>
Committed: Fri Jan 24 19:35:59 2014 -0800

----------------------------------------------------------------------
 ambari-web/app/controllers/main/host/details.js | 344 +++++++++-----
 ambari-web/app/messages.js                      |  11 +
 ambari-web/app/templates/main/host/summary.hbs  |  32 ++
 ambari-web/app/utils/ajax.js                    |  99 ++++
 ambari-web/app/views/main/host/summary.js       | 449 +++++++++++++++----
 5 files changed, 736 insertions(+), 199 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/930c8d90/ambari-web/app/controllers/main/host/details.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js
index 76d6d8e..f81a794 100644
--- a/ambari-web/app/controllers/main/host/details.js
+++ b/ambari-web/app/controllers/main/host/details.js
@@ -649,28 +649,34 @@ App.MainHostDetailsController = Em.Controller.extend({
       }
     });
   },
+
   /**
-   * send command to server to run decommission on DATANODE
+   * send command to server to run decommission on DATANODE, TASKTRACKER, NODEMANAGER, REGIONSERVER
    * @param event
    */
   decommission: function(event){
     var self = this;
-    var decommissionHostNames = this.get('view.decommissionDataNodeHostNames');
-    if (decommissionHostNames == null) {
-      decommissionHostNames = [];
-    }
     App.showConfirmationPopup(function(){
       var component = event.context;
-      // Only HDFS service as of now
       var svcName = component.get('service.serviceName');
+      var hostName = self.get('content.hostName');
+      // HDFS service, decommission DataNode
       if (svcName === "HDFS") {
-        var hostName = self.get('content.hostName');
-        var index = decommissionHostNames.indexOf(hostName);
-        if (index < 0) {
-          decommissionHostNames.push(hostName);
-        }
-        self.doDatanodeDecommission(decommissionHostNames, true);
+        self.doDecommission(hostName, svcName, "NAMENODE", "DATANODE");
+      }
+      // YARN service, decommission NodeManager
+      if (svcName === "YARN") {
+        self.doDecommission(hostName, svcName, "RESOURCEMANAGER", "NODEMANAGER");
+      }
+      // MAPREDUCE service, decommission TaskTracker
+      if (svcName === "MAPREDUCE") {
+        self.doDecommission(hostName, svcName, "JOBTRACKER", "TASKTRACKER");
+      }
+      // HBASE service, decommission RegionServer
+      if (svcName === "HBASE") {
+        self.doDecommissionRegionServer(hostName, svcName, "HBASE_MASTER", "HBASE_REGIONSERVER");
       }
+
       // load data (if we need to show this background operations popup) from persist
       App.router.get('applicationController').dataLoading().done(function (initValue) {
         if (initValue) {
@@ -679,107 +685,35 @@ App.MainHostDetailsController = Em.Controller.extend({
       });
     });
   },
-
-  /**
-   * Performs either Decommission or Recommission by updating the hosts list on
-   * server.
-   * @param {Array} decommissionHostNames
-   * @param {Boolean} decommission defines context for request (true for decommission and false for recommission)
-   */
-  doDatanodeDecommission: function(decommissionHostNames, decommission){
-    var self = this;
-    if (decommissionHostNames == null) {
-      decommissionHostNames = [];
-    }
-    var invocationTag = String(new Date().getTime());
-    var context = decommission ? Em.I18n.t('hosts.host.datanode.decommission') : Em.I18n.t('hosts.host.datanode.recommission');
-    var clusterName = App.router.get('clusterController.clusterName');
-    var clusterUrl = App.apiPrefix + '/clusters/' + clusterName;
-    var configsUrl = clusterUrl + '/configurations';
-    var configsData = {
-      type: "hdfs-exclude-file",
-      tag: invocationTag,
-      properties: {
-        datanodes: decommissionHostNames.join(',')
-      }
-    };
-    var configsAjax = {
-      type: 'POST',
-      url: configsUrl,
-      dataType: 'json',
-      data: JSON.stringify(configsData),
-      timeout: App.timeout,
-      success: function(){
-        var actionsUrl = clusterUrl + '/requests';
-        var actionsData = {
-          RequestInfo: {
-            context: context,
-            command: 'DECOMMISSION_DATANODE',
-            service_name: 'HDFS',
-            parameters: {
-              excludeFileTag: invocationTag
-            }
-          }
-        };
-        var actionsAjax = {
-          type: 'POST',
-          url: actionsUrl,
-          dataType: 'json',
-          data: JSON.stringify(actionsData),
-          timeout: App.timeout,
-          success: function(){
-            var persistUrl = App.apiPrefix + '/persist';
-            var persistData = {
-              "decommissionDataNodesTag": invocationTag
-            };
-            var persistPutAjax = {
-              type: 'POST',
-              url: persistUrl,
-              dataType: 'json',
-              data: JSON.stringify(persistData),
-              timeout: App.timeout,
-              success: function(){
-                var view = self.get('view');
-                view.loadDecommissionNodesList();
-              }
-            };
-            jQuery.ajax(persistPutAjax);
-          },
-          error: function(xhr, textStatus, errorThrown){
-            console.log(textStatus);
-            console.log(errorThrown);
-          }
-        };
-        jQuery.ajax(actionsAjax);
-      },
-      error: function(xhr, textStatus, errorThrown){
-        console.log(textStatus);
-        console.log(errorThrown);
-      }
-    };
-    jQuery.ajax(configsAjax);
-  },
-
+  
   /**
-   * send command to server to run recommission on DATANODE
+   * send command to server to run recommission on DATANODE, TASKTRACKER, NODEMANAGER
    * @param event
    */
   recommission: function(event){
     var self = this;
-    var decommissionHostNames = this.get('view.decommissionDataNodeHostNames');
-    if (decommissionHostNames == null) {
-      decommissionHostNames = [];
-    }
     App.showConfirmationPopup(function(){
       var component = event.context;
-      // Only HDFS service as of now
       var svcName = component.get('service.serviceName');
+      var hostName = self.get('content.hostName');
+      var start_context = Em.I18n.t('requestInfo.startHostComponent') + " " + component.get('displayName');
+      // HDFS service, Recommission datanode
       if (svcName === "HDFS") {
-        var hostName = self.get('content.hostName');
-        var index = decommissionHostNames.indexOf(hostName);
-        decommissionHostNames.splice(index, 1);
-        self.doDatanodeDecommission(decommissionHostNames, false);
+        self.doRecommissionAndStart(hostName, svcName, "NAMENODE", "DATANODE", start_context);
       }
+      // YARN service, Recommission nodeManager
+      if (svcName === "YARN") {
+        self.doRecommissionAndStart(hostName, svcName, "RESOURCEMANAGER", "NODEMANAGER", start_context);
+      }
+      // MAPREDUCE service, Recommission taskTracker
+      if (svcName === "MAPREDUCE") {
+        self.doRecommissionAndRestart(hostName, svcName, "JOBTRACKER", "TASKTRACKER");
+      }
+      // HBASE service, Recommission RegionServer
+      if (svcName === "HBASE") {
+        self.doRecommissionAndStart(hostName, svcName, "HBASE_MASTER", "HBASE_REGIONSERVER", start_context);
+      }
+
       // load data (if we need to show this background operations popup) from persist
       App.router.get('applicationController').dataLoading().done(function (initValue) {
         if (initValue) {
@@ -788,7 +722,209 @@ App.MainHostDetailsController = Em.Controller.extend({
       });
     });
   },
-  
+
+  /**
+   * Performs Decommission (for DN, TT and NM)
+   */
+  doDecommission: function(hostName, serviceName, componentName, slaveType){
+    var contextNameString = 'hosts.host.' + slaveType.toLowerCase() + '.decommission';
+    var context = Em.I18n.t(contextNameString);
+    App.ajax.send({
+      name: 'host.host_component.decommission_slave',
+      sender: this,
+      data: {
+        context: context,
+        command: 'DECOMMISSION',
+        hostName: hostName,
+        serviceName: serviceName ,
+        componentName: componentName,
+        slaveType: slaveType
+      },
+      success: 'decommissionSuccessCallback',
+      error: 'decommissionErrorCallback'
+    });
+  },
+
+  /**
+   * Performs Decommission (for RegionServer)
+   */
+  doDecommissionRegionServer: function(hostName, serviceName, componentName, slaveType){
+
+    App.ajax.send({
+      name: 'host.host_component.recommission_and_restart',
+      sender: this,
+      data: {
+        intervalTimeSeconds: 1,
+        toleratePercentage : 50,
+        batches:[
+          {
+            "order_id" : 1,
+            "type" : "POST",
+            "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
+            "RequestBodyInfo" : {
+              "RequestInfo" : {
+                "context" : Em.I18n.t('hosts.host.regionserver.decommission.batch1'),
+                "command" : "DECOMMISSION",
+                "service_name" : serviceName,
+                "component_name" : componentName,
+                "parameters" : {
+                  "slave_type": slaveType,
+                  "excluded_hosts": hostName
+                }
+              }
+            }
+          },
+          {
+            "order_id" : 2,
+            "type" : "PUT",
+            "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/hosts/" + hostName + "/host_components/" + slaveType.toUpperCase(),
+            "RequestBodyInfo" : {
+              "RequestInfo" : {
+                "context" : Em.I18n.t('hosts.host.regionserver.decommission.batch2')
+              },
+              "Body": {
+                "HostRoles": {
+                  "state": 'INSTALLED'
+                }
+              }
+            }
+          },
+          {
+            "order_id" : 3,
+            "type" : "POST",
+            "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
+            "RequestBodyInfo" : {
+              "RequestInfo" : {
+                "context" : Em.I18n.t('hosts.host.regionserver.decommission.batch3'),
+                "command" : "DECOMMISSION",
+                "service_name" : serviceName,
+                "component_name" : componentName,
+                "parameters" : {
+                  "slave_type": slaveType,
+                  "excluded_hosts": hostName,
+                  "mark_draining_only": "true"
+                }
+              }
+            }
+          }
+        ]
+      },
+      success: 'decommissionSuccessCallback',
+      error: 'decommissionErrorCallback'
+    });
+  },
+
+  decommissionAndStartSuccessCallback: function (response, request, data) {
+    console.log('Success in decommission callback:' + response);
+    if (!App.testMode) {
+      App.router.get('clusterController').loadUpdatedStatusDelayed(500);
+    }
+  },
+  decommissionSuccessCallback: function (response, request, data) {
+    console.log('Success in decommission callback:' + response);
+  },
+  decommissionErrorCallback: function (request, ajaxOptions, error) {
+    console.log('ERROR: '+ error);
+  },
+
+  doRecommissionAndStart:  function(hostName, serviceName, componentName, slaveType, startContext){
+    var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
+    var context_1 = Em.I18n.t(contextNameString_1);
+    App.ajax.send({
+      name: 'host.host_component.recommission_and_restart',
+      sender: this,
+      data: {
+        intervalTimeSeconds: 1,
+        toleratePercentage : 50,
+        batches:[
+          {
+            "order_id" : 1,
+            "type" : "POST",
+            "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
+            "RequestBodyInfo" : {
+              "RequestInfo" : {
+                "context" : context_1,
+                "command" : "DECOMMISSION",
+                "service_name" : serviceName,
+                "component_name" : componentName,
+                "parameters" : {
+                  "slave_type": slaveType,
+                  "included_hosts": hostName
+                }
+              }
+            }
+          },
+          {
+            "order_id" : 2,
+            "type" : "PUT",
+            "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/hosts/" + hostName + "/host_components/" + slaveType.toUpperCase(),
+            "RequestBodyInfo" : {
+              "RequestInfo" : {
+                "context" : startContext
+              },
+              "Body": {
+                "HostRoles": {
+                  "state": 'STARTED'
+                }
+              }
+            }
+          }
+        ]
+      },
+      success: 'decommissionAndStartSuccessCallback',
+      error: 'decommissionErrorCallback'
+    });
+  },
+  doRecommissionAndRestart:  function(hostName, serviceName, componentName, slaveType){
+    var contextNameString_1 = 'hosts.host.' + slaveType.toLowerCase() + '.recommission';
+    var context_1 = Em.I18n.t(contextNameString_1);
+    var contextNameString_2 = 'hosts.host.' + slaveType.toLowerCase() + '.restart';
+    var context_2 = Em.I18n.t(contextNameString_2);
+    App.ajax.send({
+      name: 'host.host_component.recommission_and_restart',
+      sender: this,
+      data: {
+        intervalTimeSeconds: 1,
+        toleratePercentage : 50,
+        batches:[
+          {
+            "order_id" : 1,
+            "type" : "POST",
+            "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
+            "RequestBodyInfo" : {
+              "RequestInfo" : {
+                "context" : context_1,
+                "command" : "DECOMMISSION",
+                "service_name" : serviceName,
+                "component_name" : componentName,
+                "parameters" : {
+                  "slave_type": slaveType,
+                  "included_hosts": hostName
+                }
+              }
+            }
+          },
+          {
+            "order_id" : 2,
+            "type" : "POST",
+            "uri" : App.apiPrefix + "/clusters/" + App.get('clusterName') + "/requests",
+            "RequestBodyInfo" : {
+              "RequestInfo" : {
+                "context" : context_2,
+                "command" : "RESTART",
+                "service_name" : serviceName,
+                "component_name" : slaveType,
+                "hosts" : hostName
+              }
+            }
+          }
+        ]
+      },
+      success: 'decommissionSuccessCallback',
+      error: 'decommissionErrorCallback'
+    });
+  },
+
   doAction: function(option) {
     switch (option.context.action) {
       case "deleteHost":

http://git-wip-us.apache.org/repos/asf/ambari/blob/930c8d90/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 1bf7a52..5e9a68f 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1401,6 +1401,17 @@ Em.I18n.translations = {
   'hosts.host.addComponent.securityNote':'You are running your cluster in secure mode. You must set up the keytab for {0} on {1} before you proceed. Otherwise, the component will not be able to start properly.',
   'hosts.host.datanode.decommission':'Decommission DataNode',
   'hosts.host.datanode.recommission':'Recommission DataNode',
+  'hosts.host.nodemanager.decommission':'Decommission NodeManager',
+  'hosts.host.nodemanager.recommission':'Recommission NodeManager',
+  'hosts.host.tasktracker.decommission':'Decommission TaskTracker',
+  'hosts.host.tasktracker.recommission':'Recommission TaskTracker',
+  'hosts.host.tasktracker.restart':'Restart TaskTracker',
+  'hosts.host.regionserver.decommission.batch1':'Decommission RegionServer - Turn drain mode on',
+  'hosts.host.regionserver.decommission.batch2':'Decommission RegionServer - Stop RegionServer',
+  'hosts.host.regionserver.decommission.batch3':'Decommission RegionServer - Turn drain mode off',
+  'hosts.host.regionserver.recommission':'Recommission HBase RegionServer',
+  'hosts.host.decommissioned':'Decommissioned',
+  'hosts.host.decommissioning':'Decommissioning...',
 
 
   'hosts.host.alert.noAlerts':'No alerts',

http://git-wip-us.apache.org/repos/asf/ambari/blob/930c8d90/ambari-web/app/templates/main/host/summary.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/host/summary.hbs b/ambari-web/app/templates/main/host/summary.hbs
index ecda7f8..072676c 100644
--- a/ambari-web/app/templates/main/host/summary.hbs
+++ b/ambari-web/app/templates/main/host/summary.hbs
@@ -90,6 +90,38 @@
                       </li>
                     {{/if}}
                   {{/if}}
+                  {{#if view.isNodeManager}}
+                    {{#if view.isNodeManagerDecommissionAvailable}}
+                        <li {{bindAttr class="view.noActionAvailable"}}>
+                            <a href="javascript:void(null)" data-toggle="modal" {{action "decommission" view.content target="controller"}}>
+                              {{t common.decommission}}
+                            </a>
+                        </li>
+                    {{/if}}
+                    {{#if view.isNodeManagerRecommissionAvailable}}
+                        <li {{bindAttr class="view.noActionAvailable"}}>
+                            <a href="javascript:void(null)" data-toggle="modal" {{action "recommission" view.content target="controller"}}>
+                              {{t common.recommission}}
+                            </a>
+                        </li>
+                    {{/if}}
+                  {{/if}}
+                  {{#if view.isTaskTracker}}
+                    {{#if view.isTaskTrackerDecommissionAvailable}}
+                        <li {{bindAttr class="view.noActionAvailable"}}>
+                            <a href="javascript:void(null)" data-toggle="modal" {{action "decommission" view.content target="controller"}}>
+                              {{t common.decommission}}
+                            </a>
+                        </li>
+                    {{/if}}
+                    {{#if view.isTaskTrackerRecommissionAvailable}}
+                        <li {{bindAttr class="view.noActionAvailable"}}>
+                            <a href="javascript:void(null)" data-toggle="modal" {{action "recommission" view.content target="controller"}}>
+                              {{t common.recommission}}
+                            </a>
+                        </li>
+                    {{/if}}
+                  {{/if}}
                   {{#if view.isDeletableComponent}}
                     <li {{bindAttr class="view.isDeleteComponentDisabled:disabled"}}>
                       <a href="javascript:void(null)" data-toggle="modal" {{action "deleteComponent" view.content target="controller"}}>

http://git-wip-us.apache.org/repos/asf/ambari/blob/930c8d90/ambari-web/app/utils/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax.js b/ambari-web/app/utils/ajax.js
index c7d73a1..49ce65b 100644
--- a/ambari-web/app/utils/ajax.js
+++ b/ambari-web/app/utils/ajax.js
@@ -327,6 +327,105 @@ var urls = {
       }
     }
   },
+  'host.host_component.slave_desired_admin_state': {
+    'real': '/clusters/{clusterName}/hosts/{hostName}/host_components/{componentName}/?fields=HostRoles/desired_admin_state',
+    'mock': '',
+    'type': 'GET',
+    'format': function (data, opt) {
+      return {
+      };
+    }
+  },
+  'host.host_component.datanodes_decommission_status': {
+    'real': '/clusters/{clusterName}/services/HDFS/components/NAMENODE/?fields=ServiceComponentInfo',
+    'mock': '',
+    'type': 'GET',
+    'format': function (data, opt) {
+      return {
+      };
+    }
+  },
+  'host.host_component.nodemanager_decommission_status': {
+    'real': '/clusters/{clusterName}/services/YARN/components/RESOURCEMANAGER/?fields=ServiceComponentInfo',
+    'mock': '',
+    'type': 'GET',
+    'format': function (data, opt) {
+      return {
+      };
+    }
+  },
+  'host.host_component.tasktracker_decommission_status': {
+    'real': '/clusters/{clusterName}/services/MAPREDUCE/components/JOBTRACKER/?fields=ServiceComponentInfo',
+    'mock': '',
+    'type': 'GET',
+    'format': function (data, opt) {
+      return {
+      };
+    }
+  },
+  'host.host_component.decommission_slave': {
+    'real' : '/clusters/{clusterName}/requests',
+    'mock' : '',
+    'format' : function(data) {
+      return {
+        type : 'POST',
+        data : JSON.stringify({
+          RequestInfo: {
+            'context': data.context,
+            'command': data.command,
+            'service_name': data.serviceName,
+            'component_name': data.componentName,
+            'parameters': {
+              'slave_type': data.slaveType,
+              'excluded_hosts': data.hostName
+            }
+          }
+        })
+      }
+    }
+  },
+  'host.host_component.recommission_and_restart': {
+    'real': '/clusters/{clusterName}/request_schedules',
+    'mock': '',
+    'format' : function(data) {
+      return {
+        type : 'POST',
+        data : JSON.stringify([ {
+          "RequestSchedule" : {
+            "batch" : [ {
+              "requests" : data.batches
+            }, {
+              "batch_settings" : {
+                "batch_separation_in_seconds" : data.intervalTimeSeconds,
+                "task_failure_tolerance" : data.toleratePercentage
+              }
+            } ]
+          }
+        } ])
+      }
+    }
+  },
+  'host.host_component.recommission_slave' : {
+    'real' : '/clusters/{clusterName}/requests',
+    'mock' : '',
+    'format' : function(data) {
+      return {
+        type : 'POST',
+        data : JSON.stringify({
+          RequestInfo: {
+            context: data.context,
+            command: data.command,
+            service_name: data.serviceName,
+            component_name: data.componentName,
+            parameters: {
+              slave_type: data.slaveType,
+              included_hosts: data.hostName
+            }
+          }
+        })
+      }
+    }
+  },
   'host.stale_host_components.start_stop': {
     'real': '/clusters/{clusterName}/hosts/{hostName}/host_components?HostRoles/stale_configs=true&' +
             'HostRoles/component_name.in({componentNames})',

http://git-wip-us.apache.org/repos/asf/ambari/blob/930c8d90/ambari-web/app/views/main/host/summary.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/summary.js b/ambari-web/app/views/main/host/summary.js
index dc3f2a6..18875c3 100644
--- a/ambari-web/app/views/main/host/summary.js
+++ b/ambari-web/app/views/main/host/summary.js
@@ -45,70 +45,10 @@ App.MainHostSummaryView = Em.View.extend({
     return Em.I18n.t('hosts.host.details.needToRestart').format(this.get('content.componentsWithStaleConfigsCount'), word);
   }.property('content.componentsWithStaleConfigsCount'),
 
-  /**
-   * @type: [{String}]
-   */
-  decommissionDataNodeHostNames: null,
-
-  loadDecommissionNodesList: function () {
-    var self = this;
-    var clusterName = App.router.get('clusterController.clusterName');
-    var persistUrl = App.apiPrefix + '/persist/decommissionDataNodesTag';
-    var clusterUrl = App.apiPrefix + '/clusters/' + clusterName;
-    var getConfigAjax = {
-      type: 'GET',
-      url: persistUrl,
-      dataType: 'json',
-      timeout: App.timeout,
-      success: function (decommissionDataNodesTag) {
-        if (decommissionDataNodesTag) {
-          // We know the tag which contains the decommisioned nodes.
-          var configsUrl = clusterUrl + '/configurations?type=hdfs-exclude-file&tag=' + decommissionDataNodesTag;
-          var decomNodesAjax = {
-            type: 'GET',
-            url: configsUrl,
-            dataType: 'json',
-            timeout: App.timeout,
-            success: function (data) {
-              if (data && data.items) {
-                var csv = data.items[0].properties.datanodes;
-                if (csv!==null && csv.length>0) {
-                  self.set('decommissionDataNodeHostNames', csv.split(','));  
-                } else {
-                  self.set('decommissionDataNodeHostNames', null);  
-                }
-              }
-            },
-            error: function (xhr, textStatus, errorThrown) {
-              console.log(textStatus);
-              console.log(errorThrown);
-            }
-          };
-          jQuery.ajax(decomNodesAjax);
-        }
-      },
-      error: function (xhr, textStatus, errorThrown) {
-        // No tag pointer in persist. Rely on service's decomNodes.
-        var hdfsSvcs = App.HDFSService.find();
-        if (hdfsSvcs && hdfsSvcs.get('length') > 0) {
-          var hdfsSvc = hdfsSvcs.objectAt(0);
-          if (hdfsSvc) {
-            var hostNames = [];
-            var decomNodes = hdfsSvc.get('decommissionDataNodes');
-            decomNodes.forEach(function (decomNode) {
-              hostNames.push(decomNode.get('hostName'));
-            });
-            self.set('decommissionDataNodeHostNames', hostNames);
-          }
-        }
-      }
-    };
-    jQuery.ajax(getConfigAjax);
-  },
   didInsertElement: function () {
-    if (this.get('content.hostComponents').someProperty('componentName', 'DATANODE')) {
-      this.loadDecommissionNodesList();
-    }
+    //if (this.get('content.hostComponents').someProperty('componentName', 'DATANODE')) {
+      //this.loadDecommissionNodesList();
+    //}
     this.addToolTip();
   },
   addToolTip: function() {
@@ -287,6 +227,15 @@ App.MainHostSummaryView = Em.View.extend({
       if (this.get('isInProgress')) {
         this.doBlinking();
       }
+      if (this.get('isDataNode')){
+        this.loadDataNodeDecommissionStatus();
+      }
+      if (this.get('isNodeManager')){
+        this.loadNodeManagerDecommissionStatus();
+      }
+      if (this.get('isTaskTracker')){
+        this.loadTaskTrackerDecommissionStatus();
+      }
     },
     hostComponent: function () {
       var hostComponent = null;
@@ -315,17 +264,22 @@ App.MainHostSummaryView = Em.View.extend({
       var hostComponent = this.get('hostComponent');
       if (hostComponent) {
         componentTextStatus = hostComponent.get('componentTextStatus');
-        if(this.get("isDataNode"))
-          if(this.get('isDataNodeRecommissionAvailable')){
-            if(hostComponent.get('isDecommissioning')){
-              componentTextStatus = "Decommissioning...";
-            } else {
-              componentTextStatus = "Decommissioned";
-            }
+        if(this.get("isDataNode") && this.get('isDataNodeRecommissionAvailable')){
+          if(this.get('isDataNodeDecommissioning')){
+            componentTextStatus = Em.I18n.t('hosts.host.decommissioning');
+          } else {
+            componentTextStatus = Em.I18n.t('hosts.host.decommissioned');
           }
+        }
+        if(this.get("isNodeManager") && this.get('isNodeManagerRecommissionAvailable')){
+          componentTextStatus = Em.I18n.t('hosts.host.decommissioned');
+        }
+        if(this.get("isTaskTracker") && this.get('isTaskTrackerRecommissionAvailable')){
+          componentTextStatus = Em.I18n.t('hosts.host.decommissioned');
+        }
       }
       return componentTextStatus;
-    }.property('workStatus','isDataNodeRecommissionAvailable'),
+    }.property('workStatus','isDataNodeRecommissionAvailable', 'isDataNodeDecommissioning', 'isNodeManagerRecommissionAvailable','isTaskTrackerRecommissionAvailable'),
 
     statusClass: function () {
       //If the component is DataNode
@@ -335,6 +289,20 @@ App.MainHostSummaryView = Em.View.extend({
         }
       }
 
+      //If the component is NodeManager
+      if (this.get('isNodeManager')) {
+        if (this.get('isNodeManagerRecommissionAvailable') && (this.get('isStart') || this.get('workStatus') == 'INSTALLED')) {
+          return 'health-status-DEAD-ORANGE';
+        }
+      }
+
+      //If the component is TaskTracker
+      if (this.get('isTaskTracker')) {
+        if (this.get('isTaskTrackerRecommissionAvailable') && (this.get('isStart') || this.get('workStatus') == 'INSTALLED')) {
+          return 'health-status-DEAD-ORANGE';
+        }
+      }
+
       //Class when install failed
       if (this.get('workStatus') === App.HostComponentStatus.install_failed) {
         return 'health-status-color-red icon-cog';
@@ -352,7 +320,7 @@ App.MainHostSummaryView = Em.View.extend({
 
       //For all other cases
       return 'health-status-' + App.HostComponentStatus.getKeyName(this.get('workStatus'));
-    }.property('workStatus', 'isDataNodeRecommissionAvailable', 'this.content.isDecommissioning'),
+    }.property('workStatus', 'isDataNodeRecommissionAvailable', 'isNodeManagerRecommissionAvailable', 'isTaskTrackerRecommissionAvailable'),
 
     disabled: function () {
       return (this.get('parentView.content.healthClass') === "health-status-DEAD-YELLOW") ? 'disabled' : '';
@@ -391,13 +359,13 @@ App.MainHostSummaryView = Em.View.extend({
       }
     },
     /**
-     * Start blinking when host component is starting/stopping
+     * Start blinking when host component is starting/stopping/decommissioning
      */
     startBlinking: function () {
       this.$('.components-health').stop(true, true);
       this.$('.components-health').css({opacity: 1.0});
       this.doBlinking();
-    }.observes('workStatus','isDataNodeRecommissionAvailable'),
+    }.observes('workStatus','isDataNodeRecommissionAvailable', 'isDecommissioning'),
 
     isStart: function () {
       return (this.get('workStatus') == App.HostComponentStatus.started || this.get('workStatus') == App.HostComponentStatus.starting);
@@ -426,43 +394,334 @@ App.MainHostSummaryView = Em.View.extend({
       return (this.get('workStatus') === App.HostComponentStatus.stopping || 
           this.get('workStatus') === App.HostComponentStatus.starting) || 
           this.get('isDecommissioning');
-    }.property('workStatus', 'isDataNodeRecommissionAvailable'),
-    /**
-     * Shows whether we need to show Decommision/Recomission buttons
-     */
+    }.property('workStatus', 'isDecommissioning'),
+
     isDataNode: function () {
       return this.get('content.componentName') === 'DATANODE';
     }.property('content'),
-
-    isDecommissioning: function () {
-      var hostComponentDecommissioning = this.get('hostComponent.isDecommissioning');
-      return this.get('isDataNode') &&  this.get("isDataNodeRecommissionAvailable") && hostComponentDecommissioning;
-    }.property("workStatus", "isDataNodeRecommissionAvailable", "hostComponent.isDecommissioning"),
+    isNodeManager: function () {
+      return this.get('content.componentName') === 'NODEMANAGER';
+    }.property('content'),
+    isTaskTracker: function () {
+      return this.get('content.componentName') === 'TASKTRACKER';
+    }.property('content'),
+    isRegionServer: function () {
+      return this.get('content.componentName') === 'HBASE_REGIONSERVER';
+    }.property('content'),
 
     isInMaintenance: function () {
       return (this.get('workStatus') == App.HostComponentStatus.maintenance);
     }.property("workStatus"),
 
+
+    isDecommissioning: function () {
+      //the slaves is decommissioning.
+      return this.get('isDataNode') && this.get("isDataNodeDecommissioning");
+    }.property("workStatus", "isDataNodeDecommissioning"),
+
+    isDataNodeDecommissioning: null,
+    isDataNodeDecommissionAvailable: null,
+    isDataNodeRecommissionAvailable: null,
+
+    /**
+     * load Recommission/Decommission status from adminState of each live node
+     */
+    loadDataNodeDecommissionStatus: function () {
+      var clusterName = App.router.get('clusterController.clusterName');
+      var hostName = App.router.get('mainHostDetailsController.content.hostName');
+      var componentName = 'NAMENODE';
+      var slaveType = 'DATANODE';
+      var version = App.get('currentStackVersionNumber');
+      var dfd = $.Deferred();
+      var self = this;
+      this.getDNDecommissionStatus(clusterName, hostName, componentName).done(function () {
+        var curObj = self.get('decommissionedStatusObject');
+        self.set('decommissionedStatusObject', null);
+        // HDP-2 stack
+        if (version.charAt(0) == 2) {
+          if (curObj) {
+            var liveNodesJson = App.parseJSON(curObj.LiveNodes);
+            if (liveNodesJson && liveNodesJson[hostName] ) {
+              switch(liveNodesJson[hostName].adminState) {
+                case "In Service":
+                  self.set('isDataNodeRecommissionAvailable', false);
+                  self.set('isDataNodeDecommissioning', false);
+                  self.set('isDataNodeDecommissionAvailable', self.get('isStart'));
+                  break;
+                case "Decommission In Progress":
+                  self.set('isDataNodeRecommissionAvailable', true);
+                  self.set('isDataNodeDecommissioning', true);
+                  self.set('isDataNodeDecommissionAvailable', false);
+                  break;
+                case "Decommissioned":
+                  self.set('isDataNodeRecommissionAvailable', true);
+                  self.set('isDataNodeDecommissioning', false);
+                  self.set('isDataNodeDecommissionAvailable', false);
+                  break;
+              }
+            } else {
+              // if namenode is down, get desired_admin_state to decide if the used had issued a decommission
+              var deferred = $.Deferred();
+              self.getDesiredAdminState(clusterName, hostName, slaveType).done( function () {
+                var desired_admin_state = self.get('desiredAdminState');
+                self.set('desiredAdminState', null);
+                switch(desired_admin_state) {
+                  case "INSERVICE":
+                    self.set('isDataNodeRecommissionAvailable', false);
+                    self.set('isDataNodeDecommissioning', false);
+                    self.set('isDataNodeDecommissionAvailable', self.get('isStart'));
+                    break;
+                  case "DECOMMISSIONED":
+                    self.set('isDataNodeRecommissionAvailable', true);
+                    self.set('isDataNodeDecommissioning', false);
+                    self.set('isDataNodeDecommissionAvailable', false);
+                    break;
+                }
+                deferred.resolve(desired_admin_state);
+              });
+            }
+          }
+        }
+        // HDP-1 stack
+        if (version.charAt(0) == 1) {
+          if (curObj) {
+            var liveNodesJson = App.parseJSON(curObj.LiveNodes);
+            var decomNodesJson = App.parseJSON(curObj.DecomNodes);
+            var deadNodesJson = App.parseJSON(curObj.DeadNodes);
+            if (decomNodesJson && decomNodesJson[hostName] ) {
+              self.set('isDataNodeRecommissionAvailable', true);
+              self.set('isDataNodeDecommissioning', true);
+              self.set('isDataNodeDecommissionAvailable', false);
+            } else if (deadNodesJson && deadNodesJson[hostName] ) {
+              self.set('isDataNodeRecommissionAvailable', true);
+              self.set('isDataNodeDecommissioning', false);
+              self.set('isDataNodeDecommissionAvailable', false);
+            } else if (liveNodesJson && liveNodesJson[hostName] ) {
+              self.set('isDataNodeRecommissionAvailable', false);
+              self.set('isDataNodeDecommissioning', false);
+              self.set('isDataNodeDecommissionAvailable', self.get('isStart'));
+            } else {
+              // if namenode is down, get desired_admin_state to decide if the used had issued a decommission
+              var deferred = $.Deferred();
+              self.getDesiredAdminState(clusterName, hostName, slaveType).done( function () {
+                var desired_admin_state = self.get('desiredAdminState');
+                self.set('desiredAdminState', null);
+                switch(desired_admin_state) {
+                  case "INSERVICE":
+                    self.set('isDataNodeRecommissionAvailable', false);
+                    self.set('isDataNodeDecommissioning', false);
+                    self.set('isDataNodeDecommissionAvailable', self.get('isStart'));
+                    break;
+                  case "DECOMMISSIONED":
+                    self.set('isDataNodeRecommissionAvailable', true);
+                    self.set('isDataNodeDecommissioning', false);
+                    self.set('isDataNodeDecommissionAvailable', false);
+                    break;
+                }
+                deferred.resolve(desired_admin_state);
+              });
+            }
+          }
+        }
+        dfd.resolve(curObj);
+      });
+      return dfd.promise();
+    }.observes('App.router.mainHostDetailsController.content'),
+
+    /**
+     * get datanodes decommission status: from NAMENODE component, liveNodes property
+     */
+    getDNDecommissionStatus: function(clusterName, hostName, componentName){
+      return App.ajax.send({
+        name: 'host.host_component.datanodes_decommission_status',
+        sender: this,
+        data: {
+          clusterName: clusterName,
+          hostName: hostName,
+          componentName: componentName
+        },
+        success: 'getDNDecommissionStatusSuccessCallback',
+        error: 'getDNDecommissionStatusErrorCallback'
+      });
+    },
+    decommissionedStatusObject: null,
+    getDNDecommissionStatusSuccessCallback: function (response, request, data) {
+      var statusObject = response.ServiceComponentInfo;
+      if ( statusObject != null) {
+        this.set('decommissionedStatusObject', statusObject);
+        return statusObject;
+      }
+    },
+    getDNDecommissionStatusErrorCallback: function (request, ajaxOptions, error) {
+      console.log('ERROR: '+ error);
+      this.set('decommissionedStatusObject', null);
+      return null;
+    },
+
+    /**
+     * get desired_admin_state status of DataNode, TaskTracker, NodeManager and RegionServer
+     */
+    getDesiredAdminState: function(clusterName, hostName, componentName){
+      return App.ajax.send({
+        name: 'host.host_component.slave_desired_admin_state',
+        sender: this,
+        data: {
+          clusterName: clusterName,
+          hostName: hostName,
+          componentName: componentName
+        },
+        success: 'getDesiredAdminStateSuccessCallback',
+        error: 'getDesiredAdminStateErrorCallback'
+      });
+    },
+    desiredAdminState: null,
+    getDesiredAdminStateSuccessCallback: function (response, request, data) {
+      var status = response.HostRoles.desired_admin_state;
+      if ( status != null) {
+        this.set('desiredAdminState', status);
+        return status;
+      }
+    },
+    getDesiredAdminStateErrorCallback: function (request, ajaxOptions, error) {
+      console.log('ERROR: '+ error);
+      this.set('desiredAdminState', null);
+      return null;
+    },
+
+    isNodeManagerDecommissionAvailable: null,
+    isNodeManagerRecommissionAvailable: null,
+
     /**
-     * Set in template via binding from parent view
+     * load Recommission/Decommission status for nodeManager from nodeManagers list
      */
-    decommissionDataNodeHostNames: null,
+    loadNodeManagerDecommissionStatus: function () {
+      var clusterName = App.router.get('clusterController.clusterName');
+      var hostName = App.router.get('mainHostDetailsController.content.hostName');
+      var componentName = 'RESOURCEMANAGER';
+      var slaveType = 'NODEMANAGER';
+      var dfd = $.Deferred();
+      var self = this;
+      this.getNMDecommissionStatus(clusterName, hostName, componentName).done(function () {
+        var curObj = self.get('decommissionedStatusObject');
+        self.set('decommissionedStatusObject', null);
+        if (curObj && curObj.rm_metrics) {
+          var nodeManagersArray = App.parseJSON(curObj.rm_metrics.cluster.nodeManagers);
+            if (nodeManagersArray.findProperty('HostName', hostName)){
+              self.set('isNodeManagerRecommissionAvailable', false);
+              self.set('isNodeManagerDecommissionAvailable', self.get('isStart'));
+            } else {
+              self.set('isNodeManagerRecommissionAvailable', true);
+              self.set('isNodeManagerDecommissionAvailable', false);
+            }
+        } else if (!curObj.rm_metrics) {
+          // if ResourceManager is down, get desired_admin_state of NM to decide if the used had issued a decommission
+          var deferred = $.Deferred();
+          self.getDesiredAdminState(clusterName, hostName, slaveType).done( function () {
+            var desired_admin_state = self.get('desiredAdminState');
+            self.set('desiredAdminState', null);
+            switch(desired_admin_state) {
+              case "INSERVICE":
+                self.set('isNodeManagerRecommissionAvailable', false);
+                self.set('isNodeManagerDecommissionAvailable', self.get('isStart'));
+                break;
+              case "DECOMMISSIONED":
+                self.set('isNodeManagerRecommissionAvailable', true);
+                self.set('isNodeManagerDecommissionAvailable', false);
+                break;
+            }
+            deferred.resolve(desired_admin_state);
+          });
+        }
+        dfd.resolve(curObj);
+      });
+      return dfd.promise();
+    }.observes('App.router.mainHostDetailsController.content'),
+
     /**
-     * Decommission is available whenever the service is started.
+     * get NodeManager decommission status: from RESOURCEMANAGER component, rm_metrics/nodeManagers property
      */
-    isDataNodeDecommissionAvailable: function () {
-      return this.get('isStart') && !this.get('isDataNodeRecommissionAvailable');
-    }.property('isStart', 'isDataNodeRecommissionAvailable'),
+    getNMDecommissionStatus: function(clusterName, hostName, componentName){
+      return App.ajax.send({
+        name: 'host.host_component.nodemanager_decommission_status',
+        sender: this,
+        data: {
+          clusterName: clusterName,
+          hostName: hostName,
+          componentName: componentName
+        },
+        success: 'getDNDecommissionStatusSuccessCallback',
+        error: 'getDNDecommissionStatusErrorCallback'
+      });
+    },
+
+    isTaskTrackerDecommissionAvailable: null,
+    isTaskTrackerRecommissionAvailable: null,
 
     /**
-     * Recommission is available only when this hostname shows up in the
-     * 'decommissionDataNodeHostNames'
+     * load Recommission/Decommission status for TaskTracker from JobTracker/AliveNodes list
      */
-    isDataNodeRecommissionAvailable: function () {
-      var decommissionHostNames = this.get('decommissionDataNodeHostNames');
+    loadTaskTrackerDecommissionStatus: function () {
+      var clusterName = App.router.get('clusterController.clusterName');
       var hostName = App.router.get('mainHostDetailsController.content.hostName');
-      return decommissionHostNames != null && decommissionHostNames.contains(hostName);
-    }.property('App.router.mainHostDetailsController.content', 'decommissionDataNodeHostNames'),
+      var componentName = 'JOBTRACKER';
+      var slaveType = 'TASKTRACKER';
+      var dfd = $.Deferred();
+      var self = this;
+      this.getTTDecommissionStatus(clusterName, hostName, componentName).done(function () {
+        var curObj = self.get('decommissionedStatusObject');
+        self.set('decommissionedStatusObject', null);
+        if (curObj) {
+          var aliveNodesArray = App.parseJSON(curObj.AliveNodes);
+          if (aliveNodesArray != null) {
+            if (aliveNodesArray.findProperty('hostname', hostName)){
+              self.set('isTaskTrackerRecommissionAvailable', false);
+              self.set('isTaskTrackerDecommissionAvailable', self.get('isStart'));
+            } else {
+              self.set('isTaskTrackerRecommissionAvailable', true);
+              self.set('isTaskTrackerDecommissionAvailable', false);
+            }
+          }
+        } else {
+          // if JobTracker is down, get desired_admin_state of TT to decide if the used had issued a decommission
+          var deferred = $.Deferred();
+          self.getDesiredAdminState(clusterName, hostName, slaveType).done( function () {
+            var desired_admin_state = self.get('desiredAdminState');
+            self.set('desiredAdminState', null);
+            switch(desired_admin_state) {
+              case "INSERVICE":
+                self.set('isTaskTrackerRecommissionAvailable', false);
+                self.set('isTaskTrackerDecommissionAvailable', self.get('isStart'));
+                break;
+              case "DECOMMISSIONED":
+                self.set('isTaskTrackerRecommissionAvailable', true);
+                self.set('isTaskTrackerDecommissionAvailable', false);
+                break;
+            }
+            deferred.resolve(desired_admin_state);
+          });
+        }
+        dfd.resolve(curObj);
+      });
+      return dfd.promise();
+    }.observes('App.router.mainHostDetailsController.content'),
+
+    /**
+     * get TaskTracker decommission status: from JobTracker component, AliveNodes property
+     */
+    getTTDecommissionStatus: function(clusterName, hostName, componentName){
+      return App.ajax.send({
+        name: 'host.host_component.tasktracker_decommission_status',
+        sender: this,
+        data: {
+          clusterName: clusterName,
+          hostName: hostName,
+          componentName: componentName
+        },
+        success: 'getDNDecommissionStatusSuccessCallback',
+        error: 'getDNDecommissionStatusErrorCallback'
+      });
+    },
+
 
     /**
      * Shows whether we need to show Delete button