You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ak...@apache.org on 2018/05/31 18:54:44 UTC

[ambari] branch trunk updated: AMBARI-24001. Recommission action doesn't appear for decommissioned component (akovalenko)

This is an automated email from the ASF dual-hosted git repository.

akovalenko pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new b3f356d  AMBARI-24001. Recommission action doesn't appear for decommissioned component (akovalenko)
b3f356d is described below

commit b3f356d013f6bc3cb983dae0266464b1b91db382
Author: Aleksandr Kovalenko <ak...@apache.org>
AuthorDate: Thu May 31 19:34:28 2018 +0300

    AMBARI-24001. Recommission action doesn't appear for decommissioned component (akovalenko)
---
 ambari-web/app/controllers/main/host/details.js    | 12 +++++-
 .../details/host_components/decommissionable.js    | 45 +++++++++++++++++++++-
 ambari-web/app/utils/stomp_client.js               |  8 ++--
 ambari-web/test/utils/stomp_client_test.js         |  6 +--
 4 files changed, 58 insertions(+), 13 deletions(-)

diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js
index b517e61..08009c1 100644
--- a/ambari-web/app/controllers/main/host/details.js
+++ b/ambari-web/app/controllers/main/host/details.js
@@ -1829,12 +1829,16 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
   /**
    * Send command to server to run decommission on DATANODE, TASKTRACKER, NODEMANAGER, REGIONSERVER
    * @param {App.HostComponent} component
+   * @param {callback} callback
    * @method decommission
    */
-  decommission: function (component) {
+  decommission: function (component, callback) {
     var self = this;
     return App.showConfirmationPopup(function () {
       self.runDecommission.call(self, self.get('content.hostName'), component.get('service.serviceName'));
+      if (callback) {
+        callback()
+      }
     }, Em.I18n.t('question.sure.decommission').format(component.get('service.serviceName')));
   },
   /**
@@ -1859,12 +1863,16 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
   /**
    * Send command to server to run recommission on DATANODE, TASKTRACKER, NODEMANAGER
    * @param {App.HostComponent} component
+   * @param {callback} callback
    * @method recommission
    */
-  recommission: function (component) {
+  recommission: function (component, callback) {
     var self = this;
     return App.showConfirmationPopup(function () {
       self.runRecommission.call(self, self.get('content.hostName'), component.get('service.serviceName'));
+      if (callback) {
+        callback()
+      }
     }, Em.I18n.t('question.sure.recommission').format(component.get('service.serviceName')));
   },
   /**
diff --git a/ambari-web/app/mixins/main/host/details/host_components/decommissionable.js b/ambari-web/app/mixins/main/host/details/host_components/decommissionable.js
index 645db5c..ef1453b 100644
--- a/ambari-web/app/mixins/main/host/details/host_components/decommissionable.js
+++ b/ambari-web/app/mixins/main/host/details/host_components/decommissionable.js
@@ -51,6 +51,18 @@ App.Decommissionable = Em.Mixin.create({
   isComponentRecommissionAvailable: false,
 
   /**
+   * Timer id for decommission status polling
+   * @type {number}
+   */
+  decommissionStatusPollingTimer: null,
+
+  /**
+   * Interval for decommission status polling
+   * @type {number}
+   */
+  POLLING_INTERVAL: 6000,
+
+  /**
    * Component with stopped masters can't be docommissioned
    * @type {bool}
    */
@@ -301,6 +313,15 @@ App.Decommissionable = Em.Mixin.create({
     });
   },
 
+  willDestroyElement: function () {
+    this._super();
+    var timer = this.get('decommissionStatusPollingTimer');
+    if (timer) {
+      clearInterval(timer);
+      this.set('decommissionStatusPollingTimer', null);
+    }
+  },
+
   /**
    * Update Decommission status only one time when component was changed
    */
@@ -311,6 +332,26 @@ App.Decommissionable = Em.Mixin.create({
     });
   }.observes('content.workStatus', 'content.passiveState'),
 
