widget_mixin.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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. var App = require('app');
  19. App.WidgetMixin = Ember.Mixin.create({
  20. /**
  21. * @type {RegExp}
  22. * @const
  23. */
  24. EXPRESSION_REGEX: /\$\{([\w\.\+\-\*\/\(\)\:\=\[\]]*)\}/g,
  25. /**
  26. * @type {RegExp}
  27. * @const
  28. */
  29. MATH_EXPRESSION_REGEX: /^[\d\+\-\*\/\(\)\.]+$/,
  30. /**
  31. * @type {RegExp}
  32. * @const
  33. */
  34. VALUE_NAME_REGEX: /[\w\.\:\=\[\]]+/g,
  35. /**
  36. * common metrics container
  37. * @type {Array}
  38. */
  39. metrics: [],
  40. /**
  41. * @type {boolean}
  42. */
  43. isLoaded: false,
  44. /**
  45. * @type {App.Widget}
  46. * @default null
  47. */
  48. content: null,
  49. /**
  50. * load metrics
  51. */
  52. beforeRender: function () {
  53. var requestData = this.getRequestData(this.get('content.metrics')),
  54. request,
  55. requestCounter = 0,
  56. self = this;
  57. for (var i in requestData) {
  58. request = requestData[i];
  59. requestCounter++;
  60. if (request.host_component_criteria) {
  61. this.getHostComponentMetrics(request).complete(function () {
  62. requestCounter--;
  63. if (requestCounter === 0) self.set('isLoaded', true);
  64. });
  65. } else {
  66. this.getServiceComponentMetrics(request).complete(function () {
  67. requestCounter--;
  68. if (requestCounter === 0) self.set('isLoaded', true);
  69. });
  70. }
  71. }
  72. },
  73. /**
  74. * extract expressions
  75. * Example:
  76. * input: "${a/b} equal ${b+a}"
  77. * expressions: ['a/b', 'b+a']
  78. *
  79. * @param {object} input
  80. * @returns {Array}
  81. */
  82. extractExpressions: function (input) {
  83. var pattern = this.get('EXPRESSION_REGEX'),
  84. expressions = [],
  85. match;
  86. while (match = pattern.exec(input.value)) {
  87. expressions.push(match[1]);
  88. }
  89. return expressions;
  90. },
  91. /**
  92. * calculate series datasets for graph widgets
  93. */
  94. calculateValues: function () {
  95. var metrics = this.get('metrics');
  96. var displayUnit = this.get('content.properties.display_unit');
  97. this.get('content.values').forEach(function (value) {
  98. var computeExpression = this.computeExpression(this.extractExpressions(value), metrics);
  99. value.computedValue = value.value.replace(this.get('EXPRESSION_REGEX'), function (match) {
  100. return (computeExpression[match]) ? computeExpression[match] + (displayUnit || "") : Em.I18n.t('common.na');
  101. });
  102. }, this);
  103. },
  104. /**
  105. * compute expression
  106. * @param expressions
  107. * @param metrics
  108. * @returns {object}
  109. */
  110. computeExpression: function (expressions, metrics) {
  111. var result = {};
  112. expressions.forEach(function (_expression) {
  113. var validExpression = true;
  114. var value = "";
  115. //replace values with metrics data
  116. var beforeCompute = _expression.replace(this.get('VALUE_NAME_REGEX'), function (match) {
  117. if (metrics.someProperty('name', match)) {
  118. return metrics.findProperty('name', match).data;
  119. } else {
  120. validExpression = false;
  121. console.warn('Metrics not found to compute expression');
  122. }
  123. });
  124. if (validExpression) {
  125. //check for correct math expression
  126. validExpression = this.get('MATH_EXPRESSION_REGEX').test(beforeCompute);
  127. !validExpression && console.warn('Value is not correct mathematical expression');
  128. }
  129. result['${' + _expression + '}'] = (validExpression) ? Number(window.eval(beforeCompute)).toString() : value;
  130. }, this);
  131. return result;
  132. },
  133. /**
  134. * get data formatted for request
  135. * @param {Array} metrics
  136. */
  137. getRequestData: function (metrics) {
  138. var requestsData = {};
  139. metrics.forEach(function (metric) {
  140. var key = metric.service_name + '_' + metric.component_name + '_' + metric.host_component_criteria;
  141. var requestMetric = $.extend({}, metric);
  142. if (requestsData[key]) {
  143. requestsData[key]["widget_ids"].push(requestMetric["widget_id"]);
  144. } else {
  145. requestMetric["widget_ids"] = [requestMetric["widget_id"]];
  146. delete requestMetric["widget_id"];
  147. requestsData[key] = requestMetric;
  148. }
  149. }, this);
  150. return requestsData;
  151. },
  152. /**
  153. * make GET call to server in order to fetch service-component metrics
  154. * @param {object} request
  155. * @returns {$.ajax}
  156. */
  157. getServiceComponentMetrics: function (request) {
  158. return App.ajax.send({
  159. name: 'widgets.serviceComponent.metrics.get',
  160. sender: this,
  161. data: {
  162. serviceName: request.service_name,
  163. componentName: request.component_name,
  164. widgetIds: request.widget_ids.join(',')
  165. },
  166. success: 'getServiceComponentMetricsSuccessCallback'
  167. });
  168. },
  169. getServiceComponentMetricsSuccessCallback: function (data, opt, params) {
  170. var metrics = [];
  171. this.get('content.metrics').forEach(function (_metric) {
  172. if (Em.get(data, _metric.widget_id.replace(/\//g, '.'))) {
  173. _metric.data = Em.get(data, _metric.widget_id.replace(/\//g, '.'));
  174. this.get('metrics').pushObject(_metric);
  175. }
  176. }, this);
  177. },
  178. /**
  179. * make GET call to server in order to fetch host-component metrics
  180. * @param {object} request
  181. * @returns {$.ajax}
  182. */
  183. getHostComponentMetrics: function (request) {
  184. return App.ajax.send({
  185. name: 'widgets.hostComponent.metrics.get',
  186. sender: this,
  187. data: {
  188. serviceName: request.service_name,
  189. componentName: request.component_name,
  190. widgetIds: request.widget_ids.join(','),
  191. hostComponentCriteria: 'host_components/HostRoles/' + request.host_component_criteria
  192. },
  193. success: 'getHostComponentMetricsSuccessCallback'
  194. });
  195. },
  196. getHostComponentMetricsSuccessCallback: function () {
  197. //TODO push data to metrics after response structure approved
  198. }
  199. });