blob: d8a6a3f98427ea42337067aaa7d95101c7a9d135 [file] [log] [blame]
/**
* 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');
var dateUtils = require('utils/date/date');
function computedOnSummaryState(state) {
return Em.computed('summary.' + state, 'summary.' + state + '.count', 'summary.' + state + '.maintenanceCount', function () {
var summary = Em.get(this, 'summary');
return !!summary[state] && !!(summary[state].count || summary[state].maintenanceCount);
});
}
App.AlertDefinition = DS.Model.extend({
name: DS.attr('string'),
label: DS.attr('string'),
description: DS.attr('string'),
service: DS.belongsTo('App.Service'),
serviceName: DS.attr('string'),
componentName: DS.attr('string'),
enabled: DS.attr('boolean'),
repeat_tolerance_enabled: DS.attr('boolean'),
repeat_tolerance: DS.attr('number'),
scope: DS.attr('string'),
interval: DS.attr('number'),
type: DS.attr('string'),
helpUrl: DS.attr('string'),
groups: DS.hasMany('App.AlertGroup'),
reporting: DS.hasMany('App.AlertReportDefinition'),
parameters: DS.hasMany('App.AlertDefinitionParameter'),
lastTriggered: 0,
lastTriggeredRaw: 0,
//relates only to SCRIPT-type alert definition
location: DS.attr('string'),
//relates only to AGGREGATE-type alert definition
alertName: DS.attr('string'),
//relates only to WEB and METRIC types of alert definition
uri: DS.belongsTo('App.AlertMetricsUriDefinition'),
//relates only METRIC-type alert definition
jmx: DS.belongsTo('App.AlertMetricsSourceDefinition'),
ganglia: DS.belongsTo('App.AlertMetricsSourceDefinition'),
ams: DS.belongsTo('App.AlertMetricsAmsDefinition'),
//relates only PORT-type alert definition
defaultPort: DS.attr('number'),
portUri: DS.attr('string'),
/**
* Raw data from AlertDefinition/source
* used to format request content for updating alert definition
* @type {Object}
*/
rawSourceData: {},
/**
* Counts of alert grouped by their status
* Format:
* <code>
* {
* "CRITICAL": {
* count: 1,
* maintenanceCount: 0
* },
* "OK": {
* count: 0,
* maintenanceCount: 1
* },
* "UNKNOWN": {
* count: 0,
* maintenanceCount: 0
* },
* "WARNING": {
* count: 1,
* maintenanceCount: 1
* }
* }
* </code>
* @type {object}
*/
summary: {},
/**
* Formatted timestamp for latest alert triggering for current alertDefinition
* @type {string}
*/
lastTriggeredFormatted: function () {
return dateUtils.dateFormat(this.get('lastTriggered'));
}.property('lastTriggered'),
/**
* Formatted timestamp with <code>$.timeago</code>
* @type {string}
*/
lastTriggeredAgoFormatted: function () {
var lastTriggered = this.get('lastTriggeredRaw');
return lastTriggered ? $.timeago(new Date(lastTriggered)) : '';
}.property('lastTriggeredRaw'),
lastTriggeredVerboseDisplay: function () {
var lastTriggered = this.get('lastTriggered');
return Em.I18n.t('models.alert_definition.triggered.verbose').format(dateUtils.dateFormat(lastTriggered));
}.property('lastTriggered'),
/**
* Formatted timestamp in format: for 4 days
* @type {string}
*/
lastTriggeredForFormatted: function () {
var lastTriggered = this.get('lastTriggeredRaw');
var previousSuffixAgo = $.timeago.settings.strings.suffixAgo;
var previousPrefixAgo = $.timeago.settings.strings.prefixAgo;
$.timeago.settings.strings.suffixAgo = null;
$.timeago.settings.strings.prefixAgo = 'for';
var triggeredFor = lastTriggered ? $.timeago(new Date(lastTriggered)) : '';
$.timeago.settings.strings.suffixAgo = previousSuffixAgo;
$.timeago.settings.strings.prefixAgo = previousPrefixAgo;
return triggeredFor;
}.property('lastTriggeredRaw'),
/**
* Formatted displayName for <code>componentName</code>
* @type {String}
*/
componentNameFormatted: Em.computed.formatRole('componentName', false),
hostCnt: function () {
var order = this.get('order'),
summary = this.get('summary'),
hostCnt = 0;
order.forEach(function (state) {
hostCnt += summary[state] ? summary[state].count + summary[state].maintenanceCount : 0;
});
return hostCnt;
}.property('order', 'summary'),
latestText: function () {
var order = this.get('order'), summary = this.get('summary'), text = '';
order.forEach(function (state) {
var cnt = summary[state] ? summary[state].count + summary[state].maintenanceCount : 0;
if (cnt > 0) {
text = summary[state].latestText;
}
});
return text;
}.property('summary'),
latestTextSummary: function () {
var latestText = this.get('latestText');
var ellipsis = '...';
var summaryLength = 400;
if(latestText.length > summaryLength) {
latestText = latestText.substring(0, summaryLength - ellipsis.length) + ellipsis;
}
return latestText;
}.property('latestText'),
isAmbariService: Em.computed.equal('service._id', 'AMBARI'),
isAmbariAgentComponent: Em.computed.equal('componentName', 'AMBARI_AGENT'),
isHostAlertDefinition: Em.computed.and('isAmbariService', 'isAmbariAgentComponent'),
typeIconClass: Em.computed.getByKey('typeIcons', 'type'),
isTypeAggregate: Em.computed.equal('type', 'AGGREGATE'),
/**
* if this definition is in state: CRITICAL / WARNING, if true, will show up in alerts fast access popup
* instances with maintenance mode ON are ignored
* @type {boolean}
*/
isCriticalOrWarning: Em.computed.or('summary.CRITICAL.count', 'summary.WARNING.count'),
/**
* if this definition is in state: CRITICAL
* @type {boolean}
*/
isCritical: computedOnSummaryState('CRITICAL'),
/**
* if this definition is in state: WARNING
* @type {boolean}
*/
isWarning: computedOnSummaryState('WARNING'),
/**
* if this definition is in state: OK
* @type {boolean}
*/
isOK: computedOnSummaryState('OK'),
/**
* if this definition is in state: UNKNOWN
* @type {boolean}
*/
isUnknown: computedOnSummaryState('UNKNOWN'),
/**
* For alerts we will have processes which are not typical
* cluster services - like Ambari-Server. This method unifies
* cluster services and other services into a common display-name.
* @see App.AlertInstance#serviceDisplayName()
*/
serviceDisplayName: function () {
var serviceName = this.get('service.displayName');
if (!serviceName) {
serviceName = this.get('serviceName');
if (serviceName) {
serviceName = serviceName.toCapital();
}
}
return serviceName;
}.property('serviceName', 'service.displayName'),
/**
* Determines if alert definition has help url
* @type {boolean}
*/
hasHelpUrl: Em.computed.bool('helpUrl'),
/**
* List of css-classes for alert types
* @type {object}
*/
typeIcons: {
'METRIC': 'icon-bolt',
'SCRIPT': 'icon-file-text',
'WEB': 'icon-globe',
'PORT': 'icon-signin',
'AGGREGATE': 'icon-plus',
'SERVER': 'icon-desktop',
'RECOVERY': 'icon-desktop',
'AMS': 'icon-bar-chart'
},
/**
* Sort on load definitions by this severity order
*/
severityOrder: ['CRITICAL', 'WARNING', 'OK', 'UNKNOWN', 'PENDING'],
order: ['OK', 'WARNING', 'CRITICAL', 'UNKNOWN'],
shortState: {
'CRITICAL': 'CRIT',
'WARNING': 'WARN',
'OK': 'OK',
'UNKNOWN': 'UNKWN',
'PENDING': 'NONE'
}
});
App.AlertDefinition.reopenClass({
/**
* Return function to sort list of AlertDefinitions by their status
* It sorts according to <code>severityOrder</code>
* @param {boolean} order true - DESC, false - ASC
* @returns {Function}
* @method getSortDefinitionsByStatus
*/
getSortDefinitionsByStatus: function (order) {
return function (a, b) {
var aSummary = a.get('summary'),
bSummary = b.get('summary'),
stOrder = a.get('severityOrder'),
ret = 0;
for (var i = 0; i < stOrder.length; i++) {
var aV = Em.isNone(aSummary[stOrder[i]]) ? 0 : aSummary[stOrder[i]].count + aSummary[stOrder[i]].maintenanceCount,
bV = Em.isNone(bSummary[stOrder[i]]) ? 0 : bSummary[stOrder[i]].count + bSummary[stOrder[i]].maintenanceCount;
ret = bV - aV;
if (ret !== 0) {
break;
}
}
return order ? ret : -ret;
};
}
});
App.AlertDefinitionParameter = DS.Model.extend({
name: DS.attr('string'),
displayName: DS.attr('string'),
units: DS.attr('string'),
value: DS.attr('string'),
description: DS.attr('string'),
type: DS.attr('string'),
threshold: DS.attr('string'),
visibility: DS.attr('string')
});
App.AlertReportDefinition = DS.Model.extend({
type: DS.attr('string'),
text: DS.attr('string'),
value: DS.attr('number')
});
App.AlertMetricsSourceDefinition = DS.Model.extend({
propertyList: [],
value: DS.attr('string')
});
App.AlertMetricsUriDefinition = DS.Model.extend({
http: DS.attr('string'),
https: DS.attr('string'),
httpsProperty: DS.attr('string'),
httpsPropertyValue: DS.attr('string'),
connectionTimeout: DS.attr('number')
});
App.AlertMetricsAmsDefinition = DS.Model.extend({
value: DS.attr('string'),
minimalValue: DS.attr('number'),
interval: DS.attr('number')
});
App.AlertDefinition.FIXTURES = [];
App.AlertReportDefinition.FIXTURES = [];
App.AlertMetricsSourceDefinition.FIXTURES = [];
App.AlertMetricsUriDefinition.FIXTURES = [];
App.AlertMetricsAmsDefinition.FIXTURES = [];
App.AlertDefinitionParameter.FIXTURES = [];