/** * 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.MainAlertInstancesController = Em.Controller.extend({ name: 'mainAlertInstancesController', content: App.AlertInstance.find(), /** * @type {App.AlertInstance[]} */ unhealthyAlertInstances: [], updateUnhealthyAlertInstances: function () { Em.run.once(this, this.updateUnhealthyAlertInstancesOnce); }.observes('content.[]'), updateUnhealthyAlertInstancesOnce: function() { var alertInstances = App.AlertInstance.find().filter(function (item) { return ['CRITICAL', 'WARNING'].contains(item.get('state')); }); this.set('unhealthyAlertInstances', alertInstances); }, /** * Are alertInstances loaded * @type {boolean} */ isLoaded: false, /** * A flag to reload alert instances table every 10 seconds * @type {boolean} */ reload: false, /** * Causes automatic updates of content if set to true * @type {boolean} */ isUpdating: false, /** * Times for alert instances updater * Used in scheduleUpdate * @type {number|null} */ updateTimer: null, /** * @type {string|null} sourceName - hostName or alertDefinitionId */ sourceName: null, /** * @type {string|null} sourceType - 'HOST'|'ALERT_DEFINITION' */ sourceType: null, /** * Load alert instances from server (all, for selected host, for selected alert definition) * @returns {$.ajax} * @method fetchAlertInstances */ fetchAlertInstances: function () { var sourceType = this.get('sourceType'), sourceName = this.get('sourceName'), ajaxData = { sender: this, success: 'getAlertInstancesSuccessCallback', error: 'getAlertInstancesErrorCallback' }; switch (sourceType) { case 'HOST': $.extend(ajaxData, { name: 'alerts.instances.by_host', data: { hostName: sourceName } }); break; case 'ALERT_DEFINITION': $.extend(ajaxData, { name: 'alerts.instances.by_definition', data: { definitionId: sourceName } }); break; default: $.extend(ajaxData, { name: 'alerts.instances' }); break; } return App.ajax.send(ajaxData); }, /** * Pseudo for fetchAlertInstances * Used to get all alert instances * @method loadAlertInstances */ loadAlertInstances: function () { this.setProperties({ isLoaded: false, sourceType: null, sourceName: null }); this.fetchAlertInstances(); }, /** * Pseudo for fetchAlertInstances * Used to get alert instances for some host * @param {string} hostName * @method loadAlertInstancesByHost */ loadAlertInstancesByHost: function (hostName) { this.setProperties({ isLoaded: false, sourceType: 'HOST', sourceName: hostName }); this.fetchAlertInstances(); }, /** * Pseudo for fetchAlertInstances * Used to get alert instances for some alert definition * @param {string} definitionId * @method loadAlertInstancesByAlertDefinition */ loadAlertInstancesByAlertDefinition: function (definitionId) { this.setProperties({ isLoaded: false, sourceType: 'ALERT_DEFINITION', sourceName: definitionId }); this.fetchAlertInstances(); }, scheduleUpdate: function () { var self = this; if (this.get('isUpdating')) { this.set('updateTimer', setTimeout(function () { self.fetchAlertInstances().complete(function() { self.scheduleUpdate(); }); }, App.get('alertInstancesUpdateInterval'))); } else { clearTimeout(this.get('updateTimer')); } }.observes('isUpdating'), /** * Success-callback for alert instances request * @param {object} json * @method getAlertInstancesSuccessCallback */ getAlertInstancesSuccessCallback: function (json) { App.alertInstanceMapper.mapLocal(json); this.set('isLoaded', true); this.toggleProperty('reload'); }, /** * Error-callback for alert instances request * @method getAlertInstancesErrorCallback */ getAlertInstancesErrorCallback: function () { this.set('isLoaded', true); }, /** * Onclick handler for alerts number located right to bg ops number (see application.hbs) * @method showPopup * @return {App.ModalPopup} */ showPopup: function () { var self = this; return App.ModalPopup.show({ alertsNumberBinding: 'App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount', header: function () { return Em.I18n.t('alerts.fastAccess.popup.header').format(this.get('alertsNumber')); }.property('alertsNumber'), classNames: ['sixty-percent-width-modal', 'alerts-popup'], secondary: Em.I18n.t('alerts.fastAccess.popup.body.showmore'), autoHeight: false, isHideBodyScroll: true, onSecondary: function () { this._super(); App.router.transitionTo('main.alerts.index'); }, bodyClass: App.TableView.extend(App.TableServerViewMixin, { updaterBinding: 'App.router.updateController', templateName: require('templates/common/modal_popups/alerts_popup'), controller: self, isPaginate: true, willInsertElement: function () { this._super(); this.updateAlertInstances(); }, /** * Number of all critical and warning alert instances * @type {Boolean} */ filteredCount: function () { return App.router.get('mainAlertDefinitionsController.unhealthyAlertInstancesCount'); }.property('alertsNumber'), content: function () { return this.get('controller.unhealthyAlertInstances'); }.property('controller.unhealthyAlertInstances.@each.state'), isLoaded: Em.computed.bool('controller.unhealthyAlertInstances'), isAlertEmptyList: Em.computed.empty('content'), /** * Update list of shown alert instances * @method updateAlertInstances */ updateAlertInstances: function () { var self = this, displayLength = this.get('displayLength'), startIndex = this.get('startIndex'); if (!displayLength) return; // wait while table-info is loaded this.get('updater').set('queryParamsForUnhealthyAlertInstances', { from: startIndex - 1, page_size: displayLength }); this.set('filteringComplete', false); this.get('updater').updateUnhealthyAlertInstances(function() { self.set('filteringComplete', true); }); }.observes('displayLength', 'startIndex'), /** * Show spinner when filter/sorting request is in processing * @method overlayObserver */ overlayObserver: function() { var $tbody = this.$('#alert-info'), $overlay = this.$('.table-overlay'), $spinner = $($overlay).find('.spinner'); if (!this.get('filteringComplete')) { if (!$tbody) return; var tbodyPos = $tbody.position(); if (!tbodyPos) return; $spinner.css('display', 'block'); $overlay.css({ top: tbodyPos.top + 1, left: tbodyPos.left + 1, width: $tbody.width() - 1, height: $tbody.height() - 1 }); } }, /** * No filtering for alert definitions * @method filter */ filter: function() { this.set('filteredContent', this.get('content')); }.observes('content.length'), /** * Router transition to alert definition details page * @param event */ gotoAlertDetails: function (event) { if (event && event.context) { this.get('parentView').hide(); var definition = App.AlertDefinition.find().findProperty('id', event.context.get('definitionId')); App.router.transitionTo('main.alerts.alertDetails', definition); } }, /** * Router transition to service summary page * @param event */ goToService: function (event) { if (event && event.context) { this.get('parentView').hide(); App.router.transitionTo('main.services.service.summary', event.context); } }, /** * Router transition to host level alerts page * @param event */ goToHostAlerts: function (event) { if (event && event.context) { this.get('parentView').hide(); App.router.transitionTo('main.hosts.hostDetails.alerts', event.context); } }, didInsertElement: function () { this.filter(); this.addObserver('filteringComplete', this, this.overlayObserver); this.overlayObserver(); return this._super(); } }) }); } });