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 2014/11/20 18:37:21 UTC
ambari git commit: AMBARI-8398. Alerts UI: Details page thresholds
API integration. (akovalenko)
Repository: ambari
Updated Branches:
refs/heads/trunk 6f2875cee -> f543cc6c0
AMBARI-8398. Alerts UI: Details page thresholds API integration. (akovalenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f543cc6c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f543cc6c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f543cc6c
Branch: refs/heads/trunk
Commit: f543cc6c08909b3ed157fda4ba23827a745a7881
Parents: 6f2875c
Author: Aleksandr Kovalenko <ak...@hortonworks.com>
Authored: Thu Nov 20 18:38:09 2014 +0200
Committer: Aleksandr Kovalenko <ak...@hortonworks.com>
Committed: Thu Nov 20 18:38:09 2014 +0200
----------------------------------------------------------------------
.../main/alert_definitions_controller.js | 6 +-
.../alerts/definition_configs_controller.js | 48 ++++++++-
.../mappers/alert_definition_summary_mapper.js | 8 +-
.../app/mappers/alert_definitions_mapper.js | 42 +++++---
ambari-web/app/models/alert_config.js | 102 +++++++++++++++----
ambari-web/app/models/alert_definition.js | 21 ++++
.../main/alerts/definition_details.hbs | 2 +-
.../definitions_configs_controller_test.js | 94 ++++++++++++++++-
.../mappers/alert_definitions_mapper_test.js | 2 +
9 files changed, 274 insertions(+), 51 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f543cc6c/ambari-web/app/controllers/main/alert_definitions_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alert_definitions_controller.js b/ambari-web/app/controllers/main/alert_definitions_controller.js
index 7ada3ba..df02e0e 100644
--- a/ambari-web/app/controllers/main/alert_definitions_controller.js
+++ b/ambari-web/app/controllers/main/alert_definitions_controller.js
@@ -42,11 +42,7 @@ App.MainAlertDefinitionsController = Em.ArrayController.extend({
* @type {App.AlertDefinition[]}
*/
content: function() {
- return Array.prototype.concat.call(Array.prototype, App.PortAlertDefinition.find().toArray(),
- App.MetricsAlertDefinition.find().toArray(),
- App.WebAlertDefinition.find().toArray(),
- App.AggregateAlertDefinition.find().toArray(),
- App.ScriptAlertDefinition.find().toArray());
+ return App.AlertDefinition.getAllDefinitions();
}.property('mapperTimestamp'),
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/f543cc6c/ambari-web/app/controllers/main/alerts/definition_configs_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alerts/definition_configs_controller.js b/ambari-web/app/controllers/main/alerts/definition_configs_controller.js
index 12ab94e..dc57b09 100644
--- a/ambari-web/app/controllers/main/alerts/definition_configs_controller.js
+++ b/ambari-web/app/controllers/main/alerts/definition_configs_controller.js
@@ -174,10 +174,12 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({
})
}),
App.AlertConfigProperties.Metrics.create({
- value: alertDefinition.get('jmx.propertyList') ? alertDefinition.get('jmx.propertyList').join('\n') : alertDefinition.get('ganglia.propertyList').join('\n')
+ value: alertDefinition.get('jmx.propertyList') ? alertDefinition.get('jmx.propertyList').join(',\n') : alertDefinition.get('ganglia.propertyList').join(',\n'),
+ isJMXMetric: !!alertDefinition.get('jmx.propertyList')
}),
App.AlertConfigProperties.FormatString.create({
- value: alertDefinition.get('jmx.value') ? alertDefinition.get('jmx.value') : alertDefinition.get('ganglia.value')
+ value: alertDefinition.get('jmx.value') ? alertDefinition.get('jmx.value') : alertDefinition.get('ganglia.value'),
+ isJMXMetric: !!alertDefinition.get('jmx.value')
})
];
},
@@ -306,9 +308,49 @@ App.MainAlertDefinitionConfigsController = Em.Controller.extend({
* Save edit configs button handler
*/
saveConfigs: function () {
- //todo: write logic for saving alert definition properties to server
this.get('configs').setEach('isDisabled', true);
this.set('canEdit', false);
+
+ var propertiesToUpdate = this.getPropertiesToUpdate();
+
+ App.ajax.send({
+ name: 'alerts.update_alert_definition',
+ sender: this,
+ data: {
+ id: this.get('content.id'),
+ data: propertiesToUpdate
+ }
+ });
+ },
+
+ /**
+ * Create object with new values to put it on server
+ * @returns {Object}
+ */
+ getPropertiesToUpdate: function () {
+ var propertiesToUpdate = {};
+ this.get('configs').filterProperty('wasChanged').forEach(function (property) {
+ if (property.get('apiProperty').contains('source.')) {
+ if (!propertiesToUpdate['AlertDefinition/source']) {
+ propertiesToUpdate['AlertDefinition/source'] = this.get('content.rawSourceData');
+ }
+
+ var sourcePath = propertiesToUpdate['AlertDefinition/source'];
+ property.get('apiProperty').replace('source.', '').split('.').forEach(function (path, index, array) {
+ // check if it is last path
+ if (array.length - index === 1) {
+ sourcePath[path] = property.get('apiFormattedValue');
+ } else {
+ sourcePath = sourcePath[path];
+ }
+ });
+
+ } else {
+ propertiesToUpdate['AlertDefinition/' + property.get('apiProperty')] = property.get('apiFormattedValue');
+ }
+ }, this);
+
+ return propertiesToUpdate;
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/f543cc6c/ambari-web/app/mappers/alert_definition_summary_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/alert_definition_summary_mapper.js b/ambari-web/app/mappers/alert_definition_summary_mapper.js
index 8b9680d..9e18b0d 100644
--- a/ambari-web/app/mappers/alert_definition_summary_mapper.js
+++ b/ambari-web/app/mappers/alert_definition_summary_mapper.js
@@ -23,13 +23,7 @@ App.alertDefinitionSummaryMapper = App.QuickDataMapper.create({
map: function(data) {
if (!data.alerts_summary_grouped) return;
- var alertDefinitions = Array.prototype.concat.call(
- Array.prototype, App.PortAlertDefinition.find().toArray(),
- App.MetricsAlertDefinition.find().toArray(),
- App.WebAlertDefinition.find().toArray(),
- App.AggregateAlertDefinition.find().toArray(),
- App.ScriptAlertDefinition.find().toArray()
- );
+ var alertDefinitions = App.AlertDefinition.getAllDefinitions();
data.alerts_summary_grouped.forEach(function(alertDefinitionSummary) {
var alertDefinition = alertDefinitions.findProperty('id', alertDefinitionSummary.definition_id);
if (alertDefinition) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/f543cc6c/ambari-web/app/mappers/alert_definitions_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/alert_definitions_mapper.js b/ambari-web/app/mappers/alert_definitions_mapper.js
index 2b817d9..7ca8c41 100644
--- a/ambari-web/app/mappers/alert_definitions_mapper.js
+++ b/ambari-web/app/mappers/alert_definitions_mapper.js
@@ -74,21 +74,16 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({
if (json && json.items) {
var portAlertDefinitions = [],
- metricsAlertDefinitions = [],
- webAlertDefinitions = [],
- aggregateAlertDefinitions = [],
- scriptAlertDefinitions = [],
- alertReportDefinitions = [],
- alertMetricsSourceDefinitions = [],
- alertMetricsUriDefinitions = [],
- alertGroupsMap = App.cache['previousAlertGroupsMap'],
- alertDefinitions = Array.prototype.concat.call(
- Array.prototype, App.PortAlertDefinition.find().toArray(),
- App.MetricsAlertDefinition.find().toArray(),
- App.WebAlertDefinition.find().toArray(),
- App.AggregateAlertDefinition.find().toArray(),
- App.ScriptAlertDefinition.find().toArray()
- );
+ metricsAlertDefinitions = [],
+ webAlertDefinitions = [],
+ aggregateAlertDefinitions = [],
+ scriptAlertDefinitions = [],
+ alertReportDefinitions = [],
+ alertMetricsSourceDefinitions = [],
+ alertMetricsUriDefinitions = [],
+ alertGroupsMap = App.cache['previousAlertGroupsMap'],
+ alertDefinitions = App.AlertDefinition.getAllDefinitions(),
+ rawSourceData = {};
json.items.forEach(function (item) {
var convertedReportDefinitions = [];
@@ -106,6 +101,9 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({
alertReportDefinitions = alertReportDefinitions.concat(convertedReportDefinitions);
item.reporting = convertedReportDefinitions;
+
+ rawSourceData[item.AlertDefinition.id] = item.AlertDefinition.source;
+
var alertDefinition = this.parseIt(item, this.get('config'));
if (alertGroupsMap[alertDefinition.id]) {
@@ -179,8 +177,9 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({
App.store.loadMany(this.get('webModel'), webAlertDefinitions);
App.store.loadMany(this.get('aggregateModel'), aggregateAlertDefinitions);
App.store.loadMany(this.get('scriptModel'), scriptAlertDefinitions);
+ this.setAlertDefinitionsRawSourceData(rawSourceData);
if (App.router.get('mainAlertDefinitionsController')) {
- App.router.set('mainAlertDefinitionsController.mapperTimestamp', (new Date()).getTime());
+ App.router.set('mainAlertDefinitionsController.mapperTimestamp', (new Date()).getTime());
}
}
},
@@ -194,5 +193,16 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({
data.forEach(function (record) {
model.find().findProperty('id', record.id).set('propertyList', record.property_list);
});
+ },
+
+ /**
+ * set rawSourceDate properties for <code>App.AlertDefinition</code> records
+ * @param rawSourceData
+ */
+ setAlertDefinitionsRawSourceData: function (rawSourceData) {
+ var allDefinitions = App.AlertDefinition.getAllDefinitions();
+ for (var alertDefinitionId in rawSourceData) {
+ allDefinitions.findProperty('id', +alertDefinitionId).set('rawSourceData', rawSourceData[alertDefinitionId]);
+ }
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/f543cc6c/ambari-web/app/models/alert_config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/alert_config.js b/ambari-web/app/models/alert_config.js
index 7d9a720..804eec4 100644
--- a/ambari-web/app/models/alert_config.js
+++ b/ambari-web/app/models/alert_config.js
@@ -70,6 +70,36 @@ App.AlertConfigProperty = Ember.Object.extend({
classNames: '',
/**
+ * name of property related to config
+ * @type {String}
+ */
+ apiProperty: '',
+
+ /**
+ * for some metrics properties may be set true or false
+ * depending on what property is related to (JMX or Ganglia)
+ */
+ isJMXMetric: null,
+
+ /**
+ * value converted to appropriate format for sending to server
+ * should be computed property
+ * should be defined in child class
+ * @type {*}
+ */
+ apiFormattedValue: function () {
+ return this.get('value');
+ }.property('value'),
+
+ /**
+ * define if property was changed by user
+ * @type {Boolean}
+ */
+ wasChanged: function () {
+ return this.get('previousValue') !== null && this.get('value') !== this.get('previousValue');
+ }.property('value', 'previousValue'),
+
+ /**
* view class according to <code>displayType</code>
* @type {Em.View}
*/
@@ -96,35 +126,52 @@ App.AlertConfigProperties = {
AlertName: App.AlertConfigProperty.extend({
label: 'Alert Name',
displayType: 'textField',
- classNames: 'alert-text-input'
+ classNames: 'alert-text-input',
+ apiProperty: 'name'
}),
AlertNameSelected: App.AlertConfigProperty.extend({
label: 'Alert Name',
- displayType: 'select'
+ displayType: 'select',
+ apiProperty: 'name'
}),
Service: App.AlertConfigProperty.extend({
label: 'Service',
- displayType: 'select'
+ displayType: 'select',
+ apiProperty: 'service_name',
+ apiFormattedValue: function () {
+ return App.StackService.find().findProperty('displayName', this.get('value')).get('serviceName');
+ }.property('value')
}),
Component: App.AlertConfigProperty.extend({
label: 'Component',
- displayType: 'select'
+ displayType: 'select',
+ apiProperty: 'component_name',
+ apiFormattedValue: function () {
+ return App.StackServiceComponent.find().findProperty('displayName', this.get('value')).get('componentName');
+ }.property('value')
}),
Scope: App.AlertConfigProperty.extend({
label: 'Scope',
options: ['Any', 'Host', 'Service'],
- displayType: 'select'
+ displayType: 'select',
+ apiProperty: 'scope',
+ apiFormattedValue: function () {
+ return this.get('value').toUpperCase();
+ }.property('value')
}),
Description: App.AlertConfigProperty.extend({
label: 'Description',
displayType: 'textArea',
- classNames: 'alert-config-text-area'
+ classNames: 'alert-config-text-area',
+ // todo: check value after API will be provided
+ apiProperty: 'description'
}),
Interval: App.AlertConfigProperty.extend({
label: 'Interval',
displayType: 'textField',
unit: 'Second',
- classNames: 'alert-interval-input'
+ classNames: 'alert-interval-input',
+ apiProperty: 'interval'
}),
Thresholds: App.AlertConfigProperty.extend({
label: 'Thresholds',
@@ -133,6 +180,8 @@ App.AlertConfigProperties = {
from: '',
to: '',
value: '',
+ // todo: check value after API will be provided
+ apiProperty: 'thresholds',
setFromTo: function () {
this.set('doNotChangeValue', true);
@@ -153,35 +202,54 @@ App.AlertConfigProperties = {
URI: App.AlertConfigProperty.extend({
label: 'URI',
displayType: 'textField',
- classNames: 'alert-text-input'
+ classNames: 'alert-text-input',
+ apiProperty: 'source.uri'
}),
URIExtended: App.AlertConfigProperty.extend({
label: 'URI',
displayType: 'textArea',
- classNames: 'alert-config-text-area'
+ classNames: 'alert-config-text-area',
+ apiProperty: 'source.uri',
+ apiFormattedValue: function () {
+ var result = {};
+ try {
+ result = JSON.parse(this.get('value'));
+ } catch (e) {
+ console.error('Wrong format of URI');
+ }
+ return result;
+ }.property('value')
}),
DefaultPort: App.AlertConfigProperty.extend({
label: 'Default Port',
displayType: 'textField',
- classNames: 'alert-port-input'
+ classNames: 'alert-port-input',
+ apiProperty: 'source.default_port'
}),
Path: App.AlertConfigProperty.extend({
label: 'Path',
displayType: 'textField',
- classNames: 'alert-text-input'
+ classNames: 'alert-text-input',
+ apiProperty: 'source.path'
}),
Metrics: App.AlertConfigProperty.extend({
label: 'JMX/Ganglia Metrics',
displayType: 'textArea',
- classNames: 'alert-config-text-area'
+ classNames: 'alert-config-text-area',
+ apiProperty: function () {
+ return this.get('isJMXMetric') ? 'source.jmx.property_list' : 'source.ganglia.property_list'
+ }.property('isJMXMetric'),
+ apiFormattedValue: function () {
+ return this.get('value').split(',\n');
+ }.property('value')
}),
FormatString: App.AlertConfigProperty.extend({
label: 'Format String',
displayType: 'textArea',
- classNames: 'alert-config-text-area'
+ classNames: 'alert-config-text-area',
+ apiProperty: function () {
+ return this.get('isJMXMetric') ? 'source.jmx.value' : 'source.ganglia.value'
+ }.property('isJMXMetric')
})
-};
-
-
-
+};
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/f543cc6c/ambari-web/app/models/alert_definition.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/alert_definition.js b/ambari-web/app/models/alert_definition.js
index 302fa65..2005595 100644
--- a/ambari-web/app/models/alert_definition.js
+++ b/ambari-web/app/models/alert_definition.js
@@ -34,6 +34,13 @@ App.AlertDefinition = DS.Model.extend({
lastTriggered: DS.attr('number'),
/**
+ * 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>
@@ -95,6 +102,20 @@ App.AlertDefinition = DS.Model.extend({
thresholds: '5-10'
});
+App.AlertDefinition.reopenClass({
+
+ getAllDefinitions: function () {
+ return Array.prototype.concat.call(
+ Array.prototype, App.PortAlertDefinition.find().toArray(),
+ App.MetricsAlertDefinition.find().toArray(),
+ App.WebAlertDefinition.find().toArray(),
+ App.AggregateAlertDefinition.find().toArray(),
+ App.ScriptAlertDefinition.find().toArray()
+ )
+ }
+
+});
+
App.AlertReportDefinition = DS.Model.extend({
type: DS.attr('string'),
text: DS.attr('string'),
http://git-wip-us.apache.org/repos/asf/ambari/blob/f543cc6c/ambari-web/app/templates/main/alerts/definition_details.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/alerts/definition_details.hbs b/ambari-web/app/templates/main/alerts/definition_details.hbs
index 8c128b5..ab58561 100644
--- a/ambari-web/app/templates/main/alerts/definition_details.hbs
+++ b/ambari-web/app/templates/main/alerts/definition_details.hbs
@@ -113,7 +113,7 @@
</tr>
</tbody>
</table>
- <span>{{t alerts.table.header.lastTriggered}} : {{controller.content.lastTriggered}}</span>
+ <span>{{t alerts.table.header.lastTriggered}} : {{controller.content.lastTriggeredFormatted}}</span>
</div>
</div>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f543cc6c/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js b/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
index a5d9040..2c31f4d 100644
--- a/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
+++ b/ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
@@ -163,7 +163,7 @@ describe('App.MainAlertDefinitionConfigsController', function () {
expect(result.someProperty('value', 60)).to.be.true;
expect(result.someProperty('value', '10-20')).to.be.true;
expect(result.someProperty('value', '{\"http\":\"{{mapred-site/mapreduce.jobhistory.webapp.address}}\",\"https\":\"{{mapred-site/mapreduce.jobhistory.webapp.https.address}}\"}')).to.be.true;
- expect(result.someProperty('value', 'property1\nproperty2')).to.be.true;
+ expect(result.someProperty('value', 'property1,\nproperty2')).to.be.true;
expect(result.someProperty('value', 'jmxValue')).to.be.true;
});
@@ -297,6 +297,14 @@ describe('App.MainAlertDefinitionConfigsController', function () {
describe('#saveConfigs()', function () {
+ beforeEach(function () {
+ sinon.spy(App.ajax, 'send');
+ });
+
+ afterEach(function () {
+ App.ajax.send.restore();
+ });
+
it('should set previousValue, isDisabled for each config and change canEdit flag', function () {
controller.set('configs', [
@@ -311,8 +319,90 @@ describe('App.MainAlertDefinitionConfigsController', function () {
expect(controller.get('configs').someProperty('isDisabled', false)).to.be.false;
expect(controller.get('canEdit')).to.be.false;
+ expect(App.ajax.send.calledOnce).to.be.true;
+ });
+
+ });
+
+ describe('#getPropertiesToUpdate()', function () {
+
+ beforeEach(function () {
+ controller.set('content', {
+ rawSourceData: {
+ path1: 'value',
+ path2: {
+ path3: 'value'
+ }
+ }
+ });
});
+ var testCases = [
+ {
+ m: 'should ignore configs with wasChanged false',
+ configs: [
+ Em.Object.create({
+ wasChanged: false,
+ apiProperty: 'name1',
+ apiFormattedValue: 'test1'
+ }),
+ Em.Object.create({
+ wasChanged: true,
+ apiProperty: 'name2',
+ apiFormattedValue: 'test2'
+ }),
+ Em.Object.create({
+ wasChanged: false,
+ apiProperty: 'name3',
+ apiFormattedValue: 'test3'
+ })
+ ],
+ result: {
+ 'AlertDefinition/name2': 'test2'
+ }
+ },
+ {
+ m: 'should correctly map deep source properties',
+ configs: [
+ Em.Object.create({
+ wasChanged: true,
+ apiProperty: 'name1',
+ apiFormattedValue: 'test1'
+ }),
+ Em.Object.create({
+ wasChanged: true,
+ apiProperty: 'source.path1',
+ apiFormattedValue: 'value1'
+ }),
+ Em.Object.create({
+ wasChanged: true,
+ apiProperty: 'source.path2.path3',
+ apiFormattedValue: 'value2'
+ })
+ ],
+ result: {
+ 'AlertDefinition/name1': 'test1',
+ 'AlertDefinition/source': {
+ path1: 'value1',
+ path2: {
+ path3: 'value2'
+ }
+ }
+ }
+ }
+ ];
+
+ testCases.forEach(function (testCase) {
+
+ it(testCase.m, function () {
+
+ controller.set('configs', testCase.configs);
+ var result = controller.getPropertiesToUpdate();
+
+ expect(result).to.eql(testCase.result);
+ });
+ });
});
-});
+})
+;
http://git-wip-us.apache.org/repos/asf/ambari/blob/f543cc6c/ambari-web/test/mappers/alert_definitions_mapper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mappers/alert_definitions_mapper_test.js b/ambari-web/test/mappers/alert_definitions_mapper_test.js
index 12535a5..802fd96 100644
--- a/ambari-web/test/mappers/alert_definitions_mapper_test.js
+++ b/ambari-web/test/mappers/alert_definitions_mapper_test.js
@@ -210,6 +210,7 @@ describe('App.alertDefinitionsMapper', function () {
App.cache['previousAlertGroupsMap'] = {};
sinon.stub(App.alertDefinitionsMapper, 'setMetricsSourcePropertyLists', Em.K);
+ sinon.stub(App.alertDefinitionsMapper, 'setAlertDefinitionsRawSourceData', Em.K);
});
@@ -242,6 +243,7 @@ describe('App.alertDefinitionsMapper', function () {
App.cache['previousAlertGroupsMap'] = {};
App.alertDefinitionsMapper.setMetricsSourcePropertyLists.restore();
+ App.alertDefinitionsMapper.setAlertDefinitionsRawSourceData.restore();
});