Repository: ambari
Updated Branches:
  refs/heads/branch-3.0-perf 05cd35982 -> eec5936bd


AMBARI-22441 Integrate Alert Groups on Alert page with websocket events. 
(atkach)


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

Branch: refs/heads/branch-3.0-perf
Commit: eec5936bd4819ca83f65c2456c71f83ca59b4f2d
Parents: 05cd359
Author: Andrii Tkach <atk...@apache.org>
Authored: Wed Nov 15 11:32:58 2017 +0200
Committer: Andrii Tkach <atk...@apache.org>
Committed: Wed Nov 15 11:32:58 2017 +0200

----------------------------------------------------------------------
 ambari-web/app/assets/test/tests.js             |  1 +
 .../app/controllers/global/update_controller.js |  3 +-
 .../alert_definitions_actions_controller.js     |  7 +-
 .../manage_alert_notifications_controller.js    | 13 ++--
 ambari-web/app/mappers.js                       |  1 +
 ambari-web/app/mappers/alert_groups_mapper.js   | 10 +--
 .../socket/alert_groups_mapper_adapter.js       | 41 ++++++++++++
 .../main/alerts/definition_details_view.js      | 25 +++----
 .../global/update_controller_test.js            |  4 +-
 .../socket/alert_groups_mapper_adapter_test.js  | 70 ++++++++++++++++++++
 .../main/alerts/definition_details_view_test.js | 48 +++++---------
 11 files changed, 156 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/eec5936b/ambari-web/app/assets/test/tests.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/test/tests.js 