+  /**
+   * Update Decommission status periodically
+   */
+  decommissionStatusPolling: function () {
+    var self = this;
+    this.set('decommissionStatusPollingTimer', setTimeout(function () {
+      self.loadComponentDecommissionStatus().done(function() {
+        self.decommissionStatusPolling();
+      });
+    }, this.POLLING_INTERVAL));
+  },
+
+  /**
+   * Start Decommission status polling if it is not started yet
+   */
+  startDecommissionStatusPolling: function () {
+    if (!this.get('decommissionStatusPollingTimer')) {
+      this.decommissionStatusPolling();
+    }
+  },
 
   decommissionView: Em.View.extend({
     classNameBindings: ['parentView.noActionAvailable'],
@@ -327,9 +368,9 @@ App.Decommissionable = Em.Mixin.create({
     click: function () {
       if (!this.get('parentView.isComponentDecommissionDisable')) {
         if (this.get('parentView.isComponentDecommissionAvailable')) {
-          this.get('controller').decommission(this.get('parentView.content'));
+          this.get('controller').decommission(this.get('parentView.content'), this.get('parentView.startDecommissionStatusPolling').bind(this.get('parentView')));
         } else {
-          this.get('controller').recommission(this.get('parentView.content'));
+          this.get('controller').recommission(this.get('parentView.content'), this.get('parentView.startDecommissionStatusPolling').bind(this.get('parentView')));
         }
       }
     }
diff --git a/ambari-web/app/utils/stomp_client.js b/ambari-web/app/utils/stomp_client.js
index 3b8c78b..062b816 100644
--- a/ambari-web/app/utils/stomp_client.js
+++ b/ambari-web/app/utils/stomp_client.js
@@ -155,14 +155,14 @@ module.exports = Em.Object.extend({
   },
 
   reconnect: function(useSockJS) {
-    const subscriptions = this.get('subscriptions');
+    const subscriptions = Object.assign({}, this.get('subscriptions'));
     setTimeout(() => {
       console.debug('Reconnecting to WebSocket...');
       this.connect(useSockJS).done(() => {
-        for (var i in subscriptions) {
-          subscriptions[i].unsubscribe();
+        this.set('subscriptions', {});
+        for (let i in subscriptions) {
           this.subscribe(subscriptions[i].destination, subscriptions[i].handlers['default']);
-          for (var key in subscriptions[i].handlers) {
+          for (let key in subscriptions[i].handlers) {
             key !== 'default' && this.addHandler(subscriptions[i].destination, key, subscriptions[i].handlers[key]);
           }
         }
diff --git a/ambari-web/test/utils/stomp_client_test.js b/ambari-web/test/utils/stomp_client_test.js
index f816fc2..279677a 100644
--- a/ambari-web/test/utils/stomp_client_test.js
+++ b/ambari-web/test/utils/stomp_client_test.js
@@ -121,13 +121,11 @@ describe('App.StompClient', function () {
   describe('#reconnect', function() {
     beforeEach(function() {
       sinon.stub(stomp, 'connect').returns({done: Em.clb});
-      sinon.stub(stomp, 'unsubscribe');
       sinon.stub(stomp, 'subscribe');
       this.clock = sinon.useFakeTimers();
     });
     afterEach(function() {
       stomp.connect.restore();
-      stomp.unsubscribe.restore();
       stomp.subscribe.restore();
       this.clock.restore();
     });
@@ -136,14 +134,12 @@ describe('App.StompClient', function () {
       var subscriptions = {
         'foo': {
           destination: 'foo',
-          handlers: { default: Em.K },
-          unsubscribe: sinon.spy()
+          handlers: { default: Em.K }
         }
       };
       stomp.set('subscriptions', subscriptions);
       stomp.reconnect();
       this.clock.tick(stomp.RECONNECT_TIMEOUT);
-      expect(subscriptions['foo'].unsubscribe.calledOnce).to.be.true;
       expect(stomp.subscribe.calledWith('foo', Em.K)).to.be.true;
     });
   });

-- 
To stop receiving notification emails like this one, please contact
akovalenko@apache.org.