definition_configs_controller.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. App.MainAlertDefinitionConfigsController = Em.Controller.extend({
  19. name: 'mainAlertDefinitionConfigsController',
  20. /**
  21. * All configurable properties of alert definition
  22. * @type {Array}
  23. */
  24. configs: [],
  25. /**
  26. * Define whether configs are editable
  27. * binds to property populated in template
  28. * @type {Boolean}
  29. */
  30. canEdit: true,
  31. /**
  32. * Define configs view mode (Wizard or Definition Details page)
  33. * @type {Boolean}
  34. */
  35. isWizard: false,
  36. /**
  37. * Alert Definition type
  38. * binding is set in template
  39. * @type {String}
  40. */
  41. alertDefinitionType: '',
  42. /**
  43. * Array of displayNames of all services
  44. * is used for "Service" config options
  45. * @type {Array}
  46. */
  47. allServices: function () {
  48. return App.Service.find().mapProperty('displayName');
  49. }.property(),
  50. /**
  51. * All possible values for scope propery
  52. * @type {Array}
  53. */
  54. allScopes: ['Any', 'Host', 'Service'],
  55. /**
  56. * Array of all aggregate-alerts names
  57. * @type {Array}
  58. */
  59. aggregateAlertNames: function () {
  60. return App.AggregateAlertDefinition.find().mapProperty('name');
  61. }.property(),
  62. /**
  63. * Change options of "Component", after changing value of "Service" config
  64. * @method onServiceSelect
  65. */
  66. onServiceSelect: function () {
  67. var serviceProperty = this.get('configs').findProperty('name', 'service');
  68. if (serviceProperty && serviceProperty.get('value') !== 'Ambari') {
  69. var componentsProperty = this.get('configs').findProperty('name', 'component');
  70. componentsProperty.set('options', ['No component'].concat(App.HostComponent.find().filterProperty('service.displayName', serviceProperty.get('value')).mapProperty('displayName').uniq()));
  71. }
  72. }.observes('configs.@each.value'),
  73. /**
  74. * OnSelect handler for <code>select_type</code> property
  75. * disable fields related to definition type and set options to select lists
  76. */
  77. changeType: function (selectedType) {
  78. if (selectedType === 'alert_type_service') {
  79. this.get('configs').findProperty('name', 'service').set('isDisabled', false).set('options', this.get('allServices')).set('value', this.get('allServices')[0]);
  80. this.get('configs').findProperty('name', 'component').set('isDisabled', false).set('value', 'No component');
  81. this.get('configs').findProperty('name', 'scope').set('isDisabled', false).set('options', this.get('allScopes')).set('value', this.get('allScopes')[0]);
  82. } else {
  83. this.get('configs').findProperty('name', 'service').set('isDisabled', true).set('options', ['Ambari']).set('value', 'Ambari');
  84. this.get('configs').findProperty('name', 'component').set('isDisabled', true).set('options', ['Ambari Agent']).set('value', 'Ambari Agent');
  85. this.get('configs').findProperty('name', 'scope').set('isDisabled', true).set('options', ['Host']).set('value', 'Host');
  86. }
  87. },
  88. /**
  89. * @return {string|Null}
  90. * @method getThresholdsProperty
  91. */
  92. getThresholdsProperty: function (type, property) {
  93. var warning = this.get('content.reporting').findProperty('type', type);
  94. return warning && warning.get(property) ? warning.get(property) : null;
  95. },
  96. /**
  97. * Render array of configs for appropriate alert definition type
  98. * @method renderConfigs
  99. */
  100. renderConfigs: function () {
  101. var alertDefinitionType = this.get('alertDefinitionType');
  102. var configs = [];
  103. switch (alertDefinitionType) {
  104. case 'PORT':
  105. configs = this.renderPortConfigs();
  106. break;
  107. case 'METRIC':
  108. configs = this.renderMetricConfigs();
  109. break;
  110. case 'WEB':
  111. configs = this.renderWebConfigs();
  112. break;
  113. case 'SCRIPT':
  114. configs = this.renderScriptConfigs();
  115. break;
  116. case 'AGGREGATE':
  117. configs = this.renderAggregateConfigs();
  118. break;
  119. default:
  120. console.error('Incorrect Alert Definition Type: ', alertDefinitionType);
  121. }
  122. configs.setEach('isDisabled', !this.get('canEdit'));
  123. this.set('configs', configs);
  124. },
  125. /**
  126. * Render config properties for port-type alert definition
  127. * @method renderPortConfigs
  128. * @returns {App.AlertConfigProperty[]}
  129. */
  130. renderPortConfigs: function () {
  131. var result = [];
  132. var alertDefinition = this.get('content');
  133. var isWizard = this.get('isWizard');
  134. if (this.get('isWizard')) {
  135. result = result.concat(this.renderCommonWizardConfigs());
  136. }
  137. result = result.concat([
  138. App.AlertConfigProperties.Description.create({
  139. value: isWizard ? '' : alertDefinition.get('description')
  140. }),
  141. App.AlertConfigProperties.Interval.create({
  142. value: isWizard ? '' : alertDefinition.get('interval')
  143. }),
  144. App.AlertConfigProperties.Thresholds.OkThreshold.create({
  145. label: 'Thresholds',
  146. showInputForValue: false,
  147. text: isWizard ? '' : this.getThresholdsProperty('ok', 'text'),
  148. value: isWizard ? '' : this.getThresholdsProperty('ok', 'value')
  149. }),
  150. App.AlertConfigProperties.Thresholds.WarningThreshold.create({
  151. valueMetric: 'Seconds',
  152. text: isWizard ? '' : this.getThresholdsProperty('warning', 'text'),
  153. value: isWizard ? '' : this.getThresholdsProperty('warning', 'value')
  154. }),
  155. App.AlertConfigProperties.Thresholds.CriticalThreshold.create({
  156. valueMetric: 'Seconds',
  157. text: isWizard ? '' : this.getThresholdsProperty('critical', 'text'),
  158. value: isWizard ? '' : this.getThresholdsProperty('critical', 'value')
  159. })
  160. ]);
  161. return result;
  162. },
  163. /**
  164. * Render config properties for metric-type alert definition
  165. * @method renderMetricConfigs
  166. * @returns {App.AlertConfigProperty[]}
  167. */
  168. renderMetricConfigs: function () {
  169. var result = [];
  170. var alertDefinition = this.get('content');
  171. var isWizard = this.get('isWizard');
  172. var units = this.get('content.reporting').findProperty('type','units') ?
  173. this.get('content.reporting').findProperty('type','units').get('text'): null;
  174. if (this.get('isWizard')) {
  175. result = result.concat(this.renderCommonWizardConfigs());
  176. }
  177. result = result.concat([
  178. App.AlertConfigProperties.Description.create({
  179. value: isWizard ? '' : alertDefinition.get('description')
  180. }),
  181. App.AlertConfigProperties.Interval.create({
  182. value: isWizard ? '' : alertDefinition.get('interval')
  183. }),
  184. App.AlertConfigProperties.Thresholds.OkThreshold.create({
  185. label: 'Thresholds',
  186. showInputForValue: false,
  187. text: isWizard ? '' : this.getThresholdsProperty('ok', 'text'),
  188. value: isWizard ? '' : this.getThresholdsProperty('ok', 'value')
  189. }),
  190. App.AlertConfigProperties.Thresholds.WarningThreshold.create({
  191. valueMetric: units,
  192. text: isWizard ? '' : this.getThresholdsProperty('warning', 'text'),
  193. value: isWizard ? '' : this.getThresholdsProperty('warning', 'value')
  194. }),
  195. App.AlertConfigProperties.Thresholds.CriticalThreshold.create({
  196. valueMetric: units,
  197. text: isWizard ? '' : this.getThresholdsProperty('critical', 'text'),
  198. value: isWizard ? '' : this.getThresholdsProperty('critical', 'value')
  199. })
  200. ]);
  201. return result;
  202. },
  203. /**
  204. * Render config properties for web-type alert definition
  205. * @method renderWebConfigs
  206. * @returns {App.AlertConfigProperty[]}
  207. */
  208. renderWebConfigs: function () {
  209. var result = [];
  210. var alertDefinition = this.get('content');
  211. var isWizard = this.get('isWizard');
  212. if (this.get('isWizard')) {
  213. result = result.concat(this.renderCommonWizardConfigs());
  214. }
  215. result = result.concat([
  216. App.AlertConfigProperties.Description.create({
  217. value: isWizard ? '' : alertDefinition.get('description')
  218. }),
  219. App.AlertConfigProperties.Interval.create({
  220. value: isWizard ? '' : alertDefinition.get('interval')
  221. }),
  222. App.AlertConfigProperties.Thresholds.OkThreshold.create({
  223. label: 'Thresholds',
  224. showInputForValue: false,
  225. text: isWizard ? '' : this.getThresholdsProperty('ok', 'text'),
  226. value: isWizard ? '' : this.getThresholdsProperty('ok', 'value')
  227. }),
  228. App.AlertConfigProperties.Thresholds.WarningThreshold.create({
  229. showInputForValue: false,
  230. text: isWizard ? '' : this.getThresholdsProperty('warning', 'text'),
  231. value: isWizard ? '' : this.getThresholdsProperty('warning', 'value')
  232. }),
  233. App.AlertConfigProperties.Thresholds.CriticalThreshold.create({
  234. showInputForValue: false,
  235. text: isWizard ? '' : this.getThresholdsProperty('critical', 'text'),
  236. value: isWizard ? '' : this.getThresholdsProperty('critical', 'value')
  237. })
  238. ]);
  239. return result;
  240. },
  241. /**
  242. * Render config properties for script-type alert definition
  243. * @method renderScriptConfigs
  244. * @returns {App.AlertConfigProperty[]}
  245. */
  246. renderScriptConfigs: function () {
  247. var result = [];
  248. var alertDefinition = this.get('content');
  249. var isWizard = this.get('isWizard');
  250. if (this.get('isWizard')) {
  251. result = result.concat(this.renderCommonWizardConfigs());
  252. }
  253. result = result.concat([
  254. App.AlertConfigProperties.Description.create({
  255. value: isWizard ? '' : alertDefinition.get('description')
  256. }),
  257. App.AlertConfigProperties.Interval.create({
  258. value: isWizard ? '' : alertDefinition.get('interval')
  259. })
  260. ]);
  261. return result;
  262. },
  263. /**
  264. * Render config properties for aggregate-type alert definition
  265. * @method renderAggregateConfigs
  266. * @returns {App.AlertConfigProperty[]}
  267. */
  268. renderAggregateConfigs: function () {
  269. var isWizard = this.get('isWizard');
  270. var alertDefinition = this.get('content');
  271. return [
  272. App.AlertConfigProperties.Description.create({
  273. value: isWizard ? '' : alertDefinition.get('description')
  274. }),
  275. App.AlertConfigProperties.Thresholds.OkThreshold.create({
  276. label: 'Thresholds',
  277. showInputForValue: false,
  278. text: isWizard ? '' : this.getThresholdsProperty('ok', 'text'),
  279. value: isWizard ? '' : this.getThresholdsProperty('ok', 'value')
  280. }),
  281. App.AlertConfigProperties.Thresholds.WarningThreshold.create(App.AlertConfigProperties.Thresholds.PercentageMixin, {
  282. text: isWizard ? '' : this.getThresholdsProperty('warning', 'text'),
  283. value: isWizard ? '' : this.getThresholdsProperty('warning', 'value'),
  284. valueMetric: '%'
  285. }),
  286. App.AlertConfigProperties.Thresholds.CriticalThreshold.create(App.AlertConfigProperties.Thresholds.PercentageMixin, {
  287. text: isWizard ? '' : this.getThresholdsProperty('critical', 'text'),
  288. value: isWizard ? '' : this.getThresholdsProperty('critical', 'value'),
  289. valueMetric: '%'
  290. })
  291. ];
  292. },
  293. /**
  294. * Render common list of configs used in almost all alert types in wizard
  295. * @returns {App.AlertConfigProperty[]}
  296. */
  297. renderCommonWizardConfigs: function () {
  298. return [
  299. App.AlertConfigProperties.AlertName.create({
  300. value: ''
  301. }),
  302. App.AlertConfigProperties.ServiceAlertType.create({
  303. value: true
  304. }),
  305. App.AlertConfigProperties.Service.create({
  306. options: this.get('allServices'),
  307. value: this.get('allServices')[0],
  308. isShifted: true
  309. }),
  310. App.AlertConfigProperties.Component.create({
  311. options: this.get('allComponents'),
  312. value: 'No component',
  313. isShifted: true
  314. }),
  315. App.AlertConfigProperties.Scope.create({
  316. options: this.get('allScopes'),
  317. isShifted: true
  318. }),
  319. App.AlertConfigProperties.HostAlertType.create({
  320. value: false
  321. })
  322. ];
  323. },
  324. /**
  325. * Edit configs button handler
  326. * @method editConfigs
  327. */
  328. editConfigs: function () {
  329. this.get('configs').forEach(function (property) {
  330. property.set('previousValue', property.get('value'));
  331. property.set('previousText', property.get('text'));
  332. });
  333. this.get('configs').setEach('isDisabled', false);
  334. this.set('canEdit', true);
  335. },
  336. /**
  337. * Cancel edit configs button handler
  338. * @method cancelEditConfigs
  339. */
  340. cancelEditConfigs: function () {
  341. this.get('configs').forEach(function (property) {
  342. property.set('value', property.get('previousValue'));
  343. property.set('text', property.get('previousText'));
  344. });
  345. this.get('configs').setEach('isDisabled', true);
  346. this.set('canEdit', false);
  347. },
  348. /**
  349. * Save edit configs button handler
  350. * @method saveConfigs
  351. * @return {$.ajax}
  352. */
  353. saveConfigs: function () {
  354. this.get('configs').setEach('isDisabled', true);
  355. this.set('canEdit', false);
  356. return App.ajax.send({
  357. name: 'alerts.update_alert_definition',
  358. sender: this,
  359. data: {
  360. id: this.get('content.id'),
  361. data: this.getPropertiesToUpdate(true)
  362. },
  363. success: 'saveConfigsSuccessCallback'
  364. });
  365. },
  366. /**
  367. * Success-callback for saveConfigs-request
  368. * @method saveConfigsSuccessCallback
  369. */
  370. saveConfigsSuccessCallback: function () {
  371. App.router.get('updateController').updateAlertDefinitions(Em.K);
  372. },
  373. /**
  374. * Create object with new values to put it on server
  375. * @param {boolean} onlyChanged
  376. * @method getPropertiesToUpdate
  377. * @returns {Object}
  378. */
  379. getPropertiesToUpdate: function (onlyChanged) {
  380. var propertiesToUpdate = {};
  381. var configs = onlyChanged ? this.get('configs').filterProperty('wasChanged') : this.get('configs');
  382. configs.forEach(function (property) {
  383. var apiProperties = property.get('apiProperty');
  384. var apiFormattedValues = property.get('apiFormattedValue');
  385. if (!Em.isArray(property.get('apiProperty'))) {
  386. apiProperties = [property.get('apiProperty')];
  387. apiFormattedValues = [property.get('apiFormattedValue')];
  388. }
  389. apiProperties.forEach(function (apiProperty, i) {
  390. if (apiProperty.contains('source.')) {
  391. if (!propertiesToUpdate['AlertDefinition/source']) {
  392. if (this.get('content.rawSourceData')) {
  393. propertiesToUpdate['AlertDefinition/source'] = this.get('content.rawSourceData');
  394. }
  395. }
  396. if (this.get('content.rawSourceData')) {
  397. // use rawSourceData to populate propertiesToUpdate
  398. var sourcePath = propertiesToUpdate['AlertDefinition/source'];
  399. apiProperty.replace('source.', '').split('.').forEach(function (path, index, array) {
  400. // check if it is last path
  401. if (array.length - index === 1) {
  402. sourcePath[path] = apiFormattedValues[i];
  403. } else {
  404. sourcePath = sourcePath[path];
  405. }
  406. });
  407. }
  408. else {
  409. if (!propertiesToUpdate['AlertDefinition/source']) {
  410. propertiesToUpdate['AlertDefinition/source'] = {};
  411. }
  412. Ember.setFullPath(propertiesToUpdate['AlertDefinition/source'], apiProperty.replace('source.', ''), apiFormattedValues[i]);
  413. }
  414. }
  415. else {
  416. if (apiProperty) {
  417. propertiesToUpdate['AlertDefinition/' + apiProperty] = apiFormattedValues[i];
  418. }
  419. }
  420. }, this);
  421. }, this);
  422. return propertiesToUpdate;
  423. },
  424. /**
  425. * Return array of all config values
  426. * used to save configs to local db in wizard
  427. * @method getConfigsValues
  428. * @returns {Array}
  429. */
  430. getConfigsValues: function () {
  431. return this.get('configs').map(function (property) {
  432. return {
  433. name: property.get('name'),
  434. value: property.get('value')
  435. }
  436. });
  437. },
  438. /**
  439. * Define whether critical threshold >= critical threshold
  440. * @type {Boolean}
  441. */
  442. hasThresholdsError: function () {
  443. if (this.get('configs').findProperty('name', 'warning_threshold')) {
  444. var smallValue = Em.get(this.get('configs').findProperty('name', 'warning_threshold'), 'value');
  445. var smallValid = Em.get(this.get('configs').findProperty('name', 'warning_threshold'), 'isValid');
  446. }
  447. if (this.get('configs').findProperty('name', 'critical_threshold')) {
  448. var largeValue = Em.get(this.get('configs').findProperty('name', 'critical_threshold'), 'value');
  449. var largeValid = Em.get(this.get('configs').findProperty('name', 'critical_threshold'), 'isValid');
  450. }
  451. return smallValid && largeValid ? Number(smallValue) > Number(largeValue) : false;
  452. }.property('configs.@each.value'),
  453. /**
  454. * Define whether all configs are valid
  455. * @type {Boolean}
  456. */
  457. hasErrors: function () {
  458. return this.get('configs').someProperty('isValid', false) || this.get('hasThresholdsError');
  459. }.property('configs.@each.isValid', 'hasThresholdsError')
  460. });