b/ambari-web/app/assets/test/tests.js
index eac9967..23b985a 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -173,6 +173,7 @@ var files = [
   'test/mappers/socket/service_state_mapper_test',
   'test/mappers/socket/host_state_mapper_test',
   'test/mappers/socket/alert_definitions_mapper_adapter_test',
+  'test/mappers/socket/alert_groups_mapper_adapter_test',
   'test/mixins/common/configs/enhanced_configs_test',
   'test/mixins/common/configs/config_recommendations_test',
   'test/mixins/common/configs/config_recommendation_parser_test',

http://git-wip-us.apache.org/repos/asf/ambari/blob/eec5936b/ambari-web/app/controllers/global/update_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/update_controller.js 
b/ambari-web/app/controllers/global/update_controller.js
index 63a4da4..9a5ae20 100644
--- a/ambari-web/app/controllers/global/update_controller.js
+++ b/ambari-web/app/controllers/global/update_controller.js
@@ -194,6 +194,7 @@ App.UpdateController = Em.Controller.extend({
       App.StompClient.subscribe('/events/services', 
App.serviceStateMapper.map.bind(App.serviceStateMapper));
       App.StompClient.subscribe('/events/hosts', 
App.hostStateMapper.map.bind(App.hostStateMapper));
       App.StompClient.subscribe('/events/alert_definitions', 
App.alertDefinitionsMapperAdapter.map.bind(App.alertDefinitionsMapperAdapter));
+      App.StompClient.subscribe('/events/alert_group', 
App.alertGroupsMapperAdapter.map.bind(App.alertGroupsMapperAdapter));
 
       App.updater.run(this, 'updateHostsMetrics', 'isWorking', 
App.contentUpdateInterval, '\/main\/(hosts).*');
       App.updater.run(this, 'updateServiceMetric', 'isWorking', 
App.componentsUpdateInterval, '\/main\/(dashboard|services).*');
@@ -201,7 +202,6 @@ App.UpdateController = Em.Controller.extend({
       App.updater.run(this, 'graphsUpdate', 'isWorking');
       App.updater.run(this, 'updateComponentConfig', 'isWorking');
 
-      App.updater.run(this, 'updateAlertGroups', 'isWorking', 
App.alertGroupsUpdateInterval, '\/main\/alerts.*');
       if (!App.get('router.mainAlertInstancesController.isUpdating')) {
         App.updater.run(this, 'updateUnhealthyAlertInstances', 
'updateAlertInstances', App.alertInstancesUpdateInterval, '\/main\/alerts.*');
       }
@@ -215,6 +215,7 @@ App.UpdateController = Em.Controller.extend({
       App.StompClient.unsubscribe('/events/services');
       App.StompClient.unsubscribe('/events/hosts');
       App.StompClient.unsubscribe('/events/alert_definitions');
+      App.StompClient.unsubscribe('/events/alert_group');
     }
   }.observes('isWorking', 
'App.router.mainAlertInstancesController.isUpdating'),
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/eec5936b/ambari-web/app/controllers/main/alerts/alert_definitions_actions_controller.js
----------------------------------------------------------------------
diff --git 
a/ambari-web/app/controllers/main/alerts/alert_definitions_actions_controller.js
 
b/ambari-web/app/controllers/main/alerts/alert_definitions_actions_controller.js
index 71d9acf..bca0d22 100644
--- 
a/ambari-web/app/controllers/main/alerts/alert_definitions_actions_controller.js
+++ 
b/ambari-web/app/controllers/main/alerts/alert_definitions_actions_controller.js
@@ -165,12 +165,7 @@ App.MainAlertDefinitionActionsController = 
Em.ArrayController.extend({
                   })
                 });
               }
-              App.router.get('updateController').updateAlertGroups(function () 
{
-                
App.router.get('manageAlertGroupsController').toggleProperty('changeTrigger');
-                
App.router.get('updateController').updateAlertDefinitions(function() {
-                  
App.router.get('updateController').updateAlertNotifications(Em.K);
-                });
-              });
+              
App.router.get('updateController').updateAlertNotifications(Em.K);
             }
           } else {
             runNextQuery();

http://git-wip-us.apache.org/repos/asf/ambari/blob/eec5936b/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js
----------------------------------------------------------------------
diff --git 
a/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js
 
b/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js
index a417a73..ddb8874 100644
--- 
a/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js
+++ 
b/ambari-web/app/controllers/main/alerts/manage_alert_notifications_controller.js
@@ -358,15 +358,12 @@ App.ManageAlertNotificationsController = 
Em.Controller.extend({
    * @method loadAlertNotifications
    */
   loadAlertNotifications: function () {
-    var self = this;
     this.set('isLoaded', false);
-    App.router.get('updateController').updateAlertGroups(function () {
-      App.ajax.send({
-        name: 'alerts.notifications',
-        sender: self,
-        success: 'getAlertNotificationsSuccessCallback',
-        error: 'getAlertNotificationsErrorCallback'
-      });
+    return App.ajax.send({
+      name: 'alerts.notifications',
+      sender: this,
+      success: 'getAlertNotificationsSuccessCallback',
+      error: 'getAlertNotificationsErrorCallback'
     });
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/eec5936b/ambari-web/app/mappers.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers.js b/ambari-web/app/mappers.js
index 241ba29..945b1dc 100644
--- a/ambari-web/app/mappers.js
+++ b/ambari-web/app/mappers.js
@@ -51,3 +51,4 @@ require('mappers/socket/host_component_status_mapper');
 require('mappers/socket/alert_summary_mapper');
 require('mappers/socket/host_state_mapper');
 require('mappers/socket/alert_definitions_mapper_adapter');
+require('mappers/socket/alert_groups_mapper_adapter');

http://git-wip-us.apache.org/repos/asf/ambari/blob/eec5936b/ambari-web/app/mappers/alert_groups_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/alert_groups_mapper.js 
b/ambari-web/app/mappers/alert_groups_mapper.js
index 1fd38f5..3e86a1d 100644
--- a/ambari-web/app/mappers/alert_groups_mapper.js
+++ b/ambari-web/app/mappers/alert_groups_mapper.js
@@ -39,7 +39,7 @@ App.alertGroupsMapper = App.QuickDataMapper.create({
     }
   },
 
-  map: function (json) {
+  map: function (json, ignoreDelete) {
     if(Em.isNone(App.cache['previousAlertGroupsFullMap'])) {
       App.cache['previousAlertGroupsFullMap'] = {};
     }
@@ -101,9 +101,11 @@ App.alertGroupsMapper = App.QuickDataMapper.create({
 
       }, this);
 
-      groupsToDelete.forEach(function(groupId) {
-        self.deleteRecord(App.AlertGroup.find(groupId));
-      });
+      if (!ignoreDelete) {
+        groupsToDelete.forEach(function(groupId) {
+          self.deleteRecord(App.AlertGroup.find(groupId));
+        });
+      }
 
       App.cache['previousAlertGroupsMap'] = alertDefinitionsGroupsMap;
       App.cache['previousAlertGroupsFullMap'] = groupsMap;

http://git-wip-us.apache.org/repos/asf/ambari/blob/eec5936b/ambari-web/app/mappers/socket/alert_groups_mapper_adapter.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/socket/alert_groups_mapper_adapter.js 
b/ambari-web/app/mappers/socket/alert_groups_mapper_adapter.js
new file mode 100644
index 0000000..c325da3
--- /dev/null
+++ b/ambari-web/app/mappers/socket/alert_groups_mapper_adapter.js
@@ -0,0 +1,41 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
+ */
+
+var App = require('app');
+
+App.alertGroupsMapperAdapter = App.QuickDataMapper.create({
+
+  /**
+   * @param {object} event
+   */
+  map: function(event) {
+    event.groups.forEach((alertGroup) => {
+      if (event.updateType === 'UPDATE' || event.updateType === 'CREATE') {
+        App.alertGroupsMapper.map({
+          items: [
+            {
+              AlertGroup: alertGroup
+            }
+          ]
+        }, true);
+      } else if (event.updateType === 'DELETE') {
+        this.deleteRecord(App.AlertGroup.find(alertGroup.id));
+      }
+    });
+    
App.router.get('manageAlertGroupsController').toggleProperty('changeTrigger');
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/eec5936b/ambari-web/app/views/main/alerts/definition_details_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/alerts/definition_details_view.js 
b/ambari-web/app/views/main/alerts/definition_details_view.js
index bb9e738..68d7ea4 100644
--- a/ambari-web/app/views/main/alerts/definition_details_view.js
+++ b/ambari-web/app/views/main/alerts/definition_details_view.js
@@ -66,25 +66,18 @@ App.MainAlertDefinitionDetailsView = App.TableView.extend({
       this.set('isLoaded', true);
       this.get('controller').loadAlertInstances();
     } else {
-      this.loadDefinitionDetails();
+      App.router.get('clusterController').addObserver('isAlertsLoaded', this, 
'loadAfterModelLoaded');
     }
   },
 
-  loadDefinitionDetails: function() {
-    var self = this,
-        updater = App.router.get('updateController');
-
-    updater.updateAlertGroups(function () {
-      updater.updateAlertDefinitions(function () {
-        updater.updateAlertDefinitionSummary(function () {
-          self.set('isLoaded', true);
-          // App.AlertDefinition doesn't represents real models
-          // Real model (see AlertDefinition types) should be used
-          self.set('controller.content', 
App.AlertDefinition.find(parseInt(self.get('controller.content.id'))));
-          self.get('controller').loadAlertInstances();
-        });
-      });
-    });
+  loadAfterModelLoaded: function() {
+    var clusterController = App.router.get('clusterController');
+    if (clusterController.get('isAlertsLoaded')) {
+      this.set('isLoaded', true);
+      this.set('controller.content', 
App.AlertDefinition.find(parseInt(this.get('controller.content.id'))));
+      this.get('controller').loadAlertInstances();
+      clusterController.removeObserver('isAlertsLoaded', this, 
'loadAfterModelLoaded');
+    }
   },
 
   nameValidation: function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/eec5936b/ambari-web/test/controllers/global/update_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/global/update_controller_test.js 
b/ambari-web/test/controllers/global/update_controller_test.js
index c42926a..f842654 100644
--- a/ambari-web/test/controllers/global/update_controller_test.js
+++ b/ambari-web/test/controllers/global/update_controller_test.js
@@ -75,11 +75,12 @@ describe('App.UpdateController', function () {
       
expect(App.StompClient.unsubscribe.calledWith('/events/services')).to.be.true;
       
expect(App.StompClient.unsubscribe.calledWith('/events/hosts')).to.be.true;
       
expect(App.StompClient.unsubscribe.calledWith('/events/alert_definitions')).to.be.true;
+      
expect(App.StompClient.unsubscribe.calledWith('/events/alert_group')).to.be.true;
     });
 
     it('isWorking = true', function () {
       controller.set('isWorking', true);
-      expect(App.updater.run.callCount).to.equal(9);
+      expect(App.updater.run.callCount).to.equal(8);
       
expect(App.StompClient.subscribe.calledWith('/events/hostcomponents')).to.be.true;
       
expect(App.StompClient.subscribe.calledWith('/events/alerts')).to.be.true;
       
expect(App.StompClient.subscribe.calledWith('/events/ui_topologies')).to.be.true;
@@ -87,6 +88,7 @@ describe('App.UpdateController', function () {
       
expect(App.StompClient.subscribe.calledWith('/events/services')).to.be.true;
       expect(App.StompClient.subscribe.calledWith('/events/hosts')).to.be.true;
       
expect(App.StompClient.subscribe.calledWith('/events/alert_definitions')).to.be.true;
+      
expect(App.StompClient.subscribe.calledWith('/events/alert_group')).to.be.true;
     });
   });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/eec5936b/ambari-web/test/mappers/socket/alert_groups_mapper_adapter_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mappers/socket/alert_groups_mapper_adapter_test.js 
b/ambari-web/test/mappers/socket/alert_groups_mapper_adapter_test.js
new file mode 100644
index 0000000..ab1684e
--- /dev/null
+++ b/ambari-web/test/mappers/socket/alert_groups_mapper_adapter_test.js
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+require('mappers/socket/alert_groups_mapper_adapter');
+
+describe('App.alertGroupsMapperAdapter', function () {
+
+  describe('#map', function() {
+    beforeEach(function() {
+      sinon.stub(App.alertGroupsMapper, 'map');
+      sinon.stub(App.AlertGroup, 'find').returns({});
+      sinon.stub(App.alertGroupsMapperAdapter, 'deleteRecord');
+      App.set('clusterId', 1);
+    });
+    afterEach(function() {
+      App.alertGroupsMapper.map.restore();
+      App.AlertGroup.find.restore();
+      App.alertGroupsMapperAdapter.deleteRecord.restore();
+    });
+
+    it('should call App.alertGroupsMapper.map on UPDATE event', function() {
+      var event = {
+        updateType: 'UPDATE',
+        groups: [
+          {
+            id: 1
+          }
+        ]
+      };
+      App.alertGroupsMapperAdapter.map(event);
+      expect(App.alertGroupsMapper.map.getCall(0).args[0]).to.be.eql({
+        items: [{
+          AlertGroup: {
+            id: 1
+          }
+        }]
+      });
+    });
+
+    it('should call deleteRecord on DELETE event', function() {
+      var event = {
+        updateType: 'DELETE',
+        groups: [
+          {
+            id: 1
+          }
+        ]
+      };
+      App.alertGroupsMapperAdapter.map(event);
+      
expect(App.alertGroupsMapperAdapter.deleteRecord.calledWith({})).to.be.true;
+    });
+  });
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/eec5936b/ambari-web/test/views/main/alerts/definition_details_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/alerts/definition_details_view_test.js 
b/ambari-web/test/views/main/alerts/definition_details_view_test.js
index 7b96858..9813573 100644
--- a/ambari-web/test/views/main/alerts/definition_details_view_test.js
+++ b/ambari-web/test/views/main/alerts/definition_details_view_test.js
@@ -42,13 +42,15 @@ describe('App.MainAlertDefinitionDetailsView', function () {
     beforeEach(function() {
       sinon.spy(view.get('controller'), 'clearStep');
       sinon.spy(view.get('controller'), 'loadAlertInstances');
-      sinon.stub(view, 'loadDefinitionDetails');
+      sinon.stub(App.router, 'get').returns({
+        addObserver: sinon.spy()
+      });
     });
 
     afterEach(function() {
       view.get('controller').clearStep.restore();
       view.get('controller').loadAlertInstances.restore();
-      view.loadDefinitionDetails.restore();
+      App.router.get.restore();
     });
 
     it("clearStep() should be called", function() {
@@ -67,52 +69,36 @@ describe('App.MainAlertDefinitionDetailsView', function () {
       view.set('controller.content.isLoaded', false);
       view.willInsertElement();
       expect(view.get('isLoaded')).to.be.false;
-      expect(view.loadDefinitionDetails.calledOnce).to.be.true;
+      
expect(App.router.get('clusterController').addObserver.calledWith('isAlertsLoaded',
 view, 'loadAfterModelLoaded')).to.be.true;
     });
   });
 
-  describe("#loadDefinitionDetails()", function() {
-    var mock = {
-      updateAlertGroups: function(callback) { callback(); },
-      updateAlertDefinitions: function(callback) { callback(); },
-      updateAlertDefinitionSummary: function(callback) { callback(); }
-    };
-
+  describe('#loadAfterModelLoaded', function() {
     beforeEach(function() {
-      sinon.stub(App.router, 'get').returns(mock);
-      sinon.spy(mock, 'updateAlertGroups');
-      sinon.spy(mock, 'updateAlertDefinitions');
-      sinon.spy(mock, 'updateAlertDefinitionSummary');
+      sinon.stub(App.router, 'get').returns(Em.Object.create({
+        removeObserver: sinon.spy(),
+        isAlertsLoaded: true
+      }));
       sinon.stub(view.get('controller'), 'loadAlertInstances');
       sinon.stub(App.AlertDefinition, 'find').returns({});
-
-      view.loadDefinitionDetails();
+      view.set('isLoaded', false);
+      view.loadAfterModelLoaded();
     });
-
     afterEach(function() {
       App.router.get.restore();
-      mock.updateAlertGroups.restore();
-      mock.updateAlertDefinitions.restore();
-      mock.updateAlertDefinitionSummary.restore();
       view.get('controller').loadAlertInstances.restore();
       App.AlertDefinition.find.restore();
     });
 
-    it("updateAlertGroups() should be called", function() {
-      expect(mock.updateAlertGroups.calledOnce).to.be.true;
-    });
-
-    it("updateAlertDefinitions() should be called", function() {
-      expect(mock.updateAlertDefinitions.calledOnce).to.be.true;
+    it('isLoaded should be true', function() {
+      expect(view.get('isLoaded')).to.be.true;
     });
 
-    it("updateAlertDefinitionSummary() should be called", function() {
-      expect(mock.updateAlertDefinitionSummary.calledOnce).to.be.true;
+    it('content should be set', function() {
+      expect(view.get('controller.content')).to.be.object;
     });
 
-    it("loadAlertInstances() should be called", function() {
-      expect(view.get('isLoaded')).to.be.true;
-      expect(view.get('controller.content')).to.eql({});
+    it('loadAlertInstances should be called', function() {
       expect(view.get('controller').loadAlertInstances.calledOnce).to.be.true;
     });
   });

Reply via email to